Compare commits

...

834 Commits

Author SHA1 Message Date
Dennis Luxen 7b0b378abc fix a performance regression 2014-05-07 10:35:56 +02:00
Dennis Luxen a1ecab2f95 refactor xml parser, uses faster string to double conversion 2014-04-29 16:05:34 +02:00
Dennis Luxen b7704f0c7f fix regression that seg faults if path not found 2014-04-29 11:46:05 +02:00
Dennis Luxen d6962f3a09 fix geometry load on shared memory 2014-04-29 09:50:29 +02:00
Dennis Luxen e44ebe0743 minor refactoring of code layout 2014-04-28 19:37:42 +02:00
Dennis Luxen f02ec41fbc move raw pointer to smart ptrs 2014-04-28 19:37:23 +02:00
Dennis Luxen d0b4ffd154 fix openmp woes on linux 2014-04-28 18:23:56 +02:00
Dennis Luxen 265af1f790 minor refactoring 2014-04-28 17:27:15 +02:00
Dennis Luxen 241d6b482e reenable traffic signal penalty in car profile 2014-04-28 17:26:31 +02:00
Dennis Luxen 45f0af2afc remove unnecessary else statements 2014-04-28 15:08:54 +02:00
Dennis Luxen 7955066d5c remove bitwise operator in conditional 2014-04-28 15:06:26 +02:00
Dennis Luxen ec3f9695cd remove redundant local variable 2014-04-28 13:26:20 +02:00
Dennis Luxen 018c144c76 minor refactoring 2014-04-28 13:19:35 +02:00
Dennis Luxen 56e88b2a56 minor refactoring 2014-04-28 13:19:26 +02:00
Dennis Luxen a2bdc5d8d9 minor refactoring 2014-04-28 13:08:25 +02:00
Dennis Luxen 1b257f7547 fix inverted logic 2014-04-28 13:03:20 +02:00
Dennis Luxen 5d6b05979d remove unused variable 2014-04-28 12:59:24 +02:00
Dennis Luxen 538f8d040a avoid short variable name 2014-04-28 12:58:40 +02:00
Dennis Luxen 7d52aa1272 avoid short variable name 2014-04-28 12:58:00 +02:00
Dennis Luxen d316202834 avoid private static function 2014-04-28 12:56:32 +02:00
Dennis Luxen 0167dfc3c9 shorten line 2014-04-28 12:54:11 +02:00
Dennis Luxen 02dc3dee04 shorten line 2014-04-28 12:52:55 +02:00
Dennis Luxen a5d3bc9578 make function call more legible 2014-04-28 12:52:06 +02:00
Dennis Luxen cfbc6b0441 remove useless parantheses 2014-04-28 12:50:44 +02:00
Dennis Luxen 8c5f8e995e stream-lined error messages: partially implements #986 2014-04-28 11:55:46 +02:00
Dennis Luxen b77dd6699d Merge pull request #992 from DennisOSRM/feature/remove_geometry
Feature/remove geometry
2014-04-28 11:34:49 +02:00
Dennis Luxen 9a153708e6 minor reformatting / shaping up 2014-04-25 16:00:39 +02:00
Dennis Luxen e0027a78e1 fix signed unsigned comparison 2014-04-25 15:48:10 +02:00
Dennis Luxen 51e8113a69 make tests use fuzzy matching instead of tweaked expectations 2014-04-25 15:24:18 +02:00
Dennis Luxen 78f5753a3a fix signed/unsigned comparison 2014-04-25 14:42:06 +02:00
Dennis Luxen 16ca8da438 remove deactivated debug out for good 2014-04-25 13:31:08 +02:00
Dennis Luxen ca6515c58a fix tests to reflect proper rounding of travel times 2014-04-25 13:23:27 +02:00
Dennis Luxen 2ec952032a fix rounding of travel times 2014-04-25 13:22:58 +02:00
Dennis Luxen b0b67a0cdc fix typo setting potentially wrong flags in debug build 2014-04-24 18:14:35 +02:00
Dennis Luxen 0eed39cdf1 rebase branch onto develop 2014-04-24 18:13:50 +02:00
Dennis Luxen ace59411cb fix and/or remove unused variables 2014-04-24 13:31:04 +02:00
Dennis Luxen ef7619d664 fix signed/unsigned comparison 2014-04-24 13:31:04 +02:00
Dennis Luxen 0f8a32f38c shape up code 2014-04-24 13:31:04 +02:00
Dennis Luxen c6a58ff1b4 remove debug lint again 2014-04-24 13:31:04 +02:00
Dennis Luxen 45f751720a fix unpacking of geometry for shared memory 2014-04-24 13:31:04 +02:00
Dennis Luxen ca016e2818 fix unpacking of geometry for shared memory 2014-04-24 13:31:04 +02:00
Dennis Luxen 5da01946b8 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen 8b3002a685 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen ede5cca2e7 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen d0e158ca07 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen 09dc21af31 remove debug lint 2014-04-24 13:17:11 +02:00
Dennis Luxen 2435fadfbd use boost filesystem specialization instead of the ones from std 2014-04-24 13:15:26 +02:00
Dennis Luxen edef9c11f7 add default clause to switch statement albeit technically superflous 2014-04-24 13:06:57 +02:00
Dennis Luxen 2c9edcaf23 remove debug code 2014-04-24 13:06:57 +02:00
Dennis Luxen 18861d58b5 compile fix for linux / wrong include 2014-04-24 13:06:57 +02:00
Dennis Luxen 9b3dab8055 implement loading of compressed geometries 2014-04-24 13:06:56 +02:00
Dennis Luxen 7a6a5f6612 implement population of shared vector<bool> overload (manually, yikes) 2014-04-24 13:06:56 +02:00
Dennis Luxen f468fcc2b6 implement more details of shared memory store 2014-04-24 13:06:56 +02:00
Dennis Luxen 5d93c68790 remove further debug things 2014-04-24 13:06:56 +02:00
Dennis Luxen fa04706484 remove debug code, add C++11 todo 2014-04-24 13:06:56 +02:00
Dennis Luxen d09be5a80e remove debug code, make variables const 2014-04-24 13:06:56 +02:00
Dennis Luxen a4d6e5c9cc reformat geometry compressor according to new guidelines 2014-04-24 13:06:56 +02:00
Dennis Luxen 4f85fd28cf add todo for the switch to C++11 2014-04-24 13:06:56 +02:00
Dennis Luxen 39914cd933 remove some debug code 2014-04-24 13:06:56 +02:00
Dennis Luxen 038e8cc8b8 remove unneeded edge-offset during query 2014-04-24 13:06:55 +02:00
Dennis Luxen db5fd5506d partial implementation of new datastore functions 2014-04-24 13:06:55 +02:00
Dennis Luxen f2be495e95 implement shared data facade geometry loader and getter functions 2014-04-24 13:06:55 +02:00
Dennis Luxen 6d8465a04d implement geometry uncompressing using STL 2014-04-24 13:06:55 +02:00
Dennis Luxen 4bb5270f25 cut back debug verbosity 2014-04-24 13:06:55 +02:00
Dennis Luxen 0f06c71796 remove debug output 2014-04-24 13:06:55 +02:00
Dennis Luxen 5b8d8a83dd fix mangled offsets and edge weights on compressed edges (all tests passing) 2014-04-24 13:06:55 +02:00
Dennis Luxen 8ec3d549a6 further fixes but forward/reverse edge weights are reversed 2014-04-24 13:06:55 +02:00
Dennis Luxen 394e369b54 fix edge-expanded offsets 2014-04-24 13:06:55 +02:00
Dennis Luxen 899ab9ddc0 remove some uncommented code 2014-04-24 13:06:54 +02:00
Dennis Luxen 8ae467985f turn off colored logging if output is redirected to file 2014-04-24 13:06:54 +02:00
Dennis Luxen 9ccc8a7404 remove first segment if distance is 0 (down to 7 failed) 2014-04-24 12:55:53 +02:00
Dennis Luxen 0b89a9d554 ignore last edge-expanded segment if it spans over to undistinguishable node-based nodes (down to 9 failed) 2014-04-24 12:55:53 +02:00
Dennis Luxen 752fb880be switch edge-expanded street name indexes to be first segment names (18 failed tests left) 2014-04-24 12:55:53 +02:00
Dennis Luxen 549bcb502b minor renaming efforts 2014-04-24 12:55:53 +02:00
Dennis Luxen 44077cb007 refactor and streamline use of TurnInstructionsClass members 2014-04-24 12:55:53 +02:00
Dennis Luxen 7b5902a580 rename phantom nodes members 2014-04-24 12:55:53 +02:00
Dennis Luxen 2861bacd2a fix check for invalid phantom nodes (20 failed left) 2014-04-24 12:55:53 +02:00
Dennis Luxen 776ac3bb2a remove superflous include 2014-04-24 12:55:52 +02:00
Dennis Luxen b429d9f509 remove unreachable code 2014-04-24 12:55:52 +02:00
Dennis Luxen 26397e4692 remove debug output 2014-04-24 12:55:52 +02:00
Dennis Luxen 48d23194af fix traffic signal penalty in compressed graph 2014-04-24 12:55:52 +02:00
Dennis Luxen bcaea1a617 remove debug output 2014-04-24 12:54:25 +02:00
Dennis Luxen 12b43d206c unpack properly when source and target are reversed on same edge 2014-04-24 12:54:24 +02:00
Dennis Luxen 9cc49f6ff3 remove debug output 2014-04-24 12:54:24 +02:00
Dennis Luxen 87f036e538 fixing sentinel nodes in adjacency list graph data structure 2014-04-24 12:54:24 +02:00
Dennis Luxen fdebec6448 correct partial distances 2014-04-24 12:51:18 +02:00
Dennis Luxen ba37836e24 allow graphs with zero edges to load 2014-04-24 12:51:18 +02:00
Dennis Luxen b60cfd9294 last segment gets it proper name now 2014-04-24 12:51:17 +02:00
Dennis Luxen bc0665cd9f fix offsets for start and end 2014-04-24 12:51:17 +02:00
Dennis Luxen 0dbe5e6593 fix shortest ch query for certain cases 2014-04-24 12:51:17 +02:00
Dennis Luxen 9b33aaa11a fix test for borked lat/lons 2014-04-24 12:51:17 +02:00
Dennis Luxen 024b78da7c Forward decl to cut compile times 2014-04-24 12:51:17 +02:00
Dennis Luxen 2a64297506 Forward decl to cut compile times 2014-04-24 12:51:17 +02:00
Dennis Luxen 09c76939f1 minor code beauty issue 2014-04-24 12:51:17 +02:00
Dennis Luxen 0b3f3bdf92 fix test for borked lat/lons 2014-04-24 12:51:17 +02:00
Dennis Luxen 3b29eeb6b6 unpacking start and target edge fixes plus some refactoring 2014-04-24 12:51:16 +02:00
Dennis Luxen 985270bb02 parse maxspeed in LUA 2014-04-24 12:51:16 +02:00
Dennis Luxen 6b91d6692f unpacking target correctly, also partial unpacking origin and destination are on the very same packed edge 2014-04-24 12:47:36 +02:00
Dennis Luxen eca09e6c81 unpacking of target segment works 2014-04-24 12:47:00 +02:00
Dennis Luxen 874c579f86 correctly unpacking the first segment 2014-04-24 12:15:48 +02:00
Dennis Luxen a0bddab169 3/4 unpack cases working 2014-04-24 12:15:04 +02:00
Dennis Luxen b679a94930 first segment needs to be properly cut 2014-04-24 12:15:04 +02:00
Dennis Luxen 5bde545ce3 All good, but needs unpacking of start and end 2014-04-24 12:07:46 +02:00
Dennis Luxen e68c750389 remove boost typedefs 2014-04-24 12:05:43 +02:00
Dennis Luxen f16cb3c52d compressed geometries get serialized in R-tree 2014-04-24 12:05:43 +02:00
Dennis Luxen f7d5b0db9c uncompressed edges get serialized correctly'ish 2014-04-24 12:05:43 +02:00
Dennis Luxen ba0b664e3f further copy edits 2014-04-24 12:05:43 +02:00
Dennis Luxen 149d037824 further copy edits 2014-04-24 12:05:43 +02:00
Dennis Luxen d0349d9b0d further copy edits 2014-04-24 12:05:42 +02:00
Dennis Luxen c71c8b0047 Unpacking of intermediate paths 2014-04-24 12:03:19 +02:00
Dennis Luxen 3be644265b remove remnants of C-Style includes 2014-04-24 11:38:54 +02:00
Dennis Luxen cd6874ca60 remove remnants of C-Style includes 2014-04-24 11:28:12 +02:00
Dennis Luxen 7083978f9d remove remnants of C-Style includes 2014-04-24 11:28:12 +02:00
Dennis Luxen 4d132489c1 remove remnants of C-Style includes 2014-04-24 11:28:11 +02:00
Dennis Luxen b5170ed1fd remove trivial geometry nodes 2014-04-24 11:28:11 +02:00
Dennis Luxen cc915dbef2 take 2: workaround platform dependend outputs, discussed in #986 2014-04-21 19:25:24 +02:00
Dennis Luxen 9a5bf1ee95 workaround platform dependend outputs, discussed in #986 2014-04-21 18:31:45 +02:00
Dennis Luxen a14b6af5c0 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2014-04-21 17:41:54 +02:00
Dennis Luxen ec372ad01d implement tests marked todo, implements #986 2014-04-21 17:40:08 +02:00
Dennis Luxen 8a412ef69e implementing option tests marked @todo 2014-04-21 17:40:08 +02:00
Dennis Luxen c978364f49 implementing option tests marked @todo 2014-04-21 17:40:07 +02:00
Emil Tin 61d2a99dd4 remove left-over feature file 2014-04-21 17:40:07 +02:00
Emil Tin fdba916d83 cuke: fix options test, should use osrm file, not osm 2014-04-21 17:40:07 +02:00
Emil Tin a12209e61d cuke: test options for osrm-extract and osrm-prepare 2014-04-21 17:40:07 +02:00
Patrick Niklaus fc6607ce9e better error messages for extractor
Previously extractor would just crash because of unhandled exceptions.
Now it displays meaningful error messages.
2014-04-21 17:40:07 +02:00
Dennis Luxen 62ccbc7490 use insert(.) on unordered map instead of access operator, potential resource leak 2014-04-21 17:40:07 +02:00
Dennis Luxen b2b36984e1 make single parameter c'tor explicit 2014-04-21 17:40:07 +02:00
Dennis Luxen c10208407d Revert "fix resource leak, coverity issue 1198844"
This reverts commit 3a1a51ac46.
2014-04-21 17:40:07 +02:00
Dennis Luxen 64720c2d2e several lints fixed that were detected by facebook's flint 2014-04-21 17:40:07 +02:00
Dennis Luxen da81e4839a reverse include order 2014-04-21 17:40:07 +02:00
Dennis Luxen 25013afdd2 make single argument c'tor explicit (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen 678829ab28 fix include order (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen d8dffa9d71 make single paramter c'tors explicit (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen be8810077a make single paramter c'tors explicit (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen ee4ecb9783 fix inverted logic 2014-04-21 17:40:06 +02:00
Dennis Luxen eaed8572f0 make all error messages JSON 2014-04-21 17:40:06 +02:00
Dennis Luxen e91e6fb068 check for invalid parameter, coverity issue 1198843, also reformat source 2014-04-21 17:40:06 +02:00
Dennis Luxen cb17a0a49b fix resource leak, coverity issue 1198844 2014-04-21 17:40:06 +02:00
Dennis Luxen 248df9ca2d catch exceptions that may occur, coverity issue 1198845 2014-04-21 17:40:06 +02:00
Dennis Luxen fa615ed9f4 don't binpack parameters on 100 column width 2014-04-21 17:40:05 +02:00
Dennis Luxen 65aa4af6d9 allow 120 char wide columns 2014-04-21 17:40:05 +02:00
Dennis Luxen df56ad476e add clang format style file (to change) 2014-04-21 17:40:05 +02:00
Dennis Luxen 8e20fa89e8 catch exceptions that may occur, coverity issue 1198846 2014-04-21 17:40:05 +02:00
Dennis Luxen 76058729e0 dont reset coloring when it wasn't set in the first place, partially fixes Windows woes. See #979 2014-04-21 17:40:05 +02:00
Dennis Luxen 88a0cc8c9c dont reset coloring when it wasn't set in the first place 2014-04-21 17:40:05 +02:00
Dennis Luxen 2ea45c0c58 implement tests marked todo, implements #986 2014-04-21 17:29:48 +02:00
Dennis Luxen bf27f41f52 implementing option tests marked @todo 2014-04-21 17:21:02 +02:00
Dennis Luxen 853f6012d5 implementing option tests marked @todo 2014-04-21 17:20:15 +02:00
Emil Tin 14ad02777f remove left-over feature file 2014-04-21 17:18:30 +02:00
Emil Tin c1eb00f6d5 cuke: fix options test, should use osrm file, not osm 2014-04-21 16:07:03 +02:00
Emil Tin e5adaf974d cuke: test options for osrm-extract and osrm-prepare 2014-04-21 15:24:42 +02:00
Patrick Niklaus 727a29600d better error messages for extractor
Previously extractor would just crash because of unhandled exceptions.
Now it displays meaningful error messages.
2014-04-19 13:19:48 +02:00
Dennis Luxen a5ebdb9243 use insert(.) on unordered map instead of access operator, potential resource leak 2014-04-17 11:05:26 +02:00
Dennis Luxen 2ef37ee798 make single parameter c'tor explicit 2014-04-17 10:30:15 +02:00
Dennis Luxen c23575786c Revert "fix resource leak, coverity issue 1198844"
This reverts commit 3a1a51ac46.
2014-04-16 18:13:59 +02:00
Dennis Luxen 5a0d693c93 several lints fixed that were detected by facebook's flint 2014-04-16 16:59:40 +02:00
Dennis Luxen c6902528b3 reverse include order 2014-04-16 16:22:13 +02:00
Dennis Luxen f90993be86 make single argument c'tor explicit (thx flint) 2014-04-16 16:21:16 +02:00
Dennis Luxen e7db076648 fix include order (thx flint) 2014-04-16 16:16:42 +02:00
Dennis Luxen 6d52a7d3d4 make single paramter c'tors explicit (thx flint) 2014-04-16 16:15:49 +02:00
Dennis Luxen 3368b492b9 make single paramter c'tors explicit (thx flint) 2014-04-16 16:13:48 +02:00
Dennis Luxen 1222aa6d25 fix inverted logic 2014-04-09 23:10:58 -04:00
Dennis Luxen 67efd150d4 make all error messages JSON 2014-04-09 18:12:45 -04:00
Dennis Luxen 9894f2e053 check for invalid parameter, coverity issue 1198843, also reformat source 2014-04-09 12:03:19 -04:00
Dennis Luxen 3a1a51ac46 fix resource leak, coverity issue 1198844 2014-04-09 11:59:48 -04:00
Dennis Luxen a1b5429f4e catch exceptions that may occur, coverity issue 1198845 2014-04-09 11:57:15 -04:00
Dennis Luxen b11e39554f don't binpack parameters on 100 column width 2014-04-09 11:55:59 -04:00
Dennis Luxen a92c764945 allow 120 char wide columns 2014-04-09 11:48:48 -04:00
Dennis Luxen f581396f1d add clang format style file (to change) 2014-04-09 11:44:56 -04:00
Dennis Luxen 6814926f05 catch exceptions that may occur, coverity issue 1198846 2014-04-09 11:34:15 -04:00
Dennis Luxen b8f882dba4 dont reset coloring when it wasn't set in the first place, partially fixes Windows woes. See #979 2014-04-07 15:11:04 -04:00
Dennis Luxen 783e8edf71 dont reset coloring when it wasn't set in the first place 2014-04-07 15:07:07 -04:00
Dennis Luxen 966f1d654e Merge branch 'develop' for release v0.3.8 2014-04-04 15:35:37 +02:00
Dennis Luxen 02adaac468 remove an empty line to test jenkins web hook, take 2 2014-04-03 19:45:00 +02:00
Dennis Luxen 2b2a0d685f remove an empty line to test jenkins web hook 2014-04-03 19:27:13 +02:00
Dennis Luxen 6f2ec17640 pass path as ref to JSONDescriptor.h 2014-04-03 18:28:16 +02:00
Dennis Luxen 6c158f5a1b move typedef into a single line 2014-04-03 12:08:51 +02:00
Emil Tin df83dfdfe8 cuke: test travel time of individual instructions 2014-04-02 16:05:09 +02:00
Dennis Luxen 165c252fc8 disable lto partitioning when possible (fixes GCC < 4.8 issues, e.g. Debian stock compiler) 2014-04-02 10:49:32 +02:00
Dennis Luxen d21f63d327 activate LTO on platforms that support it, ie. most recent compilers 2014-04-01 18:11:45 +02:00
Dennis Luxen 05c33bee78 Merge pull request #973 from DennisOSRM/fix/clean_profile_indentation
cleanup indentation of lua profiles
2014-04-01 17:07:39 +02:00
Emil Tin 762dd17512 cleanup indentation of lua profiles 2014-04-01 15:40:52 +02:00
Emil Tin 5f7065848e clean cucumber comments, fixes 'file to long' problem with latest version of cucumber 2014-04-01 15:30:55 +02:00
Emil Tin 65e020a627 cuke: use new speed tests where relevant 2014-04-01 14:56:25 +02:00
Emil Tin 793e477898 active tests for fixed bugs 2014-04-01 14:56:25 +02:00
Dennis Luxen a5232f857e failed tests fail the build, see #970 2014-04-01 12:41:48 +02:00
Dennis Luxen 0ef7a72b33 Merge PR #970 'experimental/cuke_import_format' into develop 2014-04-01 12:02:56 +02:00
Emil Tin 717787ff62 travis: set osrm timeout to 60s 2014-03-31 21:46:01 +02:00
Emil Tin 2d599a5190 cuke: optional timeout 2014-03-31 21:45:53 +02:00
Emil Tin e73145d558 travis: set osrm timeout to 60s 2014-03-31 16:55:39 +02:00
Emil Tin 220e7748a9 cuke: use .osm by default, add tests for .pbf 2014-03-31 16:55:39 +02:00
Emil Tin 72f41c5b4f check for empty input in extractor, same msg in prepare 2014-03-31 16:55:39 +02:00
Emil Tin 775627473a remove .osm deprecation warning 2014-03-31 16:55:39 +02:00
Emil Tin ba2356d2ba cuke: optional timeout 2014-03-31 16:55:01 +02:00
Emil Tin 179f53b21b cuke: fix test for -v on travis 2014-03-31 15:29:00 +02:00
Emil Tin 3ccd3b5650 cuke: increase osrm launch/shutdown timeout 2014-03-31 13:55:29 +02:00
Dennis Luxen 224655f8cb fix osmosis install on Travis CI. May fix #970 2014-03-31 11:53:10 +02:00
Emil Tin fd96c7c488 fix travel speeds for cars 2014-03-27 18:22:04 +01:00
Emil Tin 45c96f73c2 cuke test showing odd car speeds 2014-03-27 18:02:42 +01:00
Emil Tin c5893ef6e8 cuke: check for invalid expectation formats 2014-03-27 17:32:37 +01:00
Emil Tin 8b1f09d302 cuke: test speed, fix logging, clear log files on each run 2014-03-27 10:38:03 +01:00
Emil Tin cb1b824a75 cuke: improve routability tables, test for speed 2014-03-27 10:38:02 +01:00
Emil Tin b0ce9e4af7 cuke: don't use scenario outlines, to fix problem with jenkins 2014-03-27 10:38:02 +01:00
Dennis Luxen aae3637e0c implements #958 2014-03-25 14:54:52 +01:00
Dennis Luxen 33faa2f252 set output size on StockReplies properly 2014-03-24 18:13:40 +01:00
andrewbts 482d79ef4b Fix comment typo
SharedDataFacade.h is for the shared memory case; old comment implied the opposite.
2014-03-24 15:52:54 +01:00
Dennis Luxen 6bdd517c43 new cucumber profile for Jenkins that doesn't fail because of an old Gherkin bug 2014-03-24 14:29:19 +01:00
Dennis Luxen a337109618 implements #961 2014-03-24 12:16:30 +01:00
Dennis Luxen 0ae5ace520 Merge PR #960 2014-03-24 11:30:55 +01:00
Dennis Luxen a4306cddef remove NO-BREAK SPACE (U+00A0) that broke testing 2014-03-24 10:16:32 +01:00
Dennis Luxen 1f97c5518e fixes build errors from 9e10b94 2014-03-24 10:06:42 +01:00
Clint Harris 1823a4da36 Added missing Boost date_time component. Resolves issue #925. 2014-03-22 12:30:24 -04:00
Clint Harris d60caf7095 CMake now adds RPATH info to executables. Resolves issue #960. 2014-03-22 11:44:51 -04:00
Emil Tin 9e10b94339 cuke: test file options 2014-03-22 12:01:07 +01:00
Emil Tin 7048dd754d cuke: check exit code as last step, add step to non-existing file 2014-03-22 00:47:20 +01:00
Emil Tin de29e17d95 cuke: add a few options steps 2014-03-22 00:38:53 +01:00
Emil Tin c299989ff7 reorganize options tests 2014-03-22 00:33:23 +01:00
Emil Tin 0b655ea6a1 trial option 2014-03-22 00:16:45 +01:00
Dennis Luxen 538827942a workaround for inconsistent error messages across boost versions 2014-03-20 14:38:16 +01:00
Dennis Luxen 8bd5f69e04 fixes #958, activates 2 additional tests 2014-03-20 13:19:36 +01:00
Dennis Luxen c470ea9fa1 lock to RAM on Linux only after options are parsed 2014-03-20 09:53:05 +01:00
Emil Tin c1806476af cuke: test osrm-routed options 2014-03-19 19:28:24 +01:00
Emil Tin af41c9f6e4 cuke: detach osrm-routed to avoid zombie processes 2014-03-19 18:03:47 +01:00
Dennis Luxen 823e8d24b5 deactivate file validation as it is externally handled 2014-03-18 16:27:46 +01:00
Dennis Luxen 4028c0b24f implement proper checks for conflicting inputs 2014-03-18 16:22:42 +01:00
Dennis Luxen 2e4ff30103 fix parameter regression when using shared memory 2014-03-18 10:51:36 +01:00
Dennis Luxen 121dcca7e3 refactor a bit for better readability 2014-03-17 15:46:13 +01:00
Dennis Luxen 5adfe2d46b transfrom short switch statements into readable if statements 2014-03-17 15:45:47 +01:00
Dennis Luxen 03f4aaa2d6 make functions const, make short variable name more telling 2014-03-17 15:31:13 +01:00
Dennis Luxen d67c3f36ff call function object instead of static function 2014-03-17 15:28:42 +01:00
Dennis Luxen e199d30beb move static function into funtion object 2014-03-17 15:27:33 +01:00
Dennis Luxen 27e2de2b1f fix inverted logic 2014-03-17 15:19:24 +01:00
Dennis Luxen 8a6d07342e remove redundant local variable 2014-03-17 15:14:29 +01:00
Dennis Luxen ab39457fe1 move bit-wise operator out of conditions 2014-03-17 15:13:36 +01:00
Dennis Luxen e6933ea413 avoid private static member functions 2014-03-17 15:12:13 +01:00
Dennis Luxen 422e0c44d5 reverse inverted logic 2014-03-17 14:55:33 +01:00
Dennis Luxen ad03b409ab make variable names more telling 2014-03-17 14:42:24 +01:00
Dennis Luxen 38ae213260 make variable names more telling 2014-03-17 14:40:10 +01:00
Dennis Luxen 6a0a59896e make variable names more telling 2014-03-17 14:39:24 +01:00
Dennis Luxen 187cb56364 split long line in two 2014-03-17 14:37:33 +01:00
Dennis Luxen 1fe96d0d22 remove collapsable if statement 2014-03-17 14:36:34 +01:00
Dennis Luxen 52b859b3e6 remove pesky fun ptr from CRC32 computation 2014-03-17 11:07:01 +01:00
Dennis Luxen 9483b781e2 provide better feedback on command lines 2014-03-14 11:14:19 +01:00
Dennis Luxen 791f475168 implement #951, better command line handling 2014-03-14 10:15:39 +01:00
Dennis Luxen 6b69d6dce2 implements #951 2014-03-13 22:48:09 +01:00
Dennis Luxen 720abbc81e minor tweak to disable C++11 flag on demand 2014-03-13 22:08:03 +01:00
Dennis Luxen e3183cfd16 set stdlib explicitly, fix indentations 2014-03-13 13:28:58 +01:00
Dennis Luxen e07423f260 minor copy-edits to PR #946 2014-03-12 13:56:25 +01:00
Daniel Karch ecfda146b2 minor change 2014-03-12 10:48:54 +01:00
Daniel Karch f923f508f5 applied requested changes to EdgeBasedNode.h 2014-03-12 10:24:35 +01:00
Daniel Karch b465dabe77 Refactored the EdgeBasedNode class.
This includes more robust computations in ComputePerpendicularDistance.
There were cases where ComputePerpendicularDistance divided by zero and had
to handle special cases, even though this was not necessary.
2014-03-11 16:40:20 +01:00
Dennis Luxen d8d6b91257 std lib adjustable on all versions of OS X 2014-03-06 14:48:20 +01:00
Dennis Luxen 0946fac11f Escape characters in JSON instead of HTML-entetizing, implements #895 2014-03-04 14:54:41 +01:00
Dennis Luxen c50b69c654 Escape characters in JSON instead of HTML-entetizing, implements #895 2014-03-04 14:54:34 +01:00
Dennis Luxen 32bf99ba40 decode all URIs, fixes #937, 386 2014-03-04 13:56:11 +01:00
Dennis Luxen 0baa8215ef fix unitialized variable warning 2014-03-04 13:52:41 +01:00
Dennis Luxen 85a007d87b set backward speed properly, partially fixes #936 2014-03-03 15:31:57 +01:00
Dennis Luxen 7b14de13ec assign complete edge data if duplicate shortcut edge has lower weight 2014-03-03 14:08:34 +01:00
Dennis Luxen 117ebe1c32 add switch to override stdlib implementation on OS X < 10.9 2014-02-27 11:07:53 +01:00
Dennis Luxen 2b010811d8 fixes #932, and partially also fixes #921 2014-02-25 12:50:08 +01:00
Dennis Luxen 4b94f1fa83 implements compilation issues on non-X86(-64) targets, also see #921 2014-02-25 10:57:57 +01:00
Dennis Luxen d73f3ebd1b fix tests for scaled maxspeeds 2014-02-14 18:23:25 +01:00
Dennis Luxen 4c48cda4cd refactor HashTable facade class 2014-02-14 18:18:26 +01:00
Dennis Luxen 9e64ccdbf2 scale maxspeeds to 2/3 to be more realistic and in sync with the default profile 2014-02-14 18:17:37 +01:00
Dennis Luxen aedf9d3a91 run debug build on different port 2014-02-14 18:17:00 +01:00
Dennis Luxen 0ee94a5729 add new tool to ignore list 2014-02-13 18:11:53 +01:00
Dennis Luxen 2130630293 run tests on different ports 2014-02-12 16:34:46 +01:00
Dennis Luxen 445cf5d42c ignore broken osmosis from Travis CI repo 2014-02-12 16:25:57 +01:00
Dennis Luxen 08f13a1776 install osmosis manually 2014-02-12 16:22:26 +01:00
Dennis Luxen f406dc51fa Merge branch 'patch-1' of https://github.com/alex85k/Project-OSRM into alex85k-patch-1 2014-02-12 15:27:12 +01:00
Dennis Luxen 7580777e43 implement and use portable implementation of canonical file paths, see #909, this time against dev branch 2014-02-11 15:55:22 +01:00
Dennis Luxen ea30005762 fixes and closes #914 and updates #907 2014-02-11 14:34:47 +01:00
Dennis Luxen 7794cd6274 do not instantiate shared memory facility in routed, fixes #905 and #910 2014-02-11 11:35:29 +01:00
Dennis Luxen 45a4fe44f7 disable cucumber tests until the travis CI issues are sorted out 2014-02-10 16:53:29 +01:00
Dennis Luxen 1d225078eb install osmosis manually, take three 2014-02-10 16:01:48 +01:00
Dennis Luxen 533caf8c0f install osmosis manually, take two 2014-02-10 15:45:24 +01:00
Dennis Luxen e6c25ae290 install osmosis manually 2014-02-10 15:35:36 +01:00
Dennis Luxen 264077acac install libpostgis-java to fulfil dependencies 2014-02-10 15:21:48 +01:00
Dennis Luxen 0ff18881b6 explicit rvm use, workaround for Travis CI testing woes 2014-02-10 15:02:05 +01:00
Dennis Luxen 9e0e536dbc fix yml syntax 2014-02-10 11:58:56 +01:00
Dennis Luxen 1a9e54ba33 install bundler without sudo, change Travis environment 2014-02-10 11:57:48 +01:00
Dennis Luxen 9378af1057 fixes #907, segfault when ampersands where missing 2014-02-10 11:43:26 +01:00
Dennis Luxen cd6075a884 Merge pull request #906 from andrewbts/patch-1
Fix comment typo
2014-02-05 20:41:12 +01:00
andrewbts 1da3a00b92 Fix comment typo
SharedDataFacade.h is for the shared memory case; old comment implied the opposite.
2014-02-05 11:19:33 -08:00
alex85k 275961f088 Fix assertion in debug version
When running tests on FreeBSD 10 on debug verion I got boost assertion errors in mutex.hpp:79 . 

It seems that mutex unlock is not needed (it is already unlocked and behavior is undefined).
2014-02-04 19:56:23 +06:00
Dennis Luxen f14fac3f7d fixes off-by-one and testing issue discussed in 889 2014-02-01 16:02:43 +01:00
Dennis Luxen ce784e0491 distinguish between left and right, thx @emiltin 2014-01-27 12:58:23 +01:00
Dennis Luxen 65ad3bb941 fix test regression 2014-01-27 12:55:17 +01:00
Dennis Luxen b5b4280c3b remove c-style calls to fabs 2014-01-27 11:26:34 +01:00
Dennis Luxen 0649f6e607 preparing call of turn penalty function 2014-01-27 11:18:26 +01:00
Dennis Luxen 22c2efded9 Some mild refactoring of the BinaryHeap code. style only 2014-01-24 11:24:23 +01:00
Dennis Luxen 7825279405 reverting back to two cores on travis 2014-01-24 10:17:57 +01:00
Dennis Luxen 2623c7023c compile on travis with the maximum number of cores 2014-01-23 13:47:05 +01:00
Dennis Luxen 2138fdfadf re-enable cucumber tests on travis CI 2014-01-23 13:44:40 +01:00
Dennis Luxen 40517e3010 implements #872 2014-01-23 13:31:29 +01:00
Dennis Luxen 1341214044 Add fwd decl to slash compile time 2014-01-23 13:30:38 +01:00
Dennis Luxen 34e2ef13cf use z0 parameters on z0 2014-01-23 13:20:57 +01:00
Dennis Luxen 058219528d fix floating point accuracy woes on certain hardware platforms 2014-01-22 19:35:30 +01:00
Dennis Luxen f4bd175616 fixes #881 2014-01-22 14:52:31 +01:00
Dennis Luxen fea0c07e1c implements #386 2014-01-21 16:31:29 +01:00
Dennis Luxen f684fa9a7b fix tests to resemble the fixed duration calculation 2014-01-21 16:11:51 +01:00
Dennis Luxen 2855b94aa8 remove disabled debug output 2014-01-21 15:12:06 +01:00
Dennis Luxen 9958aaae4f fixes #871 2014-01-20 19:24:20 +01:00
Dennis Luxen 289e5ada2c catch prev. uncaught exception, coverity issue 1121925 2014-01-09 18:21:07 +01:00
Dennis Luxen 648eed6532 fix resource leak, performance issue, alternative route success rate. coverity issue 971431 2014-01-09 18:05:29 +01:00
Dennis Luxen d94955d51e fix resource leak, coverity issue #1121924 2014-01-09 17:11:31 +01:00
Dennis Luxen 046fe93f1f refactor ExtractorStructs.h for faster compiles. achieves approx. 10 secs 2014-01-09 16:13:35 +01:00
Dennis Luxen ce60af5029 fixes issues #770 and #856 2014-01-08 17:18:59 +01:00
Dennis Luxen dbe70ffc8a save 4 bytes per internal edge 2014-01-08 17:11:31 +01:00
Dennis Luxen 8acf081be3 remove dead function decl 2013-12-27 15:47:51 +01:00
Dennis Luxen c5f6065280 reorder code to make it a bit more readable 2013-12-27 12:38:08 +01:00
Dennis Luxen 07509ba5c9 remove left-over debug output 2013-12-27 12:15:17 +01:00
Dennis Luxen 8b3c8f7093 refactoring variable names and layout to be more readable 2013-12-23 17:55:29 +01:00
Dane Springmeyer c3e0b68399 fix pkg-config --static when pthread is reported 2013-12-21 13:14:48 -05:00
Dane Springmeyer f0dd1fdfc7 pkg-config fixes 2013-12-20 14:00:30 -05:00
DennisOSRM 5fd8c0938a include and typo fixes 2013-12-20 18:14:09 +01:00
DennisOSRM b3f4aa4504 further include cleanup 2013-12-20 18:01:53 +01:00
DennisOSRM 4718cf6cc0 fixed signed/unsigned comparison 2013-12-20 15:30:39 +01:00
DennisOSRM ac07c78664 build libOSRM static library implicitly. Overridable by -DBUILD_SHARED_LIBS:BOOL=OFF 2013-12-20 13:24:25 +01:00
DennisOSRM 4a3db7e2c3 Merging PR #847 manually 2013-12-20 13:15:57 +01:00
DennisOSRM a23158f986 remove deleted files 2013-12-20 13:14:02 +01:00
DennisOSRM 838322299a generate pkgconfig file 2013-12-20 13:13:35 +01:00
DennisOSRM 41f3f53540 move includes to include/osrm 2013-12-20 13:12:56 +01:00
Dennis Luxen a26d982f52 deactivate dead code 2013-12-19 19:19:26 +01:00
Dane Springmeyer 5e4121ac58 libosrm as static lib 2013-12-18 18:08:25 -05:00
Dennis Luxen 81d8c8f9bf don't inline code in debug build 2013-12-18 18:33:24 +01:00
Dennis Luxen 0c34addfa7 fix signed/unsigned comparison 2013-12-18 15:50:14 +01:00
Dennis Luxen 6a68fe6a4f fix comparison between signed and unsigned integer 2013-12-18 13:19:23 +01:00
Dennis Luxen 0d246a4422 enable profiling information in debug build 2013-12-18 13:16:32 +01:00
Dennis Luxen 991c9f2f8b remove superflous include 2013-12-18 12:01:16 +01:00
Dennis Luxen ffd36b5489 add missing include 2013-12-18 12:00:58 +01:00
Dennis Luxen b9149658a8 remove unused variable 2013-12-18 12:00:35 +01:00
Dennis Luxen 21ff3fbccd un-lint'ing CMakeLists.txt 2013-12-17 21:42:00 +01:00
Dennis Luxen 90efbefbec install includes to include/osrm 2013-12-17 20:26:15 +01:00
Dennis Luxen 8f89d75edc remove deleted files from repo 2013-12-17 18:02:49 +01:00
Dennis Luxen 5d082f53ae remove deleted files from repo 2013-12-17 18:02:34 +01:00
Dennis Luxen 591d79ba49 remove deleted files from repo 2013-12-17 18:02:24 +01:00
Dennis Luxen 5ee6ede824 remove deleted files from repo 2013-12-17 18:02:01 +01:00
Dennis Luxen 095a58b1bd remove deleted files from repo 2013-12-17 18:01:42 +01:00
Dennis Luxen fd2f000075 install lib header files with make install target 2013-12-17 17:59:44 +01:00
Dane Springmeyer bb244646df bake gitdescription and uuid into OSRM library to avoid failure points of linking them directly 2013-12-16 18:49:35 -05:00
Dane Springmeyer 238dd07cf6 fix linking order to unbreak linux builds against static protobuf and libz 2013-12-16 17:03:17 -05:00
Dennis Luxen aea5e446e5 minor efficiency improvements 2013-12-16 19:52:57 +01:00
Dennis Luxen 203beff4d2 remove dead code 2013-12-16 18:33:08 +01:00
Dennis Luxen cb6f4ad646 (partially) sanitize capitalization 2013-12-16 17:58:57 +01:00
Dennis Luxen f7b72dd136 minor typo 2013-12-16 17:52:45 +01:00
Dennis Luxen 96aff57275 fixes #731, perpendicular projection to nearest location 2013-12-16 17:36:36 +01:00
Dennis Luxen 4b46d07380 remove debug output 2013-12-16 17:32:55 +01:00
Dennis Luxen 204f7c918e remove empty line 2013-12-16 17:26:18 +01:00
Dennis Luxen b1c83e6588 link against right pthreads library 2013-12-16 17:25:17 +01:00
Dennis Luxen c55bd11377 Merge PR 838
Conflicts:
	CMakeLists.txt
2013-12-16 12:52:41 +01:00
Dennis Luxen 885a9df356 remove duplicate symbol 2013-12-16 11:39:38 +01:00
Dennis Luxen 0a373018c6 properly link osrm-prepare 2013-12-16 11:36:59 +01:00
Dennis Luxen 8c4c1a56fd reduce compile time by using fwd decls 2013-12-16 11:29:38 +01:00
Dennis Luxen de790c7c19 delete file 2013-12-16 11:21:46 +01:00
Dennis Luxen 3c2bf76103 implements #839, check for 32 bits properly, bump required boost version to 1.46 2013-12-16 11:21:30 +01:00
Dane Springmeyer 13bc41fc36 CMake: Respect CXXFLAGS set in environment
Without this change the `CXXFLAGS` environment setting is not respected (tested on OS X 10.8/clang++)
2013-12-15 15:32:15 -05:00
Dennis Luxen 758027e2e0 untangling includes to cut down compile time 2013-12-13 18:49:05 -05:00
Dennis Luxen 25b352aeab add/delete several files 2013-12-13 17:27:31 -05:00
Dennis Luxen b030fe7db2 break out Coordinate in compile unit 2013-12-13 17:26:57 -05:00
Dennis Luxen 9b09c9f0c3 move includes into compile unit 2013-12-13 12:34:21 -05:00
Dennis Luxen de73809bb9 remove unneeded includes 2013-12-13 12:33:41 -05:00
Dennis Luxen 7144f69683 movve osrm class into hidden object 2013-12-13 12:32:24 -05:00
Dennis Luxen c3396fa6fd add compile targets for the main binaries (not the aux utils) 2013-12-13 10:55:57 -05:00
Dennis Luxen 924a41a2f4 Initialize pointer always 2013-12-13 09:52:57 -05:00
Dennis Luxen a492bf3885 kill superflous semicolon 2013-12-13 09:52:22 -05:00
Dennis Luxen 662714fca3 add another minor viaroute check 2013-12-12 18:37:36 -05:00
Dennis Luxen 4fc4e93ab5 adapt tests to changed output, killed version and transactionId 2013-12-12 18:37:00 -05:00
Dennis Luxen d0b5929a9e explicitly give the locations of all via locations in response 2013-12-12 18:35:23 -05:00
Dennis Luxen 58dc98460b remove left-over todo marker 2013-12-12 18:33:27 -05:00
Dennis Luxen e0dd4848b0 add function to set edge target 2013-12-12 18:32:12 -05:00
Dennis Luxen cef01f5dbc remove superflous blank padding 2013-12-12 18:31:08 -05:00
Dennis Luxen 88af9c545b add util funtion to iterate adjacent pairs of a stl compliant container 2013-12-12 18:29:51 -05:00
Dennis Luxen cd1f45e248 Util/ContainerUtils.h 2013-12-12 18:28:39 -05:00
Dennis Luxen d5eee3138f fixes issues #768, #794, #812 2013-12-11 15:36:32 -05:00
Dennis Luxen fdfe0ce63d Implements #822 (partially) 2013-12-09 14:20:35 -05:00
Dennis Luxen ba6641ed9a fix node-OSRM build, https://github.com/DennisOSRM/node-OSRM/issues/19 2013-12-09 12:03:02 -05:00
Dennis Luxen fb13e3ddb8 add new include 2013-12-09 11:47:42 -05:00
Dennis Luxen ca17efd764 break out OriginalEdgeData class into its own include 2013-12-09 11:45:45 -05:00
Dennis Luxen dd104a49f6 break-out Requesthandler into compile unit 2013-12-09 10:54:17 -05:00
Dennis Luxen b849d008d2 break-out Requesthandler into compile unit 2013-12-09 10:48:32 -05:00
Dennis Luxen 1e09935501 make counters available in release and debug build, take2 2013-12-09 09:17:38 -05:00
Dennis Luxen d7e558350b make counters available in release and debug build 2013-12-09 09:04:44 -05:00
Dennis Luxen 04afe8fbf1 remove pesky sstream 2013-12-08 19:43:43 +01:00
Dennis Luxen 392726bad3 remove pesky sstream 2013-12-08 19:42:48 +01:00
Dennis Luxen 19285d61ab reorder includes to cut compile time 2013-12-08 19:38:13 +01:00
Dennis Luxen 015b29e8a3 remove superflous ifdef 2013-12-08 19:12:01 +01:00
Dennis Luxen aff61dbc3e remove unused include 2013-12-08 19:11:38 +01:00
Dennis Luxen 37f5d755f1 break out header file in compile unit 2013-12-08 19:11:22 +01:00
Dennis Luxen 98cd3465d3 remove dead code 2013-12-08 19:11:03 +01:00
Dennis Luxen 009f08dca3 Refactoring PathData class 2013-12-08 19:10:10 +01:00
Dennis Luxen 2edf4906a4 refactoring SegmentInformation to fit into a cache line 2013-12-08 18:33:53 +01:00
Dennis Luxen ee6c15b997 remove self include 2013-12-08 16:30:08 +01:00
Dennis Luxen 03df07e4b6 rebasing develop on master branch. 2013-12-08 15:52:53 +01:00
Dennis Luxen 501f2f8267 workaround for #783 2013-12-08 15:52:23 +01:00
Dennis Luxen e949677c48 fixes #808 2013-12-08 15:52:23 +01:00
Dennis Luxen b2512915ae cache dependencies on travis ci 2013-12-08 15:52:23 +01:00
Dennis Luxen dc9db06cc8 reverting skeleton, introducing later 2013-12-08 15:52:23 +01:00
Dennis Luxen cb5931aaeb add skeleton for geometry compression 2013-12-08 15:52:23 +01:00
Dennis Luxen da17e55657 don't use clang specific defines 2013-12-08 15:52:22 +01:00
Dennis Luxen f47d944349 do not seek in temporary storage 2013-12-08 15:52:22 +01:00
Dennis Luxen 682079adc6 add buffering to temporary storage 2013-12-08 15:52:22 +01:00
Dennis Luxen f0fb97e67c add buffering to temporary storage 2013-12-08 15:52:22 +01:00
Dennis Luxen 6e5058f95f further refactoring and code simplification 2013-12-08 15:52:22 +01:00
Dennis Luxen 31b8997518 partially fixes #768, #794, #812 2013-12-08 15:52:22 +01:00
Dennis Luxen 76a9723268 remove dead code 2013-12-08 15:52:22 +01:00
Dennis Luxen 5fe79764de implements #801 2013-12-08 15:52:22 +01:00
Dennis Luxen 186859fcf0 clean up of build config 2013-12-08 15:52:22 +01:00
Dennis Luxen b545d60453 temporarily fixes #811 plus 16 others 2013-12-08 15:52:22 +01:00
DennisOSRM f68a046080 cast to larger data type on 32bits, probably fixes #809 2013-12-08 15:52:22 +01:00
Dennis Luxen f77fa5b34c clear memory early by swap trick 2013-12-08 15:52:21 +01:00
Dennis Luxen 38bf0c276c moving BFS exploration into its own function 2013-12-08 15:52:21 +01:00
Dennis Luxen ef5c8c24a8 fixing coverity issue 2013-12-08 15:52:21 +01:00
Dennis Luxen 4e8fb92e07 renaming file 2013-12-08 15:52:21 +01:00
Dennis Luxen 4f1ff5b24c renaming file 2013-12-08 15:52:21 +01:00
Dennis Luxen 22abc27b6b use explicit unsigned type in max operation 2013-12-08 15:52:21 +01:00
Dennis Luxen 19f6d885fe remove potential division by zero 2013-12-08 15:52:21 +01:00
Dennis Luxen b19a633441 add geometry compressor 2013-12-08 15:52:21 +01:00
Dennis Luxen 997dcad799 make rtree query do O(1) allocations only 2013-12-08 15:52:21 +01:00
Dennis Luxen e35efd001c move implementation details out of templat'ized container code 2013-12-08 15:52:21 +01:00
Dennis Luxen 50d6b10be4 move distance computation from r-tree to element type class 2013-12-08 15:52:21 +01:00
Dennis Luxen 5ef7ea794a move Hilbert curve computation in compile unit 2013-12-08 15:52:20 +01:00
Dennis Luxen e70485f1fd workaround for #783 2013-12-06 15:08:36 +01:00
Rodolphe Quiedeville f55f8a3629 [options] string is more explicit 2013-12-06 13:23:25 +01:00
Dennis Luxen fbbd6caf97 Merge pull request #818 from rodo/master
Add missing option '-p' in help message
2013-12-06 04:14:59 -08:00
Dennis Luxen bde3f95ae9 fixes #808 2013-12-06 12:06:51 +01:00
Dennis Luxen a5c406a4dd cache dependencies on travis ci 2013-12-06 10:14:42 +01:00
Rodolphe Quiedeville 58a57543ce [options] string is more explicit 2013-12-04 15:48:28 +01:00
Dennis Luxen e32bc5e186 reverting skeleton, introducing later 2013-11-29 19:00:00 +01:00
Dennis Luxen 7a5f45ac94 add skeleton for geometry compression 2013-11-29 18:49:02 +01:00
Dennis Luxen 657f7577bf don't use clang specific defines 2013-11-29 16:37:36 +01:00
Dennis Luxen 48355447f9 do not seek in temporary storage 2013-11-29 16:27:26 +01:00
Dennis Luxen c8f7e6331b add buffering to temporary storage 2013-11-29 15:38:21 +01:00
Dennis Luxen 40bb27c95f add buffering to temporary storage 2013-11-29 15:38:15 +01:00
Dennis Luxen 78f8124c63 further refactoring and code simplification 2013-11-28 18:50:12 +01:00
Dennis Luxen 94d5bcbf1c partially fixes #768, #794, #812 2013-11-28 15:26:13 +01:00
Dennis Luxen ad5d8c6f9a remove dead code 2013-11-28 15:24:23 +01:00
Dennis Luxen 4911601b24 implements #801 2013-11-27 23:24:00 +01:00
Dennis Luxen cb86d3d829 clean up of build config 2013-11-27 17:27:47 +01:00
Dennis Luxen 24c6314f1a Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-11-27 16:37:48 +01:00
Dennis Luxen 02e2b3bd47 temporarily fixes #811 plus 16 others 2013-11-27 16:37:40 +01:00
DennisOSRM ec84b3a0ca cast to larger data type on 32bits, probably fixes #809 2013-11-26 22:41:01 +01:00
Dennis Luxen 4455e816aa clear memory early by swap trick 2013-11-26 19:56:45 +01:00
Dennis Luxen 3df89c0dfe moving BFS exploration into its own function 2013-11-26 19:43:30 +01:00
Dennis Luxen f5d22c904f fixing coverity issue 2013-11-26 19:41:55 +01:00
Dennis Luxen 2233c44d36 renaming file 2013-11-26 19:41:36 +01:00
Dennis Luxen d5f6c1c15c renaming file 2013-11-26 19:41:32 +01:00
Dennis Luxen e36a27307b use explicit unsigned type in max operation 2013-11-26 14:27:19 +01:00
Dennis Luxen cf527ed819 remove potential division by zero 2013-11-26 14:25:53 +01:00
Dennis Luxen a8e8833a8d add geometry compressor 2013-11-25 19:05:58 +01:00
Dennis Luxen 349df0dc94 make rtree query do O(1) allocations only 2013-11-22 18:58:58 +01:00
Dennis Luxen 0e33f638e6 move implementation details out of templat'ized container code 2013-11-22 18:43:01 +01:00
Dennis Luxen 50ccfbf554 move distance computation from r-tree to element type class 2013-11-22 18:05:47 +01:00
Dennis Luxen e2c093856c move Hilbert curve computation in compile unit 2013-11-22 18:05:41 +01:00
Dennis Luxen 992458ae4b fix indentation 2013-11-21 00:06:00 +01:00
Dennis Luxen 8c16686150 remove dead code 2013-11-21 00:05:37 +01:00
Dennis Luxen 7cbadfbd12 remove dead code 2013-11-21 00:05:28 +01:00
Dennis Luxen 0e43697ee0 fixes issue #804 2013-11-20 18:24:06 +01:00
DennisOSRM 7de27df309 fix linking on Ubuntu 13.10 2013-11-20 16:22:39 +01:00
DennisOSRM b06db1ba39 Merge branch 'dep-liblua' of https://github.com/NochEinDirk/Project-OSRM-contribute into NochEinDirk-dep-liblua 2013-11-20 10:56:47 +01:00
Dennis Luxen 5fe24cb689 report a warning if shared memory segment cannot be locked into RAM 2013-11-19 10:38:59 +01:00
Dennis Luxen 733d1384a4 fixes #803 2013-11-19 10:18:59 +01:00
Dennis Luxen 99e9d0d023 ignore impassable ways, requested by HOT 2013-11-18 16:54:52 +01:00
Dennis Luxen 2bd1e46ab9 Remove left-over merge hunk 2013-11-18 11:54:39 +01:00
Dennis Luxen cabaad4b17 replaced contigouos output data with collection of small'ish sub blocks. saves (re-)allocations. also removed a remaining stringstream 2013-11-14 17:16:26 -05:00
Dennis Luxen 8b6fe691ed add missing files 2013-11-14 12:44:36 -05:00
Dennis Luxen ccf9efdaa5 rename file, untangle more includes 2013-11-14 12:42:57 -05:00
Dennis Luxen bf66bec4c7 rename file, untangle more includes 2013-11-14 12:42:50 -05:00
Dennis Luxen 3319709526 rename file, untangle more includes 2013-11-14 12:42:33 -05:00
Dennis Luxen 7ceab5c88c lock data into RAM on Linux 2013-11-14 12:33:09 -05:00
Dennis Luxen 94d4789e68 pull include from correct position 2013-11-14 12:31:51 -05:00
Dennis Luxen b13985d550 remove old files 2013-11-14 12:31:20 -05:00
Dennis Luxen dc4a3e9b89 untangle server and http components 2013-11-14 12:29:56 -05:00
Dennis Luxen d538c35532 moving and splitting of http protocal data types 2013-11-14 12:28:28 -05:00
Dennis Luxen cfd26321b5 lock shared memory into RAM by default on Linux 2013-11-14 10:03:56 -05:00
Dennis Luxen 61d955f3de move Reply into compile unit 2013-11-13 18:42:57 -05:00
Dennis Luxen a9f54c44e9 move Reply into compile unit 2013-11-13 18:42:42 -05:00
Dennis Luxen 125877035f move polyline generalizer into compile unit 2013-11-13 17:48:58 -05:00
Dennis Luxen 8f4b0c8078 de-templetize polyline generalizer 2013-11-13 17:33:19 -05:00
Dennis Luxen 1863e85bf5 move polyline compressor into compile unit 2013-11-13 17:32:44 -05:00
Dennis Luxen 488c6099fc remove test suite from travis 2013-11-13 16:48:15 -05:00
Dennis Luxen 67abc6d2cf removing dead legacy code 2013-11-13 16:11:31 -05:00
Dennis Luxen c56a57c0ba refactor legacy code 2013-11-13 15:52:01 -05:00
Dennis Luxen 30b2c1ad61 refactor input restrictions class 2013-11-13 15:23:44 -05:00
Dennis Luxen 5e279363e4 sort data externally with 4GB of RAM 2013-11-13 11:09:20 -05:00
Dennis Luxen abb7509f03 link against libc++ on OS X Mavericks by default 2013-11-13 11:08:27 -05:00
Dennis Luxen 1cd60c05f3 renaming a couple of variables to be more obvious 2013-11-12 19:02:26 -05:00
Dennis Luxen 510cc22484 Refactor name of legacy class _Node into more telling name ExternalMemoryNode 2013-11-12 18:23:09 -05:00
Dennis Luxen 3da664236c reverting premature revert 2013-11-12 17:39:24 -05:00
Dennis Luxen 7e35a7fe0c remove deprecated stxxl calls to be ready for the 1.4.0 release 2013-11-12 17:33:03 -05:00
Dennis Luxen 58ef7db5d6 allow 64 bit sizes for shared memory regions 2013-11-12 15:01:40 -05:00
Dennis Luxen f9de4a394c minor code shrink 2013-11-11 15:50:33 -05:00
Dennis Luxen dced5816df RVO optimization of output buffer generation 2013-11-11 15:17:52 -05:00
Dennis Luxen 690ac740d2 support ANSI colors in logging class 2013-11-11 13:19:38 -05:00
Dennis Luxen 89d0412e22 fix include order 2013-11-08 10:08:27 -05:00
Dennis Luxen a305752faf access unordered map through iterators only 2013-11-08 09:47:32 -05:00
Dirk L 469b139e89 .travis.yml: Inconsistency between Master and Develop branch?! 2013-11-08 15:33:12 +01:00
Dirk L 8f5d9c4816 Merge branch 'develop' into dep-liblua 2013-11-08 15:20:56 +01:00
Dirk L 7102c77e0b Merge branch 'master' into dep-liblua 2013-11-08 15:10:53 +01:00
Dennis Luxen 115ae21f1f implements #733 2013-11-08 08:56:03 -05:00
Dennis Luxen 8d3fdf45b9 implements #781 2013-11-06 17:13:09 -05:00
Dennis Luxen 1e7e5ea57c Merge pull request #779 from springmeyer/better-file-not-found-error
Better file not found error
2013-11-05 03:03:23 -08:00
Dane Springmeyer 7c8b91456f match exact error from develop branch ~3 months ago 2013-11-04 17:06:02 -08:00
Dane Springmeyer dc960f30f5 if a file cannot be found print that preamble instead of just the filename 2013-11-04 16:56:41 -08:00
Dane Springmeyer ba12e31280 osx build: only set -std=c++11 flag for >= 10.9 2013-11-04 14:37:25 -08:00
Dennis Luxen 027a4081a2 fix loading of ini files 2013-11-01 15:24:13 +01:00
Dennis Luxen 190def17e5 fix coverity issue 1121924, Resource leak 2013-10-31 14:05:06 +01:00
Dennis Luxen 9730526d33 fix coverity issue 1121925, Uncaught exception 2013-10-31 13:21:52 +01:00
Dennis Luxen c87c843308 fix coverity issue 1121926, Uninitialized pointer field 2013-10-31 13:16:46 +01:00
Dennis Luxen 6453cdf0d6 replace all casserts with Boost.Assert 2013-10-30 18:52:23 +01:00
Dennis Luxen 5f80c33b24 lock update when queries are still running 2013-10-30 17:05:49 +01:00
Dennis Luxen a33542c9b5 link libosrm against librt on linux/gcc 2013-10-30 16:35:23 +01:00
Dennis Luxen 3a1d98648f link tool against librt on linux/gcc 2013-10-30 16:33:16 +01:00
Dennis Luxen 4ec79d61d0 Merge branch 'shared_memory' into develop 2013-10-30 15:10:07 +01:00
Dennis Luxen b4f055f80c fix check for shared or internal memory 2013-10-30 14:17:32 +01:00
Dennis Luxen 6bf35c679f add timestamp to management data structure 2013-10-30 14:15:55 +01:00
Dennis Luxen 3349d43c00 output build ID to tools 2013-10-30 13:04:22 +01:00
Dennis Luxen ced961d24c delete renamed file 2013-10-30 13:03:38 +01:00
Dennis Luxen 419f708d87 build unlock tool and link against git descriptor 2013-10-30 13:01:49 +01:00
Dennis Luxen bbc1c04042 rename tool 2013-10-30 11:52:40 +01:00
Dennis Luxen 7a6865637d release all locks 2013-10-30 11:51:20 +01:00
Dennis Luxen ae96420925 output file paths only if internal memory is used 2013-10-30 11:47:48 +01:00
Dennis Luxen 2822812d0d dont require local file parameter for shared memory input 2013-10-30 11:45:06 +01:00
Dennis Luxen c8ab430491 less verbose output 2013-10-30 11:42:05 +01:00
Dennis Luxen bb87f28e80 remove debug output 2013-10-30 11:41:06 +01:00
Dennis Luxen 6db671215a warn if shared memory segment could not be allocated properly 2013-10-29 18:52:13 +01:00
Dennis Luxen 64566ec6cf fix pesky resource leak that took me two f*#+ing days to figure out. No thanks to you, valgrind 2013-10-29 18:45:01 +01:00
Dennis Luxen faaf97ef62 return if removal of shmem segment was successful 2013-10-29 18:43:11 +01:00
Dennis Luxen 67d6efed21 make release build less verbose 2013-10-28 15:17:03 +01:00
Dennis Luxen 571d9bd610 print info on shared data only on reload 2013-10-28 15:11:53 +01:00
Dennis Luxen 4144698540 make data store less verbose in release mode 2013-10-28 14:56:25 +01:00
Dennis Luxen 9bf6bf2c78 link against on linux/gcc 2013-10-28 14:51:20 +01:00
Dennis Luxen cc9236b8db move lock outside of try/catch 2013-10-28 14:39:55 +01:00
Dennis Luxen 0103b59e61 close previously allocated filestream 2013-10-28 14:21:31 +01:00
Dennis Luxen e9f6531db7 remove comma at end of enum 2013-10-28 10:54:15 +01:00
Dennis Luxen 62c2c750ea load correct segment, remove some debug output 2013-10-25 22:26:27 +02:00
Dennis Luxen 3e5e3175e0 check for new data with every query 2013-10-25 19:32:06 +02:00
Dennis Luxen 54c5af30d9 refetch data if changed 2013-10-25 19:31:39 +02:00
Dennis Luxen ca4a3361c0 load data into other data store 2013-10-25 19:31:21 +02:00
Dennis Luxen 47d302221d add ram index file name to layout, rename data types 2013-10-25 17:45:03 +02:00
Dennis Luxen ed215657e6 remove deprecatedd swap method 2013-10-25 17:43:01 +02:00
Dennis Luxen 3e63b14192 add ability to _not_ destroy prev allocated memory 2013-10-25 14:00:34 +02:00
Dennis Luxen 86433ab3a8 fix indentation 2013-10-25 11:19:02 +02:00
Dennis Luxen 7214800d93 add marker where current shared data resides 2013-10-25 11:16:18 +02:00
Dennis Luxen 29f298fa4a load into seperate area, mark swap as todo 2013-10-23 20:06:00 +02:00
Dennis Luxen ef35bc77cb add simple lock barrier tool to block the flow of queries 2013-10-23 13:31:05 +02:00
Dennis Luxen 6ae880f61e finished locking implementation in queries. YAY\! 2013-10-23 13:22:59 +02:00
Dennis Luxen 0d1149310c implement shared lock in query 2013-10-22 19:06:47 +02:00
Dennis Luxen 51d32bb8d3 set todo marker 2013-10-22 19:06:23 +02:00
Dennis Luxen 49a8980dea use named mtx's and condition for interprocess communication 2013-10-22 13:26:39 +02:00
Dennis Luxen 9fe1680c56 remove superflous include 2013-10-21 19:08:23 +02:00
Dennis Luxen b7db65a023 rename condidition variable and add mutex for pending update 2013-10-21 19:07:49 +02:00
Dennis Luxen 4c02002265 iron out skeleton for implementation of shared sync 2013-10-21 19:06:58 +02:00
Dennis Luxen d0198649f2 use doubles in mercartor projection functions 2013-10-21 17:13:02 +02:00
Dennis Luxen 32c1fd082d fix build for tools 2013-10-21 12:01:19 +02:00
Dennis Luxen 363bf42b95 reinstate previous regex 2013-10-21 12:00:52 +02:00
Dennis Luxen a1ab2232f3 use iterator based regex replace 2013-10-21 11:46:17 +02:00
Dennis Luxen cf69f43166 add proper licence header to newly added files 2013-10-21 11:45:16 +02:00
Dennis Luxen 9833438733 add better comment 2013-10-18 21:58:07 +02:00
Emil Tin 67c5e3966a fix some indentation and spelling 2013-10-18 18:33:56 +02:00
Emil Tin aa0927911d example showing use of PostGIS data 2013-10-18 18:24:13 +02:00
Emil Tin 13c9e1ed58 allowing read-only access to osm way/node id from lua 2013-10-18 12:31:08 +02:00
Dennis Luxen 19a457ab7d implement update barrier 2013-10-17 18:11:53 +02:00
Dennis Luxen 0926bff0cc fix issue #761 2013-10-16 17:38:09 +02:00
Dennis Luxen 53a0bc963a indicate the type of memory to the user 2013-10-16 13:40:40 +02:00
Dennis Luxen a2819d822a load data from server.ini only iff no parameters are give 2013-10-16 13:27:44 +02:00
Dennis Luxen 175112d97d fix status messages during configure 2013-10-16 11:58:29 +02:00
Dennis Luxen dced47024f replace FLT_EPSILON with proper C++ variant 2013-10-15 18:42:25 +02:00
Dennis Luxen ffc361406e move git descriptor into a static library that is linked against all tools 2013-10-15 18:28:14 +02:00
Dennis Luxen 852c648235 use program options in data store tool 2013-10-15 18:24:49 +02:00
Dennis Luxen 1197b96c49 add shared memory option to command line parameters 2013-10-15 17:06:45 +02:00
Dennis Luxen f21fe81e16 remove superflous include guard 2013-10-15 17:06:22 +02:00
Dennis Luxen 593dfd0108 Merging and rebasing of develop into shared_memory
Conflicts:
	DataStructures/SearchEngine.h
	DataStructures/StaticRTree.h
	Descriptors/DescriptionFactory.cpp
	Library/OSRM.cpp
	Library/OSRM.h
	RoutingAlgorithms/BasicRoutingInterface.h
	RoutingAlgorithms/ShortestPathRouting.h
	Server/DataStructures/BaseDataFacade.h
	Server/DataStructures/InternalDataFacade.h
	Server/DataStructures/QueryObjectsStorage.cpp
	Server/DataStructures/SharedDataFacade.h
	routed.cpp
2013-10-15 17:04:53 +02:00
Dennis Luxen aaf0fb9d12 Rework facades to accept ServerPaths object as configuration 2013-10-15 15:44:40 +02:00
Dennis Luxen 02e9f8aef3 Rework facades to accept ServerPaths object as configuration 2013-10-15 15:44:35 +02:00
Dennis Luxen 424055c04e fix iterator concept implementation 2013-10-15 14:35:36 +02:00
Dennis Luxen 02daf17326 fix iterator concept implementation 2013-10-15 14:35:36 +02:00
Dennis Luxen a666f0d52e change EdgeBasedNode namespace 2013-10-15 14:35:36 +02:00
DennisOSRM 27a760c58c Move edge-based node out ouf surrounding class 2013-10-15 14:35:36 +02:00
Dennis Luxen 0ba12f48c6 state type of template class member function explicitly 2013-10-15 14:35:35 +02:00
Dennis Luxen eaaf54d886 make C++11 default on OS X 2013-10-15 14:35:35 +02:00
Dennis Luxen 4b3d634fe9 always compile with C++11 on OS X (Linux to follow) 2013-10-15 14:35:35 +02:00
Dennis Luxen f77a699ea4 remove problematic luabind code 2013-10-15 14:35:35 +02:00
Dennis Luxen e989e38cc2 further compile fixes for clang 3.3 (OS X 10.9) 2013-10-15 14:35:35 +02:00
Dennis Luxen 6a900ed6e7 remove unneeded member 2013-10-15 14:35:35 +02:00
Dennis Luxen 29e6b85f79 Add explicit shmem id for data loading 2013-10-15 14:35:34 +02:00
Dennis Luxen 2641408d53 fail gracefully when lock file is not present 2013-10-15 14:35:34 +02:00
Dennis Luxen 5b79226183 add static function to remove shared memory 2013-10-15 14:35:34 +02:00
Dennis Luxen 98f9f0cd48 make shmem swappable by ref and ptr 2013-10-15 14:35:34 +02:00
Dennis Luxen cf7e107ad1 check if shmem segment exists 2013-10-15 14:35:34 +02:00
Dennis Luxen ab66c1aa1b mild refactoring of debug outputs 2013-10-15 14:35:34 +02:00
Dennis Luxen 5b03366909 checking if data files actually exist 2013-10-15 14:35:34 +02:00
Dennis Luxen 7824e1446a removing completed todo markers 2013-10-15 14:35:34 +02:00
Dennis Luxen 59cf1a4937 deciding which memory subsystem to use depending on server.ini 2013-10-15 14:35:33 +02:00
Dennis Luxen 252113c838 implementing the fetch of name ids in shared memory 2013-10-15 14:32:45 +02:00
Dennis Luxen e2f84d1acd commenting unneeded variables 2013-10-15 14:32:45 +02:00
Dennis Luxen 204dcecb28 fixing typo in build configuration 2013-10-15 14:32:44 +02:00
Dennis Luxen 70bbfbea12 fixing include typo 2013-10-15 14:32:44 +02:00
Dennis Luxen 2221a0a908 removing extra ; 2013-10-15 14:32:44 +02:00
Dennis Luxen 203b215093 loading correct file with rtree leafs and not inner nodes 2013-10-15 14:32:44 +02:00
Dennis Luxen 76ee84dae8 printing debug output 2013-10-15 14:32:44 +02:00
Dennis Luxen 79e1c87a01 swapping correct vectors 2013-10-15 14:32:44 +02:00
Dennis Luxen ed208114be properly loading all data into shared memory 2013-10-15 14:32:44 +02:00
Dennis Luxen 7dd711b37c use only one pointer for shared layout 2013-10-15 14:32:44 +02:00
Dennis Luxen 4852802d66 load graph into shared memory 2013-10-15 14:32:44 +02:00
Dennis Luxen c495b1faab graph format now canonical 2013-10-15 14:32:43 +02:00
Dennis Luxen eb5bd8e6ac load timestamp into shared memory 2013-10-15 14:32:43 +02:00
Dennis Luxen ff7dcf9c17 load coordinate list into shared memory 2013-10-15 14:32:43 +02:00
Dennis Luxen 2b12a16c84 load orig edge information 2013-10-15 14:32:43 +02:00
Dennis Luxen 4d00b2ebbb Renaming variables to properly reflect its content 2013-10-15 14:32:43 +02:00
Dennis Luxen 1ba5abbaef add all binaries to ignore list 2013-10-15 14:32:43 +02:00
Dennis Luxen b87a98bbda street name file is now more canonical 2013-10-15 14:32:43 +02:00
Dennis Luxen f76361a345 changing file format for coordinates to be canonical 2013-10-15 14:32:43 +02:00
Dennis Luxen f25bab9555 create lock file if it does not exist 2013-10-15 14:32:42 +02:00
Dennis Luxen ed78b8429f adding proper typedefs s.t. all used types are known 2013-10-15 14:32:42 +02:00
Dennis Luxen 94e9dd8f28 store name id of edges in shmem, too 2013-10-15 14:32:42 +02:00
Dennis Luxen 90215ca0dd move shmem stored sizes to 64 bits 2013-10-15 14:32:42 +02:00
Dennis Luxen 34eb647fcb implementing loading of data into shared memory 2013-10-15 14:32:42 +02:00
Dennis Luxen 83205290de Reordering resource aquisition 2013-10-15 14:32:42 +02:00
Dennis Luxen 02fd528c32 removing debug output 2013-10-15 14:32:42 +02:00
Dennis Luxen e05193f46d osrm-datastore handles manangement of shared memory 2013-10-15 14:32:42 +02:00
Dennis Luxen 14e2d900b5 All tests are passing for internal memory\! 2013-10-15 14:32:41 +02:00
Dennis Luxen ba4290340d removing debug output and calling it a day 2013-10-15 14:32:41 +02:00
Dennis Luxen 5a04700bae create sentinel to adjancency array during preprocessing 2013-10-15 14:32:41 +02:00
Dennis Luxen 999f50dce9 inverting assertion 2013-10-15 14:32:41 +02:00
Dennis Luxen 9522e6e714 properly check for (non-)empty vectors 2013-10-15 14:32:41 +02:00
Dennis Luxen 7836ea4479 implement GetName() for shared memory (copy&paste) 2013-10-15 14:32:40 +02:00
Dennis Luxen 37e8ab8de1 implement operator()+ for shared memory iterator 2013-10-15 14:32:40 +02:00
Dennis Luxen 34048497e7 implement GetName for internal memory 2013-10-15 14:32:40 +02:00
Dennis Luxen 5197422482 fetch ptr from shared memory to via node list 2013-10-15 14:32:40 +02:00
Dennis Luxen d9987c2734 load street names into internal memory 2013-10-15 14:32:40 +02:00
Dennis Luxen c9671b4712 load via node information from shared memory 2013-10-15 14:32:40 +02:00
Dennis Luxen bbf03e3060 Load r-tree search data structure from shared memory 2013-10-15 14:32:40 +02:00
Dennis Luxen e35a78e3cf some further refactoring of variable names and code formatting 2013-10-15 14:32:40 +02:00
Dennis Luxen e318be6a88 call function in parent class 2013-10-15 14:32:40 +02:00
Dennis Luxen 1dab0ebc25 moving common code to parent class 2013-10-15 14:32:40 +02:00
Dennis Luxen 687e58e9d4 removing dead code 2013-10-15 14:32:39 +02:00
Dennis Luxen 993a4aa675 adding auxiliary typedef 2013-10-15 14:32:39 +02:00
Dennis Luxen c991510b0f minor simplification of code 2013-10-15 14:32:39 +02:00
Dennis Luxen c8025bf004 moving fwd decl of static members to root of include graph 2013-10-15 14:31:32 +02:00
Dennis Luxen 9f5767a80c remove superflous includes 2013-10-15 14:31:32 +02:00
Dennis Luxen ffb05d6271 demangling includes 2013-10-15 14:31:32 +02:00
Dennis Luxen 2dd2d3dd7b adjust facade to pass compilation 2013-10-15 14:31:32 +02:00
Dennis Luxen be29c7fca0 call facade where appropriate 2013-10-15 14:31:32 +02:00
Dennis Luxen 2c23a3c0b3 link against proper objects 2013-10-15 14:31:31 +02:00
Dennis Luxen 37e3ead8e9 use flexible shared mem interfaces 2013-10-15 14:31:31 +02:00
Dennis Luxen b018ea7b1b Give all data types in shared memory 2013-10-15 14:31:31 +02:00
Dennis Luxen d6cdca35d4 Use typedef instead of base class 2013-10-15 14:31:31 +02:00
Dennis Luxen a09d150b47 Further stl interface implementation 2013-10-15 14:31:31 +02:00
Dennis Luxen 7cf46afc48 Remove old facade from UUID generation 2013-10-15 14:31:31 +02:00
Dennis Luxen 056c95670f Added list of all data types in shared memory 2013-10-15 14:31:31 +02:00
Dennis Luxen 35dffe43d9 further implementation of the vector interface for shared memory 2013-10-15 14:31:30 +02:00
Dennis Luxen 19c26f0733 removing old data facade, good riddance 2013-10-15 14:31:30 +02:00
Dennis Luxen 388ff10ff5 const'ing new function 2013-10-15 14:31:04 +02:00
Dennis Luxen 8c7be8e45f moving common code into function 2013-10-15 14:31:04 +02:00
Dennis Luxen 579aa67cde further minor refactoring 2013-10-15 14:31:04 +02:00
Dennis Luxen 725f86a0d2 replace cassert by boost asserts 2013-10-15 14:26:27 +02:00
Dennis Luxen 50a6ef18d2 Refactoring shortest path search variable names 2013-10-15 14:24:53 +02:00
Dennis Luxen 1b3e924450 added auxiliary Empty() function 2013-10-15 14:19:54 +02:00
DennisOSRM a33e08e299 superflous typedef changed meaning of name for GCC 2013-10-15 14:19:53 +02:00
DennisOSRM 45dee5a666 Styleguide refactoring 2013-10-15 14:19:53 +02:00
DennisOSRM 642473244e fixing include typos 2013-10-15 14:19:53 +02:00
Dennis Luxen e92f344335 Workarounds for various boost versions and their lovely quirks 2013-10-15 14:19:53 +02:00
Dennis Luxen 7951795ea4 Implementation of internal data storage 2013-10-15 14:19:53 +02:00
Dennis Luxen 101fbcca90 further refactoring of variable names 2013-10-15 14:19:53 +02:00
Dennis Luxen d562132a4a further refactoring of variable names 2013-10-15 14:19:53 +02:00
Dennis Luxen 7152ab39ff further refactoring of variable names 2013-10-15 14:19:52 +02:00
Dennis Luxen 39c5279f5d further refactoring of variable names 2013-10-15 14:19:52 +02:00
Dennis Luxen fef0e16f9c replacing cassert by boost asserts 2013-10-15 14:19:52 +02:00
Dennis Luxen fb1361b00d Reworking data access to go always through facades 2013-10-15 14:19:52 +02:00
Dennis Luxen 64c75c8b57 Refactoring base descriptor class 2013-10-15 14:19:52 +02:00
Dennis Luxen f4e015a255 renamed utility class 2013-10-15 14:19:52 +02:00
Dennis Luxen 242b68c488 initial refactoring of variable names 2013-10-15 14:19:52 +02:00
Dennis Luxen 9452c7e0c7 further implementation of data facades 2013-10-15 14:19:52 +02:00
Dennis Luxen ab1d3d1ced Properly instantiate plugins 2013-10-15 14:17:44 +02:00
Dennis Luxen 41df92bb93 Use new data facade in all descriptors 2013-10-15 14:17:44 +02:00
Dennis Luxen 427db3f29a Don't build deleted classes 2013-10-15 14:14:54 +02:00
Dennis Luxen b5600bdd7f Rewiring routing algorithms 2013-10-15 14:14:54 +02:00
Dennis Luxen a2153b668a Rewiring query plugins 2013-10-15 14:14:54 +02:00
Dennis Luxen 7d52c82c3b Moving DataStructures to new data facade pattern 2013-10-15 14:14:54 +02:00
Dennis Luxen 092f1a4959 corrected include fence 2013-10-15 14:14:11 +02:00
Dennis Luxen 21bee7e40c Further includes in Facades 2013-10-15 14:14:10 +02:00
Dennis Luxen a9ac0ac725 Mockups for data facades 2013-10-15 14:12:30 +02:00
Dennis Luxen 5dc1ed6696 plugging in base facade ptr 2013-10-15 14:09:40 +02:00
Dennis Luxen b55f66e69c added graph data access 2013-10-15 14:08:49 +02:00
Dennis Luxen ab637e22b1 instantiate different inherited class at bcp that provides all data 2013-10-15 14:06:48 +02:00
Dennis Luxen fa665c5494 Facade base class to provide all data access 2013-10-15 14:05:42 +02:00
Dennis Luxen e91b75a1bb use empty() instead of comparisons 2013-10-15 14:04:12 +02:00
Dennis Luxen 4c6f85fd25 Further includes in Facades 2013-10-15 14:04:12 +02:00
Dennis Luxen f09e9b7790 make plugins templates that plug into data facade 2013-10-15 14:04:12 +02:00
Dennis Luxen b51d3da7e5 Mockups for data facades 2013-10-15 14:04:11 +02:00
Dennis Luxen 861dbd5977 plugging in base facade ptr 2013-10-15 14:02:31 +02:00
Dennis Luxen 5001fcdd53 added graph data access 2013-10-15 14:02:31 +02:00
Dennis Luxen eeb47dc724 remove unneeded white spaces 2013-10-15 14:02:31 +02:00
Dennis Luxen 5556dff11e instantiate different inherited class at bcp that provides all data 2013-10-15 14:00:50 +02:00
Dennis Luxen 18b57fa6aa Facade base class to provide all data access 2013-10-15 13:45:45 +02:00
Dennis Luxen 12bb4d75fd Adding shared memory data types 2013-10-15 13:45:45 +02:00
Dennis Luxen 411d8d4d98 fix iterator concept implementation 2013-10-15 12:00:20 +02:00
Dennis Luxen 748df0b21a fix iterator concept implementation 2013-10-15 11:56:27 +02:00
Dennis Luxen 8d98316a89 change EdgeBasedNode namespace 2013-10-15 11:52:41 +02:00
Dennis Luxen c6b45a8e09 .. 2013-10-14 17:22:10 +02:00
Dennis Luxen d42920674a compile with -std=c++11 on os x 10.9 2013-10-14 17:21:40 +02:00
Dennis Luxen c66fced161 rename createhierarchy.cpp to more canonical name 2013-10-14 17:03:46 +02:00
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
216 changed files with 13981 additions and 7180 deletions
+54
View File
@@ -0,0 +1,54 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: true
AlwaysBreakTemplateDeclarations: false
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: false
ColumnLimit: 100
ConstructorInitializerAllOnOneLineOrOnePerLine: false
DerivePointerBinding: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: true
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000
PenaltyReturnTypeOnItsOwnLine: 60
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
Standard: Cpp11
IndentWidth: 4
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Allman
IndentFunctionDeclarationAfterType: false
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
...
+4
View File
@@ -72,8 +72,12 @@ stxxl.errlog
/win/bin/ /win/bin/
/win/bin-debug/ /win/bin-debug/
/osrm-extract /osrm-extract
/osrm-io-benchmark
/osrm-components
/osrm-routed /osrm-routed
/osrm-datastore
/osrm-prepare /osrm-prepare
/osrm-unlock-all
/osrm-cli /osrm-cli
/nohup.out /nohup.out
+16 -6
View File
@@ -2,26 +2,35 @@ language: cpp
compiler: compiler:
- gcc - gcc
# - clang # - clang
# Make sure CMake is installed
install: install:
- sudo apt-get update >/dev/null - 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 - sudo apt-get -q install libprotoc-dev libprotobuf7 libprotobuf-dev libosmpbf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev libboost1.46-all-dev lua5.1 liblua5.1-0-dev libluabind-dev rubygems
- curl -s https://gist.githubusercontent.com/DennisOSRM/803a64a9178ec375069f/raw/ | sudo bash
before_script: before_script:
- sudo gem install bundler - rvm use 1.9.3
- gem install bundler
- bundle install - bundle install
- mkdir build - mkdir build
- cd build - cd build
- cmake .. $CMAKEOPTIONS - cmake .. $CMAKEOPTIONS
script: make script:
after_script: - make -j 2
- cd .. - cd ..
- cucumber -p verify - cucumber -p verify
after_script:
# - cd ..
# - cucumber -p verify
branches: branches:
only: only:
- master - master
- develop - develop
cache:
- bundler
- apt
env: env:
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release" - CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release" OSRM_PORT=5000 OSRM_TIMEOUT=60
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug" - CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug" OSRM_PORT=5010 OSRM_TIMEOUT=60
notifications: notifications:
irc: irc:
channels: channels:
@@ -30,6 +39,7 @@ notifications:
on_failure: always on_failure: always
use_notice: true use_notice: true
skip_join: false skip_join: false
recipients: recipients:
- dennis@mapbox.com - dennis@mapbox.com
email: 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;
}
+198
View File
@@ -0,0 +1,198 @@
/*
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"
#include "../DataStructures/SegmentInformation.h"
#include "../Util/MercatorUtil.h"
#include <limits>
//These thresholds are more or less heuristically chosen.
static double DouglasPeuckerThresholds[19] = {
262144., //z0
131072., //z1
65536., //z2
32768., //z3
16384., //z4
8192., //z5
4096., //z6
2048., //z7
960., //z8
480., //z9
240., //z10
90., //z11
50., //z12
25., //z13
15., //z14
5., //z15
.65, //z16
.5, //z17
.35 //z18
};
/**
* Yuck! Code duplication. This function is also in EgdeBasedNode.h
*/
double DouglasPeucker::ComputeDistance(
const FixedPointCoordinate& point,
const FixedPointCoordinate& segA,
const FixedPointCoordinate& segB
) const {
const double x = lat2y(point.lat/COORDINATE_PRECISION);
const double y = point.lon/COORDINATE_PRECISION;
const double a = lat2y(segA.lat/COORDINATE_PRECISION);
const double b = segA.lon/COORDINATE_PRECISION;
const double c = lat2y(segB.lat/COORDINATE_PRECISION);
const double d = segB.lon/COORDINATE_PRECISION;
double p,q,nY;
if( std::abs(a-c) > std::numeric_limits<double>::epsilon() ){
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m);
q = b + m*(p - a);
} else {
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
//discretize the result to coordinate precision. it's a hack!
if( std::abs(nY) < (1./COORDINATE_PRECISION) ) {
nY = 0.;
}
double r = (p - nY*a)/c;
if( std::isnan(r) ) {
r = ((segB.lat == point.lat) && (segB.lon == point.lon)) ? 1. : 0.;
} else if( std::abs(r) <= std::numeric_limits<double>::epsilon() ) {
r = 0.;
} else if( std::abs(r-1.) <= std::numeric_limits<double>::epsilon() ) {
r = 1.;
}
FixedPointCoordinate nearest_location;
BOOST_ASSERT( !std::isnan(r) );
if( r <= 0. ){
nearest_location.lat = segA.lat;
nearest_location.lon = segA.lon;
} else if( r >= 1. ){
nearest_location.lat = segB.lat;
nearest_location.lon = segB.lon;
} else { // point lies in between
nearest_location.lat = y2lat(p)*COORDINATE_PRECISION;
nearest_location.lon = q*COORDINATE_PRECISION;
}
BOOST_ASSERT( nearest_location.isValid() );
const double approximated_distance = FixedPointCoordinate::ApproximateEuclideanDistance(
point,
nearest_location
);
BOOST_ASSERT( 0. <= approximated_distance );
return approximated_distance;
}
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 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"
);
double max_distance = std::numeric_limits<double>::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 = ComputeDistance(
input_geometry[i].location,
input_geometry[pair.first].location,
input_geometry[pair.second].location
);
const double distance = std::abs(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)
);
}
}
}
}
+19 -117
View File
@@ -28,9 +28,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef DOUGLASPEUCKER_H_ #ifndef DOUGLASPEUCKER_H_
#define DOUGLASPEUCKER_H_ #define DOUGLASPEUCKER_H_
#include "../DataStructures/Coordinate.h" #include "../Util/SimpleLogger.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <cmath> #include <cmath>
@@ -38,133 +41,32 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stack> #include <stack>
#include <vector> #include <vector>
/*This class object computes the bitvector of indicating generalized input points /* This class object computes the bitvector of indicating generalized input
* according to the (Ramer-)Douglas-Peucker algorithm. * points according to the (Ramer-)Douglas-Peucker algorithm.
* *
* Input is vector of pairs. Each pair consists of the point information and a bit * Input is vector of pairs. Each pair consists of the point information and a
* indicating if the points is present in the generalization. * bit indicating if the points is present in the generalization.
* Note: points may also be pre-selected*/ * Note: points may also be pre-selected*/
//These thresholds are more or less heuristically chosen. struct SegmentInformation;
// 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 { class DouglasPeucker {
private: private:
typedef std::pair<std::size_t, std::size_t> PairOfPoints; typedef std::pair<std::size_t, std::size_t> PairOfPoints;
//Stack to simulate the recursion //Stack to simulate the recursion
std::stack<PairOfPoints > recursion_stack; std::stack<PairOfPoints> recursion_stack;
/**
* 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;
}
double ComputeDistance(
const FixedPointCoordinate& point,
const FixedPointCoordinate& segA,
const FixedPointCoordinate& segB
) const;
public: public:
void Run(std::vector<PointT> & input_geometry, const unsigned zoom_level) { void Run(
{ std::vector<SegmentInformation> & input_geometry,
BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level"); const unsigned 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)
);
}
}
}
}
}; };
#endif /* DOUGLASPEUCKER_H_ */ #endif /* DOUGLASPEUCKER_H_ */
+66 -35
View File
@@ -25,32 +25,55 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef ITERATORBASEDCRC32_H_ #ifndef ITERATOR_BASED_CRC32_H
#define ITERATORBASEDCRC32_H_ #define ITERATOR_BASED_CRC32_H
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream> #include <iostream>
#if defined(__x86_64__)
#include <cpuid.h>
#else
#include <boost/crc.hpp> // for boost::crc_32_type
inline void __get_cpuid(
int param,
unsigned *eax,
unsigned *ebx,
unsigned *ecx,
unsigned *edx
) { *ecx = 0; }
#endif
template<class ContainerT> template<class ContainerT>
class IteratorbasedCRC32 { class IteratorbasedCRC32 {
private: private:
typedef typename ContainerT::iterator ContainerT_iterator; typedef typename ContainerT::iterator IteratorType;
unsigned crc; unsigned crc;
typedef boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> my_crc_32_type; bool use_SSE42_CRC_function;
typedef unsigned (IteratorbasedCRC32::*CRC32CFunctionPtr)(char *str, unsigned len, unsigned crc);
unsigned SoftwareBasedCRC32(char *str, unsigned len, unsigned ){ #if !defined(__x86_64__)
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_Processor; boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_processor;
CRC32_Processor.process_bytes( str, len); #endif
return CRC32_Processor.checksum(); unsigned SoftwareBasedCRC32( char *str, unsigned len )
{
#if !defined(__x86_64__)
CRC32_processor.process_bytes( str, len);
return CRC32_processor.checksum();
#else
return 0;
#endif
} }
unsigned SSEBasedCRC32( char *str, unsigned len, unsigned crc){
unsigned q=len/sizeof(unsigned), // adapted from http://byteworm.com/2010/10/13/crc32/
r=len%sizeof(unsigned), unsigned SSE42BasedCRC32( char *str, unsigned len )
*p=(unsigned*)str/*, crc*/; {
#if defined(__x86_64__)
unsigned q = len/sizeof(unsigned);
unsigned r = len%sizeof(unsigned);
unsigned *p = (unsigned*)str;
//crc=0; //crc=0;
while (q--) { while (q--) {
@@ -71,47 +94,55 @@ private:
); );
++str; ++str;
} }
#endif
return crc; return crc;
} }
unsigned cpuid(unsigned functionInput){ inline unsigned cpuid() const
unsigned eax; {
unsigned ebx; unsigned eax = 0, ebx = 0, ecx = 0, edx = 0;
unsigned ecx; // on X64 this calls hardware cpuid(.) instr. otherwise a dummy impl.
unsigned edx; __get_cpuid( 1, &eax, &ebx, &ecx, &edx );
asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (functionInput));
return ecx; return ecx;
} }
CRC32CFunctionPtr detectBestCRC32C(){ bool DetectNativeCRC32Support()
static const int SSE42_BIT = 20; {
unsigned ecx = cpuid(1); static const int SSE42_BIT = 0x00100000;
bool hasSSE42 = ecx & (1 << SSE42_BIT); const unsigned ecx = cpuid();
if (hasSSE42) { const bool has_SSE42 = ecx & SSE42_BIT;
if (has_SSE42) {
SimpleLogger().Write() << "using hardware based CRC32 computation"; SimpleLogger().Write() << "using hardware based CRC32 computation";
return &IteratorbasedCRC32::SSEBasedCRC32; //crc32 hardware accelarated;
} else { } else {
SimpleLogger().Write() << "using software based CRC32 computation"; SimpleLogger().Write() << "using software based CRC32 computation";
return &IteratorbasedCRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
} }
return has_SSE42;
} }
CRC32CFunctionPtr crcFunction;
public: public:
IteratorbasedCRC32(): crc(0) { IteratorbasedCRC32() : crc(0)
crcFunction = detectBestCRC32C(); {
use_SSE42_CRC_function = DetectNativeCRC32Support();
} }
virtual ~IteratorbasedCRC32() { } unsigned operator()( IteratorType iter, const IteratorType end )
{
unsigned operator()( ContainerT_iterator iter, const ContainerT_iterator end) {
unsigned crc = 0; unsigned crc = 0;
while(iter != end) { while(iter != end) {
char * data = reinterpret_cast<char*>(&(*iter) ); char * data = reinterpret_cast<char*>(&(*iter) );
crc =((*this).*(crcFunction))(data, sizeof(typename ContainerT::value_type*), crc);
if (use_SSE42_CRC_function)
{
crc = SSE42BasedCRC32( data, sizeof(typename ContainerT::value_type) );
}
else
{
crc = SoftwareBasedCRC32( data, sizeof(typename ContainerT::value_type) );
}
++iter; ++iter;
} }
return crc; return crc;
} }
}; };
#endif /* ITERATORBASEDCRC32_H_ */ #endif /* ITERATOR_BASED_CRC32_H */
+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++) {
FixedPointCoordinate::convertInternalLatLonToString(polyline[i].lat, tmp);
output += "[";
output += tmp;
FixedPointCoordinate::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;
}
FixedPointCoordinate::convertInternalLatLonToString(polyline[i].location.lat, tmp);
output += "[";
output += tmp;
FixedPointCoordinate::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 "../Util/StringUtil.h"
#include <string> #include <string>
#include <vector>
class PolylineCompressor { class PolylineCompressor {
private: private:
inline void encodeVectorSignedNumber(std::vector<int> & numbers, std::string & output) const { void encodeVectorSignedNumber(
for(unsigned i = 0; i < numbers.size(); ++i) { std::vector<int> & numbers,
numbers[i] <<= 1; std::string & output
if (numbers[i] < 0) { ) const;
numbers[i] = ~(numbers[i]);
}
}
for(unsigned i = 0; i < numbers.size(); ++i) {
encodeNumber(numbers[i], output);
}
}
inline void encodeNumber(int numberToEncode, std::string & output) const { void encodeNumber(int number_to_encode, 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));
}
public: public:
inline void printEncodedString( void printEncodedString(
const std::vector<SegmentInformation> & polyline, const std::vector<SegmentInformation> & polyline,
std::string & output std::string & output
) const { ) 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 printEncodedString(
const std::vector<FixedPointCoordinate>& polyline,
std::string &output
) const;
inline void printEncodedString(const std::vector<FixedPointCoordinate>& polyline, std::string &output) const { void printUnencodedString(
std::vector<int> deltaNumbers(2*polyline.size()); const std::vector<FixedPointCoordinate> & polyline,
output += "\""; std::string & output
if(!polyline.empty()) { ) const;
deltaNumbers[0] = polyline[0].lat;
deltaNumbers[1] = polyline[0].lon;
for(unsigned i = 1; i < polyline.size(); ++i) {
deltaNumbers[(2*i)] = (polyline[i].lat - polyline[i-1].lat);
deltaNumbers[(2*i)+1] = (polyline[i].lon - polyline[i-1].lon);
}
encodeVectorSignedNumber(deltaNumbers, output);
}
output += "\"";
}
inline void printUnencodedString(std::vector<FixedPointCoordinate> & polyline, std::string & output) const { void printUnencodedString(
output += "["; const std::vector<SegmentInformation> & polyline,
std::string tmp; std::string & output
for(unsigned i = 0; i < polyline.size(); i++) { ) const;
convertInternalLatLonToString(polyline[i].lat, tmp);
output += "[";
output += tmp;
convertInternalLatLonToString(polyline[i].lon, tmp);
output += ", ";
output += tmp;
output += "]";
if( i < polyline.size()-1 ) {
output += ",";
}
}
output += "]";
}
inline void printUnencodedString(std::vector<SegmentInformation> & polyline, std::string & output) const {
output += "[";
std::string tmp;
for(unsigned i = 0; i < polyline.size(); i++) {
if(!polyline[i].necessary)
continue;
convertInternalLatLonToString(polyline[i].location.lat, tmp);
output += "[";
output += tmp;
convertInternalLatLonToString(polyline[i].location.lon, tmp);
output += ", ";
output += tmp;
output += "]";
if( i < polyline.size()-1 ) {
output += ",";
}
}
output += "]";
}
}; };
#endif /* POLYLINECOMPRESSOR_H_ */ #endif /* POLYLINECOMPRESSOR_H_ */
+6 -4
View File
@@ -28,7 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef STRONGLYCONNECTEDCOMPONENTS_H_ #ifndef STRONGLYCONNECTEDCOMPONENTS_H_
#define STRONGLYCONNECTEDCOMPONENTS_H_ #define STRONGLYCONNECTEDCOMPONENTS_H_
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/DeallocatingVector.h" #include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h" #include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/ImportEdge.h" #include "../DataStructures/ImportEdge.h"
@@ -39,6 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@@ -95,7 +96,7 @@ private:
typedef std::pair<NodeID, NodeID> RestrictionSource; typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> restriction_target; typedef std::pair<NodeID, bool> restriction_target;
typedef std::vector<restriction_target> EmanatingRestrictionsVector; typedef std::vector<restriction_target> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap; typedef boost::unordered_map<RestrictionSource, unsigned> RestrictionMap;
std::vector<NodeInfo> m_coordinate_list; std::vector<NodeInfo> m_coordinate_list;
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list; std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
@@ -144,7 +145,7 @@ public:
if(restriction_iterator == m_restriction_map.end()) { if(restriction_iterator == m_restriction_map.end()) {
index = m_restriction_bucket_list.size(); index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index+1); m_restriction_bucket_list.resize(index+1);
m_restriction_map[restrictionSource] = index; m_restriction_map.insert(std::make_pair(restrictionSource, index));
} else { } else {
index = restriction_iterator->second; index = restriction_iterator->second;
//Map already contains an is_only_*-restriction //Map already contains an is_only_*-restriction
@@ -357,6 +358,7 @@ public:
"identified: " << component_size_vector.size() << "identified: " << component_size_vector.size() <<
" many components, marking small components"; " many components, marking small components";
// TODO/C++11: prime candidate for lambda function
unsigned size_one_counter = 0; unsigned size_one_counter = 0;
for(unsigned i = 0, end = component_size_vector.size(); i < end; ++i){ for(unsigned i = 0, end = component_size_vector.size(); i < end; ++i){
if(1 == component_size_vector[i]) { if(1 == component_size_vector[i]) {
@@ -385,7 +387,7 @@ public:
} }
const TarjanDynamicGraph::NodeIterator v = m_node_based_graph->GetTarget(e1); const TarjanDynamicGraph::NodeIterator v = m_node_based_graph->GetTarget(e1);
total_network_distance += 100*ApproximateDistance( total_network_distance += 100*FixedPointCoordinate::ApproximateDistance(
m_coordinate_list[u].lat, m_coordinate_list[u].lat,
m_coordinate_list[u].lon, m_coordinate_list[u].lon,
m_coordinate_list[v].lat, m_coordinate_list[v].lat,
+212 -111
View File
@@ -1,168 +1,269 @@
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(OSRM) project(OSRM)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CheckCXXCompilerFlag)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
set(HUGO "${CMAKE_CURRENT_SOURCE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
git_describe(GIT_DESCRIPTION) git_describe(GIT_DESCRIPTION)
TRY_RUN(SHARED_LIBRARY_PATH_TYPE SHARED_LIBRARY_PATH_INFO_COMPILED ${PROJECT_BINARY_DIR}/CMakeTmp ${PROJECT_SOURCE_DIR}/cmake/size.cpp OUTPUT_VARIABLE IS_64_SYSTEM)
if(IS_64_SYSTEM)
message(STATUS "System supports 64 bits.")
set( HAS64BITS 1 )
else(IS_64_SYSTEM)
MESSAGE(WARNING "Compiling on a 32 bit system is unsupported!")
set( HAS64BITS 0 )
endif(IS_64_SYSTEM)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
set(bitness 32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(bitness 64)
message(STATUS "Building on a 64 bit system")
else()
message(WARNING "Building on a 32 bit system is unsupported")
endif()
include_directories(${CMAKE_SOURCE_DIR}/Include/)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UUID-Config.cmake -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UUID-Config.cmake
DEPENDS DEPENDS
${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in ${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake ${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
COMMENT "Configuring UUID.cpp" COMMENT "Configuring UUID.cpp"
VERBATIM) VERBATIM)
add_custom_target(UUIDConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/UUID.cpp ) add_custom_target(UUIDConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/UUID.cpp)
set(BOOST_COMPONENTS filesystem program_options regex system thread) set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread)
configure_file(Util/GitDescription.cpp.in ${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp) configure_file(
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp
)
file(GLOB ExtractorGlob Extractor/*.cpp) file(GLOB ExtractorGlob Extractor/*.cpp)
set(ExtractorSources extractor.cpp ${ExtractorGlob} Util/GitDescription.cpp) set(ExtractorSources extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources} ) add_executable(osrm-extract ${ExtractorSources})
file(GLOB PrepareGlob Contractor/*.cpp) file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp)
set(PrepareSources createHierarchy.cpp ${PrepareGlob} Util/GitDescription.cpp) set(PrepareSources prepare.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources} ) 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 ServerGlob Server/*.cpp)
file(GLOB DescriptorGlob Descriptors/*.cpp) file(GLOB DescriptorGlob Descriptors/*.cpp)
file(GLOB DatastructureGlob DataStructures/SearchEngineData.cpp)
file(GLOB CoordinateGlob DataStructures/Coordinate.cpp)
file(GLOB AlgorithmGlob Algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp) file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB SearchEngineSource DataStructures/SearchEngine*.cpp)
file(GLOB ServerStructureGlob Server/DataStructures/*.cpp)
set(OSRMSources ${LibOSRMGlob} ${DescriptorGlob} ${SearchEngineSource} ${ServerStructureGlob}) set(
add_library(OSRM SHARED ${OSRMSources}) OSRMSources
${LibOSRMGlob}
${DescriptorGlob}
${DatastructureGlob}
${CoordinateGlob}
${AlgorithmGlob}
${HttpGlob}
)
add_library(COORDLIB STATIC ${CoordinateGlob})
add_library(OSRM ${OSRMSources} Util/GitDescription.cpp Util/UUID.cpp)
add_library(UUID STATIC Util/UUID.cpp) add_library(UUID STATIC Util/UUID.cpp)
add_dependencies( UUID UUIDConfigure ) 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 # Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug) if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif(NOT CMAKE_BUILD_TYPE MATCHES Debug) endif()
if(CMAKE_BUILD_TYPE MATCHES Debug) if(CMAKE_BUILD_TYPE MATCHES Debug)
message(STATUS "Configuring OSRM in debug mode") message(STATUS "Configuring OSRM in debug mode")
endif(CMAKE_BUILD_TYPE MATCHES Debug) if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
message(STATUS "adding profiling flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
set(CMAKE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
endif()
endif()
if(CMAKE_BUILD_TYPE MATCHES Release) if(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "Configuring OSRM in release mode") message(STATUS "Configuring OSRM in release mode")
endif(CMAKE_BUILD_TYPE MATCHES Release)
#Configuring compilers
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
set(CMAKE_CXX_FLAGS "-Wall -Wno-unknown-pragmas -Wno-unneeded-internal-declaration")
message(STATUS "OpenMP parallelization not available using clang++")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
set(CMAKE_CXX_FLAGS "-Wall -fopenmp -pedantic")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++
set(CMAKE_CXX_FLAGS "-static-intel -wd10237 -Wall -openmp -ipo")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# using Visual Studio C++
endif() endif()
# Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -Wno-unknown-pragmas -Wno-unneeded-internal-declaration -pedantic -fPIC")
message(STATUS "OpenMP parallelization not available using clang++")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fopenmp -pedantic -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -openmp -ipo -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# using Visual Studio C++
endif()
# Check if LTO is available
set(LTO_FLAGS "")
CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
if (HAS_LTO_FLAG)
set(LTO_FLAGS "${LTO_FLAGS} -flto")
endif (HAS_LTO_FLAG)
# disable partitioning of LTO process when possible (fixes Debian issues)
set(LTO_PARTITION_FLAGS "")
CHECK_CXX_COMPILER_FLAG("-flto-partition=none" HAS_LTO_PARTITION_FLAG)
if (HAS_LTO_PARTITION_FLAG)
set(LTO_PARTITION_FLAGS "${LTO_PARTITION_FLAGS} -flto-partition=none")
endif (HAS_LTO_PARTITION_FLAG)
# Add Link-Time-Optimization flags, if supported (GCC >= 4.5) and enabled
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LTO_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LTO_FLAGS} ${LTO_PARTITION_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LTO_FLAGS} ${LTO_PARTITION_FLAGS}")
# Configuring other platform dependencies
if(APPLE) if(APPLE)
SET(CMAKE_OSX_ARCHITECTURES "x86_64") 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 AND NOT OSXLIBSTD)
message(STATUS "Activating -std=c++11 flag for >= OS X 10.9")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
if(OSXLIBSTD)
message(STATUS "linking against ${OSXLIBSTD}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=${OSXLIBSTD}")
elseif(DARWIN_VERSION GREATER 12)
message(STATUS "linking against libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
endif()
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-datastore rt)
target_link_libraries(OSRM rt)
endif() endif()
#Check Boost #Check Boost
set(BOOST_MIN_VERSION "1.44.0") set(BOOST_MIN_VERSION "1.46.0")
find_package( Boost ${BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED ) find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
if (NOT Boost_FOUND) if(NOT Boost_FOUND)
message(FATAL_ERROR "Fatal error: Boost (version >= 1.44.0) required.\n") message(FATAL_ERROR "Fatal error: Boost (version >= 1.46.0) required.\n")
endif (NOT Boost_FOUND) endif()
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
IF( APPLE ) target_link_libraries(OSRM ${Boost_LIBRARIES} COORDLIB)
target_link_libraries( OSRM ${Boost_LIBRARIES} UUID ) target_link_libraries(osrm-extract ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
ELSE( APPLE ) target_link_libraries(osrm-prepare ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
target_link_libraries( OSRM ${Boost_LIBRARIES} ) target_link_libraries(osrm-routed ${Boost_LIBRARIES} OSRM UUID GITDESCRIPTION)
ENDIF( APPLE ) target_link_libraries(osrm-datastore ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
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 )
find_package ( BZip2 REQUIRED ) find_package(Threads REQUIRED)
include_directories(${BZIP_INCLUDE_DIRS}) target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries (osrm-extract ${BZIP2_LIBRARIES})
find_package( ZLIB REQUIRED ) find_package(Lua52)
include_directories(${ZLIB_INCLUDE_DIRS}) if(NOT LUA52_FOUND)
target_link_libraries (osrm-extract ${ZLIB_LIBRARY}) find_package(Lua51 REQUIRED)
target_link_libraries (osrm-routed ${ZLIB_LIBRARY}) if(NOT APPLE)
find_package(LuaJIT 5.1)
endif()
else()
if(NOT APPLE)
find_package(LuaJIT 5.2)
endif()
endif()
find_package( Threads REQUIRED ) if( LUAJIT_FOUND )
target_link_libraries (osrm-extract ${Threads_LIBRARY}) 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( LuaJIT ) find_package(LibXml2 REQUIRED)
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( LibXml2 REQUIRED )
include_directories(${LIBXML2_INCLUDE_DIR}) include_directories(${LIBXML2_INCLUDE_DIR})
target_link_libraries (osrm-extract ${LIBXML2_LIBRARIES}) target_link_libraries(osrm-extract ${LIBXML2_LIBRARIES})
find_package( Luabind REQUIRED ) find_package( Luabind REQUIRED )
include_directories(${LUABIND_INCLUDE_DIR}) include_directories(${LUABIND_INCLUDE_DIR})
target_link_libraries (osrm-extract ${LUABIND_LIBRARY}) target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
target_link_libraries (osrm-prepare ${LUABIND_LIBRARY}) target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
find_package( Protobuf REQUIRED )
include_directories(${PROTOBUF_INCLUDE_DIRS})
target_link_libraries (osrm-extract ${PROTOBUF_LIBRARY})
target_link_libraries (osrm-prepare ${PROTOBUF_LIBRARY})
find_package( STXXL REQUIRED ) find_package( STXXL REQUIRED )
include_directories(${STXXL_INCLUDE_DIR}) include_directories(${STXXL_INCLUDE_DIR})
target_link_libraries (OSRM ${STXXL_LIBRARY}) target_link_libraries(OSRM ${STXXL_LIBRARY})
target_link_libraries (osrm-extract ${STXXL_LIBRARY}) target_link_libraries(osrm-extract ${STXXL_LIBRARY})
target_link_libraries (osrm-prepare ${STXXL_LIBRARY}) target_link_libraries(osrm-prepare ${STXXL_LIBRARY})
find_package( OSMPBF REQUIRED ) find_package( OSMPBF REQUIRED )
include_directories(${OSMPBF_INCLUDE_DIR}) include_directories(${OSMPBF_INCLUDE_DIR})
target_link_libraries (osrm-extract ${OSMPBF_LIBRARY}) target_link_libraries(osrm-extract ${OSMPBF_LIBRARY})
target_link_libraries (osrm-prepare ${OSMPBF_LIBRARY}) target_link_libraries(osrm-prepare ${OSMPBF_LIBRARY})
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${PROTOBUF_LIBRARY})
target_link_libraries(osrm-prepare ${PROTOBUF_LIBRARY})
find_package(BZip2 REQUIRED)
include_directories(${BZIP_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${BZIP2_LIBRARIES})
find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${ZLIB_LIBRARY})
target_link_libraries(osrm-routed ${ZLIB_LIBRARY})
if(WITH_TOOLS) if(WITH_TOOLS)
message("-- Activating OSRM internal tools") message(STATUS "Activating OSRM internal tools")
find_package( GDAL ) find_package(GDAL)
if(GDAL_FOUND) if(GDAL_FOUND)
add_executable(osrm-components Tools/componentAnalysis.cpp) add_executable(osrm-components Tools/componentAnalysis.cpp)
include_directories(${GDAL_INCLUDE_DIR}) include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries( target_link_libraries(
osrm-components ${GDAL_LIBRARIES} ${Boost_LIBRARIES} UUID osrm-components
) ${GDAL_LIBRARIES} ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
endif(GDAL_FOUND) endif()
add_executable ( osrm-cli Tools/simpleclient.cpp Util/GitDescription.cpp) add_executable(osrm-cli Tools/simpleclient.cpp)
target_link_libraries( osrm-cli ${Boost_LIBRARIES} OSRM UUID ) target_link_libraries(osrm-cli ${Boost_LIBRARIES} OSRM UUID GITDESCRIPTION)
add_executable ( osrm-io-benchmark Tools/io-benchmark.cpp ) 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)
endif(WITH_TOOLS) add_executable(osrm-unlock-all Tools/unlock_all_mutexes.cpp)
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} GITDESCRIPTION)
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-unlock-all rt)
endif()
endif()
file(GLOB InstallGlob Include/osrm/*.h Library/OSRM.h)
# Add RPATH info to executables so that when they are run after being installed
# (i.e., from /usr/local/bin/) the linker can find library dependencies. For
# more info see http://www.cmake.org/Wiki/CMake_RPATH_handling
set_property(TARGET osrm-extract PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-prepare PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-datastore PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
install(FILES ${InstallGlob} DESTINATION include/osrm)
install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-prepare DESTINATION bin)
install(TARGETS osrm-datastore DESTINATION bin)
install(TARGETS osrm-routed DESTINATION bin)
install(TARGETS OSRM DESTINATION lib)
list(GET Boost_LIBRARIES 1 BOOST_LIBRARY_FIRST)
get_filename_component(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_FIRST}" PATH)
set(BOOST_LIBRARY_LISTING "-L${BOOST_LIBRARY_LISTING}")
foreach (lib ${Boost_LIBRARIES})
get_filename_component(BOOST_LIBRARY_NAME "${lib}" NAME_WE)
string(REPLACE "lib" "" BOOST_LIBRARY_NAME ${BOOST_LIBRARY_NAME})
set(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_LISTING} -l${BOOST_LIBRARY_NAME}")
endforeach ()
configure_file(${CMAKE_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
+56 -59
View File
@@ -45,8 +45,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <ctime>
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
#include <vector> #include <vector>
@@ -54,10 +52,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class Contractor { class Contractor {
private: private:
struct _ContractorEdgeData { struct ContractorEdgeData {
_ContractorEdgeData() : ContractorEdgeData() :
distance(0), id(0), originalEdges(0), shortcut(0), forward(0), backward(0), originalViaNodeID(false) {} distance(0), id(0), originalEdges(0), shortcut(0), forward(0), backward(0), originalViaNodeID(false) {}
_ContractorEdgeData( unsigned _distance, unsigned _originalEdges, unsigned _id, bool _shortcut, bool _forward, bool _backward) : ContractorEdgeData( unsigned _distance, unsigned _originalEdges, unsigned _id, bool _shortcut, bool _forward, bool _backward) :
distance(_distance), id(_id), originalEdges(std::min((unsigned)1<<28, _originalEdges) ), shortcut(_shortcut), forward(_forward), backward(_backward), originalViaNodeID(false) {} distance(_distance), id(_id), originalEdges(std::min((unsigned)1<<28, _originalEdges) ), shortcut(_shortcut), forward(_forward), backward(_backward), originalViaNodeID(false) {}
unsigned distance; unsigned distance;
unsigned id; unsigned id;
@@ -75,7 +73,7 @@ private:
_HeapData( short h, bool t ) : hop(h), target(t) {} _HeapData( short h, bool t ) : hop(h), target(t) {}
}; };
typedef DynamicGraph< _ContractorEdgeData > _DynamicGraph; typedef DynamicGraph< ContractorEdgeData > _DynamicGraph;
// typedef BinaryHeap< NodeID, NodeID, int, _HeapData, ArrayStorage<NodeID, NodeID> > _Heap; // typedef BinaryHeap< NodeID, NodeID, int, _HeapData, ArrayStorage<NodeID, NodeID> > _Heap;
typedef BinaryHeap< NodeID, NodeID, int, _HeapData, XORFastHashStorage<NodeID, NodeID> > _Heap; typedef BinaryHeap< NodeID, NodeID, int, _HeapData, XORFastHashStorage<NodeID, NodeID> > _Heap;
typedef _DynamicGraph::InputEdge _ContractorEdge; typedef _DynamicGraph::InputEdge _ContractorEdge;
@@ -118,6 +116,7 @@ public:
Contractor( int nodes, ContainerT& inputEdges) { Contractor( int nodes, ContainerT& inputEdges) {
std::vector< _ContractorEdge > edges; std::vector< _ContractorEdge > edges;
edges.reserve(inputEdges.size()*2); edges.reserve(inputEdges.size()*2);
temp_edge_counter = 0;
typename ContainerT::deallocation_iterator diter = inputEdges.dbegin(); typename ContainerT::deallocation_iterator diter = inputEdges.dbegin();
typename ContainerT::deallocation_iterator dend = inputEdges.dend(); typename ContainerT::deallocation_iterator dend = inputEdges.dend();
@@ -126,8 +125,7 @@ public:
while(diter!=dend) { while(diter!=dend) {
newEdge.source = diter->source(); newEdge.source = diter->source();
newEdge.target = diter->target(); newEdge.target = diter->target();
newEdge.data = _ContractorEdgeData( (std::max)((int)diter->weight(), 1 ), 1, diter->id(), false, diter->isForward(), diter->isBackward()); newEdge.data = ContractorEdgeData( (std::max)((int)diter->weight(), 1 ), 1, diter->id(), false, diter->isForward(), diter->isBackward());
BOOST_ASSERT_MSG( newEdge.data.distance > 0, "edge distance < 1" ); BOOST_ASSERT_MSG( newEdge.data.distance > 0, "edge distance < 1" );
#ifndef NDEBUG #ifndef NDEBUG
if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) { if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) {
@@ -195,6 +193,7 @@ public:
_graph = boost::make_shared<_DynamicGraph>( nodes, edges ); _graph = boost::make_shared<_DynamicGraph>( nodes, edges );
edges.clear(); edges.clear();
std::vector<_ContractorEdge>().swap(edges); std::vector<_ContractorEdge>().swap(edges);
BOOST_ASSERT( 0 == edges.capacity() );
// unsigned maxdegree = 0; // unsigned maxdegree = 0;
// NodeID highestNode = 0; // NodeID highestNode = 0;
// //
@@ -214,14 +213,14 @@ public:
//Create temporary file //Create temporary file
// GetTemporaryFileName(temporaryEdgeStorageFilename); // GetTemporaryFileName(temporaryEdgeStorageFilename);
temporaryStorageSlotID = TemporaryStorage::GetInstance().allocateSlot(); edge_storage_slot = TemporaryStorage::GetInstance().AllocateSlot();
std::cout << "contractor finished initalization" << std::endl; std::cout << "contractor finished initalization" << std::endl;
} }
~Contractor() { ~Contractor() {
//Delete temporary file //Delete temporary file
// remove(temporaryEdgeStorageFilename.c_str()); // remove(temporaryEdgeStorageFilename.c_str());
TemporaryStorage::GetInstance().deallocateSlot(temporaryStorageSlotID); TemporaryStorage::GetInstance().DeallocateSlot(edge_storage_slot);
} }
void Run() { void Run() {
@@ -264,11 +263,11 @@ public:
std::cout << " [flush " << numberOfContractedNodes << " nodes] " << std::flush; std::cout << " [flush " << numberOfContractedNodes << " nodes] " << std::flush;
//Delete old heap data to free memory that we need for the coming operations //Delete old heap data to free memory that we need for the coming operations
BOOST_FOREACH(_ThreadData * data, threadData) BOOST_FOREACH(_ThreadData * data, threadData) {
delete data; delete data;
}
threadData.clear(); threadData.clear();
//Create new priority array //Create new priority array
std::vector<float> newNodePriority(remainingNodes.size()); std::vector<float> newNodePriority(remainingNodes.size());
//this map gives the old IDs from the new ones, necessary to get a consistent graph at the end of contraction //this map gives the old IDs from the new ones, necessary to get a consistent graph at the end of contraction
@@ -285,12 +284,6 @@ public:
remainingNodes[newNodeID].id = newNodeID; remainingNodes[newNodeID].id = newNodeID;
} }
TemporaryStorage & tempStorage = TemporaryStorage::GetInstance(); TemporaryStorage & tempStorage = TemporaryStorage::GetInstance();
//Write dummy number of edges to temporary file
// std::ofstream temporaryEdgeStorage(temporaryEdgeStorageFilename.c_str(), std::ios::binary);
uint64_t initialFilePosition = tempStorage.tell(temporaryStorageSlotID);
unsigned numberOfTemporaryEdges = 0;
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&numberOfTemporaryEdges, sizeof(unsigned));
//walk over all nodes //walk over all nodes
for(unsigned i = 0; i < _graph->GetNumberOfNodes(); ++i) { for(unsigned i = 0; i < _graph->GetNumberOfNodes(); ++i) {
const NodeID start = i; const NodeID start = i;
@@ -299,11 +292,11 @@ public:
const NodeID target = _graph->GetTarget(currentEdge); const NodeID target = _graph->GetTarget(currentEdge);
if(UINT_MAX == newNodeIDFromOldNodeIDMap[i] ){ if(UINT_MAX == newNodeIDFromOldNodeIDMap[i] ){
//Save edges of this node w/o renumbering. //Save edges of this node w/o renumbering.
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&start, sizeof(NodeID)); tempStorage.WriteToSlot(edge_storage_slot, (char*)&start, sizeof(NodeID));
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&target, sizeof(NodeID)); tempStorage.WriteToSlot(edge_storage_slot, (char*)&target, sizeof(NodeID));
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&data, sizeof(_DynamicGraph::EdgeData)); tempStorage.WriteToSlot(edge_storage_slot, (char*)&data, sizeof(_DynamicGraph::EdgeData));
++numberOfTemporaryEdges; ++temp_edge_counter;
}else { } else {
//node is not yet contracted. //node is not yet contracted.
//add (renumbered) outgoing edges to new DynamicGraph. //add (renumbered) outgoing edges to new DynamicGraph.
_ContractorEdge newEdge; _ContractorEdge newEdge;
@@ -323,9 +316,6 @@ public:
} }
} }
} }
//Note the number of temporarily stored edges
tempStorage.seek(temporaryStorageSlotID, initialFilePosition);
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&numberOfTemporaryEdges, sizeof(unsigned));
//Delete map from old NodeIDs to new ones. //Delete map from old NodeIDs to new ones.
std::vector<NodeID>().swap(newNodeIDFromOldNodeIDMap); std::vector<NodeID>().swap(newNodeIDFromOldNodeIDMap);
@@ -394,10 +384,14 @@ public:
_DynamicGraph::EdgeIterator currentEdgeID = _graph->FindEdge(edge.source, edge.target); _DynamicGraph::EdgeIterator currentEdgeID = _graph->FindEdge(edge.source, edge.target);
if(currentEdgeID < _graph->EndEdges(edge.source) ) { if(currentEdgeID < _graph->EndEdges(edge.source) ) {
_DynamicGraph::EdgeData & currentEdgeData = _graph->GetEdgeData(currentEdgeID); _DynamicGraph::EdgeData & currentEdgeData = _graph->GetEdgeData(currentEdgeID);
if( currentEdgeData.shortcut if( currentEdgeData.shortcut &&
&& edge.data.forward == currentEdgeData.forward edge.data.forward == currentEdgeData.forward &&
&& edge.data.backward == currentEdgeData.backward ) { edge.data.backward == currentEdgeData.backward &&
currentEdgeData.distance = std::min(currentEdgeData.distance, edge.data.distance); edge.data.distance < currentEdgeData.distance
) {
// found a duplicate edge with smaller weight, update it.
currentEdgeData = edge.data;
// currentEdgeData.distance = std::min(currentEdgeData.distance, edge.data.distance);
continue; continue;
} }
} }
@@ -454,13 +448,13 @@ public:
SimpleLogger().Write() << "Getting edges of minimized graph"; SimpleLogger().Write() << "Getting edges of minimized graph";
NodeID numberOfNodes = _graph->GetNumberOfNodes(); NodeID numberOfNodes = _graph->GetNumberOfNodes();
if(_graph->GetNumberOfNodes()) { if(_graph->GetNumberOfNodes()) {
Edge newEdge;
for ( NodeID node = 0; node < numberOfNodes; ++node ) { for ( NodeID node = 0; node < numberOfNodes; ++node ) {
p.printStatus(node); p.printStatus(node);
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; ++edge ) { for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; ++edge ) {
const NodeID target = _graph->GetTarget( edge ); const NodeID target = _graph->GetTarget( edge );
const _DynamicGraph::EdgeData& data = _graph->GetEdgeData( edge ); const _DynamicGraph::EdgeData& data = _graph->GetEdgeData( edge );
Edge newEdge; if( !oldNodeIDFromNewNodeIDMap.empty() ) {
if(0 != oldNodeIDFromNewNodeIDMap.size()) {
newEdge.source = oldNodeIDFromNewNodeIDMap[node]; newEdge.source = oldNodeIDFromNewNodeIDMap[node];
newEdge.target = oldNodeIDFromNewNodeIDMap[target]; newEdge.target = oldNodeIDFromNewNodeIDMap[target];
} else { } else {
@@ -477,7 +471,10 @@ public:
); );
newEdge.data.distance = data.distance; newEdge.data.distance = data.distance;
newEdge.data.shortcut = data.shortcut; newEdge.data.shortcut = data.shortcut;
if(!data.originalViaNodeID && oldNodeIDFromNewNodeIDMap.size()) { if(
!data.originalViaNodeID &&
!oldNodeIDFromNewNodeIDMap.empty()
) {
newEdge.data.id = oldNodeIDFromNewNodeIDMap[data.id]; newEdge.data.id = oldNodeIDFromNewNodeIDMap[data.id];
} else { } else {
newEdge.data.id = data.id; newEdge.data.id = data.id;
@@ -494,31 +491,29 @@ public:
} }
_graph.reset(); _graph.reset();
std::vector<NodeID>().swap(oldNodeIDFromNewNodeIDMap); std::vector<NodeID>().swap(oldNodeIDFromNewNodeIDMap);
BOOST_ASSERT( 0 == oldNodeIDFromNewNodeIDMap.capacity() );
TemporaryStorage & tempStorage = TemporaryStorage::GetInstance(); TemporaryStorage & tempStorage = TemporaryStorage::GetInstance();
//Also get the edges from temporary storage
unsigned numberOfTemporaryEdges = 0;
tempStorage.readFromSlot(temporaryStorageSlotID, (char*)&numberOfTemporaryEdges, sizeof(unsigned));
//loads edges of graph before renumbering, no need for further numbering action. //loads edges of graph before renumbering, no need for further numbering action.
NodeID start; NodeID start;
NodeID target; NodeID target;
//edges.reserve(edges.size()+numberOfTemporaryEdges);
_DynamicGraph::EdgeData data; _DynamicGraph::EdgeData data;
for(unsigned i = 0; i < numberOfTemporaryEdges; ++i) {
tempStorage.readFromSlot(temporaryStorageSlotID, (char*)&start, sizeof(NodeID)); Edge restored_edge;
tempStorage.readFromSlot(temporaryStorageSlotID, (char*)&target, sizeof(NodeID)); for(unsigned i = 0; i < temp_edge_counter; ++i) {
tempStorage.readFromSlot(temporaryStorageSlotID, (char*)&data, sizeof(_DynamicGraph::EdgeData)); tempStorage.ReadFromSlot(edge_storage_slot, (char*)&start, sizeof(NodeID));
Edge newEdge; tempStorage.ReadFromSlot(edge_storage_slot, (char*)&target, sizeof(NodeID));
newEdge.source = start; tempStorage.ReadFromSlot(edge_storage_slot, (char*)&data, sizeof(_DynamicGraph::EdgeData));
newEdge.target = target; restored_edge.source = start;
newEdge.data.distance = data.distance; restored_edge.target = target;
newEdge.data.shortcut = data.shortcut; restored_edge.data.distance = data.distance;
newEdge.data.id = data.id; restored_edge.data.shortcut = data.shortcut;
newEdge.data.forward = data.forward; restored_edge.data.id = data.id;
newEdge.data.backward = data.backward; restored_edge.data.forward = data.forward;
edges.push_back( newEdge ); restored_edge.data.backward = data.backward;
edges.push_back( restored_edge );
} }
tempStorage.deallocateSlot(temporaryStorageSlotID); tempStorage.DeallocateSlot(edge_storage_slot);
} }
private: private:
@@ -548,7 +543,7 @@ private:
//iterate over all edges of node //iterate over all edges of node
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) { for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) {
const _ContractorEdgeData& data = _graph->GetEdgeData( edge ); const ContractorEdgeData& data = _graph->GetEdgeData( edge );
if ( !data.forward ){ if ( !data.forward ){
continue; continue;
} }
@@ -594,7 +589,7 @@ private:
std::vector< _ContractorEdge >& insertedEdges = data->insertedEdges; std::vector< _ContractorEdge >& insertedEdges = data->insertedEdges;
for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) { for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) {
const _ContractorEdgeData& inData = _graph->GetEdgeData( inEdge ); const ContractorEdgeData& inData = _graph->GetEdgeData( inEdge );
const NodeID source = _graph->GetTarget( inEdge ); const NodeID source = _graph->GetTarget( inEdge );
if ( Simulate ) { if ( Simulate ) {
assert( stats != NULL ); assert( stats != NULL );
@@ -610,7 +605,7 @@ private:
unsigned numTargets = 0; unsigned numTargets = 0;
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) { for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
const _ContractorEdgeData& outData = _graph->GetEdgeData( outEdge ); const ContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward ) { if ( !outData.forward ) {
continue; continue;
} }
@@ -629,7 +624,7 @@ private:
_Dijkstra( maxDistance, numTargets, 2000, data, node ); _Dijkstra( maxDistance, numTargets, 2000, data, node );
} }
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) { for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
const _ContractorEdgeData& outData = _graph->GetEdgeData( outEdge ); const ContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward ) { if ( !outData.forward ) {
continue; continue;
} }
@@ -645,7 +640,7 @@ private:
_ContractorEdge newEdge; _ContractorEdge newEdge;
newEdge.source = source; newEdge.source = source;
newEdge.target = target; newEdge.target = target;
newEdge.data = _ContractorEdgeData( pathDistance, outData.originalEdges + inData.originalEdges, node/*, 0, inData.turnInstruction*/, true, true, false);; newEdge.data = ContractorEdgeData( pathDistance, outData.originalEdges + inData.originalEdges, node/*, 0, inData.turnInstruction*/, true, true, false);;
insertedEdges.push_back( newEdge ); insertedEdges.push_back( newEdge );
std::swap( newEdge.source, newEdge.target ); std::swap( newEdge.source, newEdge.target );
newEdge.data.forward = false; newEdge.data.forward = false;
@@ -738,9 +733,10 @@ private:
if ( priority > targetPriority ) if ( priority > targetPriority )
return false; return false;
//tie breaking //tie breaking
if ( fabs(priority - targetPriority) < std::numeric_limits<double>::epsilon() && bias(node, target) ) { if ( std::abs(priority - targetPriority) < std::numeric_limits<double>::epsilon() && bias(node, target) ) {
return false; return false;
} }
// TODO: C++11 copy_if with lambda
neighbours.push_back( target ); neighbours.push_back( target );
} }
@@ -760,7 +756,7 @@ private:
if ( priority > targetPriority) if ( priority > targetPriority)
return false; return false;
//tie breaking //tie breaking
if ( fabs(priority - targetPriority) < std::numeric_limits<double>::epsilon() && bias(node, target) ) { if ( std::abs(priority - targetPriority) < std::numeric_limits<double>::epsilon() && bias(node, target) ) {
return false; return false;
} }
} }
@@ -784,7 +780,8 @@ private:
boost::shared_ptr<_DynamicGraph> _graph; boost::shared_ptr<_DynamicGraph> _graph;
std::vector<_DynamicGraph::InputEdge> contractedEdges; std::vector<_DynamicGraph::InputEdge> contractedEdges;
unsigned temporaryStorageSlotID; unsigned edge_storage_slot;
uint64_t temp_edge_counter;
std::vector<NodeID> oldNodeIDFromNewNodeIDMap; std::vector<NodeID> oldNodeIDFromNewNodeIDMap;
XORFastHash fastHash; XORFastHash fastHash;
}; };
File diff suppressed because it is too large Load Diff
+89 -86
View File
@@ -33,73 +33,68 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h" #include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h" #include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h" #include "../DataStructures/DynamicGraph.h"
#include "../Extractor/ExtractorStructs.h" #include "../DataStructures/EdgeBasedNode.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportEdge.h" #include "../DataStructures/ImportEdge.h"
#include "../DataStructures/QueryEdge.h" #include "../DataStructures/OriginalEdgeData.h"
#include "../DataStructures/Percent.h" #include "../DataStructures/Percent.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../DataStructures/Restriction.h"
#include "../Util/LuaUtil.h" #include "../Util/LuaUtil.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <boost/foreach.hpp> #include "GeometryCompressor.h"
#include <boost/make_shared.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#include <algorithm> #include <algorithm>
#include <fstream> #include <iosfwd>
#include <queue> #include <queue>
#include <vector> #include <vector>
class EdgeBasedGraphFactory : boost::noncopyable { class EdgeBasedGraphFactory : boost::noncopyable {
public: public:
struct EdgeBasedNode { struct SpeedProfileProperties;
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 { explicit EdgeBasedGraphFactory(
return other.id < id; int number_of_nodes,
} std::vector<ImportEdge> & input_edge_list,
std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties & speed_profile
);
bool operator==(const EdgeBasedNode & other) const { void Run(
return id == other.id; const std::string & original_edge_data_filename,
} const std::string & geometry_filename,
lua_State *myLuaState
);
inline FixedPointCoordinate Centroid() const { void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
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 { void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
return ignoreInGrid;
}
NodeID id; TurnInstruction AnalyzeTurn(
int lat1; const NodeID u,
int lat2; const NodeID v,
int lon1; const NodeID w
int lon2:31; ) const;
bool belongsToTinyComponent:1;
NodeID nameID; int GetTurnPenalty(
unsigned weight:31; const NodeID u,
bool ignoreInGrid:1; const NodeID v,
}; const NodeID w,
lua_State *myLuaState
) const;
unsigned GetNumberOfEdgeBasedNodes() const;
struct SpeedProfileProperties{ struct SpeedProfileProperties{
SpeedProfileProperties() : SpeedProfileProperties() :
@@ -113,36 +108,13 @@ public:
bool has_turn_penalty_function; bool has_turn_penalty_function;
} speed_profile; } speed_profile;
explicit EdgeBasedGraphFactory(
int number_of_nodes,
std::vector<ImportEdge> & input_edge_list,
std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speed_profile
);
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
void GetOriginalEdgeData( std::vector<OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(
const NodeID u,
const NodeID v,
const NodeID w
) const;
int GetTurnPenalty(
const NodeID u,
const NodeID v,
const NodeID w,
lua_State *myLuaState
) const;
unsigned GetNumberOfNodes() const;
private: private:
struct NodeBasedEdgeData { struct NodeBasedEdgeData {
NodeBasedEdgeData() {
//TODO: proper c'tor
edgeBasedNodeID = UINT_MAX;
}
int distance; int distance;
unsigned edgeBasedNodeID; unsigned edgeBasedNodeID;
unsigned nameID; unsigned nameID;
@@ -152,20 +124,26 @@ private:
bool forward:1; bool forward:1;
bool backward:1; bool backward:1;
bool roundabout:1; bool roundabout:1;
bool ignoreInGrid:1; bool ignore_in_grid:1;
bool contraFlow:1; bool contraFlow:1;
};
struct _EdgeBasedEdgeData { void SwapDirectionFlags() {
int distance; bool temp_flag = forward;
unsigned via; forward = backward;
unsigned nameID; backward = temp_flag;
bool forward; }
bool backward;
TurnInstruction turnInstruction; bool IsEqualTo( const NodeBasedEdgeData & other ) const {
return (forward == other.forward) &&
(backward == other.backward) &&
(nameID == other.nameID) &&
(ignore_in_grid == other.ignore_in_grid) &&
(contraFlow == other.contraFlow);
}
}; };
unsigned m_turn_restrictions_count; unsigned m_turn_restrictions_count;
unsigned m_number_of_edge_based_nodes;
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph; typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge; typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
@@ -187,7 +165,7 @@ private:
boost::unordered_set<NodeID> m_traffic_lights; boost::unordered_set<NodeID> m_traffic_lights;
RestrictionMap m_restriction_map; RestrictionMap m_restriction_map;
GeometryCompressor m_geometry_compressor;
NodeID CheckForEmanatingIsOnlyTurn( NodeID CheckForEmanatingIsOnlyTurn(
const NodeID u, const NodeID u,
@@ -201,10 +179,35 @@ private:
) const; ) const;
void InsertEdgeBasedNode( void InsertEdgeBasedNode(
NodeBasedDynamicGraph::EdgeIterator e1, NodeBasedDynamicGraph::NodeIterator u,
NodeBasedDynamicGraph::NodeIterator u, NodeBasedDynamicGraph::NodeIterator v,
NodeBasedDynamicGraph::NodeIterator v, NodeBasedDynamicGraph::EdgeIterator e1,
bool belongsToTinyComponent); bool belongsToTinyComponent
);
void BFSCompentExplorer(
std::vector<unsigned> & component_index_list,
std::vector<unsigned> & component_index_size
) const;
void FlushVectorToStream(
std::ofstream & edge_data_file,
std::vector<OriginalEdgeData> & original_edge_data_vector
) const;
void FixupArrivingTurnRestriction(
const NodeID u,
const NodeID v,
const NodeID w
);
void FixupStartingTurnRestriction(
const NodeID u,
const NodeID v,
const NodeID w
);
unsigned max_id;
}; };
#endif /* EDGEBASEDGRAPHFACTORY_H_ */ #endif /* EDGEBASEDGRAPHFACTORY_H_ */
+224
View File
@@ -0,0 +1,224 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "GeometryCompressor.h"
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/foreach.hpp>
#include <limits>
int current_free_list_maximum = 0;
int UniqueNumber() { return ++current_free_list_maximum; }
GeometryCompressor::GeometryCompressor()
{
m_free_list.reserve(100);
IncreaseFreeList();
}
void GeometryCompressor::IncreaseFreeList()
{
m_compressed_geometries.resize(m_compressed_geometries.size() + 100);
for (unsigned i = 100; i > 0; --i)
{
m_free_list.push_back(current_free_list_maximum);
++current_free_list_maximum;
}
}
bool GeometryCompressor::HasEntryForID(const EdgeID edge_id) const
{
return (m_edge_id_to_list_index_map.find(edge_id) != m_edge_id_to_list_index_map.end());
}
unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const
{
boost::unordered_map<EdgeID, unsigned>::const_iterator map_iterator;
map_iterator = m_edge_id_to_list_index_map.find(edge_id);
BOOST_ASSERT(map_iterator != m_edge_id_to_list_index_map.end());
BOOST_ASSERT(map_iterator->second < m_compressed_geometries.size());
return map_iterator->second;
}
void GeometryCompressor::SerializeInternalVector(const std::string &path) const
{
boost::filesystem::fstream geometry_out_stream(path, std::ios::binary|std::ios::out);
const unsigned number_of_compressed_geometries = m_compressed_geometries.size() + 1;
BOOST_ASSERT(UINT_MAX != number_of_compressed_geometries);
geometry_out_stream.write((char *)&number_of_compressed_geometries, sizeof(unsigned));
// write indices array
unsigned prefix_sum_of_list_indices = 0;
for (unsigned i = 0; i < m_compressed_geometries.size(); ++i)
{
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
const std::vector<CompressedNode> &current_vector = m_compressed_geometries.at(i);
const unsigned unpacked_size = current_vector.size();
BOOST_ASSERT(UINT_MAX != unpacked_size);
prefix_sum_of_list_indices += unpacked_size;
}
// sentinel element
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
// number of geometry entries to follow, it is the (inclusive) prefix sum
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
unsigned control_sum = 0;
// write compressed geometries
for (unsigned i = 0; i < m_compressed_geometries.size(); ++i)
{
const std::vector<CompressedNode> &current_vector = m_compressed_geometries[i];
const unsigned unpacked_size = current_vector.size();
control_sum += unpacked_size;
BOOST_ASSERT(UINT_MAX != unpacked_size);
BOOST_FOREACH (const CompressedNode current_node, current_vector)
{
geometry_out_stream.write((char *)&(current_node.first), sizeof(NodeID));
}
}
BOOST_ASSERT(control_sum == prefix_sum_of_list_indices);
// all done, let's close the resource
geometry_out_stream.close();
}
void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
const EdgeID edge_id_2,
const NodeID via_node_id,
const NodeID target_node_id,
const EdgeWeight weight1,
const EdgeWeight weight2)
{
// remove super-trivial geometries
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_1);
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2);
BOOST_ASSERT(SPECIAL_NODEID != via_node_id);
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
BOOST_ASSERT(std::numeric_limits<int>::max() != weight1);
BOOST_ASSERT(std::numeric_limits<int>::max() != weight2);
// append list of removed edge_id plus via node to surviving edge id:
// <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n
//
// General scheme:
// 1. append via node id to list of edge_id_1
// 2. find list for edge_id_2, if yes add all elements and delete it
// Add via node id. List is created if it does not exist
if (!HasEntryForID(edge_id_1))
{
// create a new entry in the map
if (0 == m_free_list.size())
{
// make sure there is a place to put the entries
IncreaseFreeList();
}
BOOST_ASSERT(!m_free_list.empty());
m_edge_id_to_list_index_map[edge_id_1] = m_free_list.back();
m_free_list.pop_back();
}
const unsigned edge_bucket_id1 = m_edge_id_to_list_index_map[edge_id_1];
BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1));
BOOST_ASSERT(edge_bucket_id1 < m_compressed_geometries.size());
std::vector<CompressedNode> &edge_bucket_list1 = m_compressed_geometries[edge_bucket_id1];
if (edge_bucket_list1.empty())
{
edge_bucket_list1.push_back(std::make_pair(via_node_id, weight1));
}
BOOST_ASSERT(0 < edge_bucket_list1.size());
BOOST_ASSERT(!edge_bucket_list1.empty());
if (HasEntryForID(edge_id_2))
{
// second edge is not atomic anymore
const unsigned list_to_remove_index = GetPositionForID(edge_id_2);
BOOST_ASSERT(list_to_remove_index < m_compressed_geometries.size());
std::vector<CompressedNode> &edge_bucket_list2 =
m_compressed_geometries[list_to_remove_index];
// found an existing list, append it to the list of edge_id_1
edge_bucket_list1.insert(
edge_bucket_list1.end(), edge_bucket_list2.begin(), edge_bucket_list2.end());
// remove the list of edge_id_2
m_edge_id_to_list_index_map.erase(edge_id_2);
BOOST_ASSERT(m_edge_id_to_list_index_map.end() ==
m_edge_id_to_list_index_map.find(edge_id_2));
edge_bucket_list2.clear();
BOOST_ASSERT(0 == edge_bucket_list2.size());
m_free_list.push_back(list_to_remove_index);
BOOST_ASSERT(list_to_remove_index == m_free_list.back());
}
else
{
// we are certain that the second edge is atomic.
edge_bucket_list1.push_back(std::make_pair(target_node_id, weight2));
}
}
void GeometryCompressor::PrintStatistics() const
{
const uint64_t compressed_edges = m_compressed_geometries.size();
BOOST_ASSERT(0 == compressed_edges % 2);
BOOST_ASSERT(m_compressed_geometries.size() + m_free_list.size() > 0);
uint64_t number_of_compressed_geometries = 0;
uint64_t longest_chain_length = 0;
BOOST_FOREACH (const std::vector<CompressedNode> &current_vector, m_compressed_geometries)
{
number_of_compressed_geometries += current_vector.size();
longest_chain_length = std::max(longest_chain_length, (uint64_t)current_vector.size());
}
SimpleLogger().Write() << "Geometry successfully removed:"
"\n compressed edges: " << compressed_edges
<< "\n compressed geometries: " << number_of_compressed_geometries
<< "\n longest chain length: " << longest_chain_length
<< "\n cmpr ratio: "
<< ((float)compressed_edges /
std::max(number_of_compressed_geometries, (uint64_t)1))
<< "\n avg chain length: "
<< (float)number_of_compressed_geometries /
std::max((uint64_t)1, compressed_edges);
}
const std::vector<GeometryCompressor::CompressedNode> &
GeometryCompressor::GetBucketReference(const EdgeID edge_id) const
{
const unsigned index = m_edge_id_to_list_index_map.at(edge_id);
return m_compressed_geometries.at(index);
}
+64
View File
@@ -0,0 +1,64 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../typedefs.h"
#include <boost/unordered_map.hpp>
#include <vector>
#ifndef GEOMETRY_COMPRESSOR_H
#define GEOMETRY_COMPRESSOR_H
class GeometryCompressor
{
public:
typedef std::pair<NodeID, EdgeWeight> CompressedNode;
GeometryCompressor();
void CompressEdge(const EdgeID surviving_edge_id,
const EdgeID removed_edge_id,
const NodeID via_node_id,
const NodeID target_node,
const EdgeWeight weight1,
const EdgeWeight weight2);
bool HasEntryForID(const EdgeID edge_id) const;
void PrintStatistics() const;
void SerializeInternalVector(const std::string &path) const;
unsigned GetPositionForID(const EdgeID edge_id) const;
const std::vector<GeometryCompressor::CompressedNode> &
GetBucketReference(const EdgeID edge_id) const;
private:
void IncreaseFreeList();
std::vector<std::vector<CompressedNode> > m_compressed_geometries;
std::vector<unsigned> m_free_list;
boost::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
};
#endif // GEOMETRY_COMPRESSOR_H
+82 -60
View File
@@ -28,113 +28,135 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "TemporaryStorage.h" #include "TemporaryStorage.h"
TemporaryStorage::TemporaryStorage() { TemporaryStorage::TemporaryStorage() {
tempDirectory = boost::filesystem::temp_directory_path(); temp_directory = boost::filesystem::temp_directory_path();
} }
TemporaryStorage & TemporaryStorage::GetInstance(){ TemporaryStorage & TemporaryStorage::GetInstance(){
static TemporaryStorage runningInstance; static TemporaryStorage static_instance;
return runningInstance; return static_instance;
} }
TemporaryStorage::~TemporaryStorage() { TemporaryStorage::~TemporaryStorage() {
removeAll(); RemoveAll();
} }
void TemporaryStorage::removeAll() { void TemporaryStorage::RemoveAll() {
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
for(unsigned slot_id = 0; slot_id < vectorOfStreamDatas.size(); ++slot_id) { for(unsigned slot_id = 0; slot_id < stream_data_list.size(); ++slot_id) {
deallocateSlot(slot_id); DeallocateSlot(slot_id);
} }
vectorOfStreamDatas.clear(); stream_data_list.clear();
} }
int TemporaryStorage::allocateSlot() { int TemporaryStorage::AllocateSlot() {
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
try { try {
vectorOfStreamDatas.push_back(StreamData()); stream_data_list.push_back(StreamData());
//SimpleLogger().Write() << "created new temporary file: " << vectorOfStreamDatas.back().pathToTemporaryFile;
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); Abort(e);
} }
return vectorOfStreamDatas.size() - 1; CheckIfTemporaryDeviceFull();
return stream_data_list.size() - 1;
} }
void TemporaryStorage::deallocateSlot(int slotID) { void TemporaryStorage::DeallocateSlot(const int slot_id) {
try { try {
StreamData & data = vectorOfStreamDatas[slotID]; StreamData & data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(!boost::filesystem::exists(data.pathToTemporaryFile)) { if(!boost::filesystem::exists(data.temp_path)) {
return; return;
} }
if(data.streamToTemporaryFile->is_open()) { if(data.temp_file->is_open()) {
data.streamToTemporaryFile->close(); data.temp_file->close();
} }
boost::filesystem::remove(data.pathToTemporaryFile); boost::filesystem::remove(data.temp_path);
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); Abort(e);
} }
} }
void TemporaryStorage::writeToSlot(int slotID, char * pointer, std::streamsize size) { void TemporaryStorage::WriteToSlot(
const int slot_id,
char * pointer,
const std::size_t size
) {
try { try {
StreamData & data = vectorOfStreamDatas[slotID]; StreamData & data = stream_data_list[slot_id];
BOOST_ASSERT(data.write_mode);
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(
data.writeMode, data.write_mode,
"Writing after first read is not allowed" "Writing after first read is not allowed"
); );
data.streamToTemporaryFile->write(pointer, size); if( 1073741824 < data.buffer.size() ) {
} catch(boost::filesystem::filesystem_error & e) { data.temp_file->write(&data.buffer[0], data.buffer.size());
abort(e); // data.temp_file->write(pointer, size);
} data.buffer.clear();
} CheckIfTemporaryDeviceFull();
void TemporaryStorage::readFromSlot(int slotID, char * pointer, std::streamsize size) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(data.writeMode) {
data.writeMode = false;
data.streamToTemporaryFile->seekg(0, data.streamToTemporaryFile->beg);
} }
data.streamToTemporaryFile->read(pointer, size); data.buffer.insert(data.buffer.end(), pointer, pointer+size);
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); Abort(e);
} }
} }
void TemporaryStorage::ReadFromSlot(
unsigned TemporaryStorage::getFreeBytesOnTemporaryDevice() { const int slot_id,
boost::filesystem::space_info tempSpaceInfo; char * pointer,
const std::size_t size
) {
try { try {
tempSpaceInfo = boost::filesystem::space(tempDirectory); StreamData & data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if( data.write_mode ) {
data.write_mode = false;
data.temp_file->write(&data.buffer[0], data.buffer.size());
data.buffer.clear();
data.temp_file->seekg( data.temp_file->beg );
BOOST_ASSERT( data.temp_file->beg == data.temp_file->tellg() );
}
BOOST_ASSERT( !data.write_mode );
data.temp_file->read(pointer, size);
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); Abort(e);
} }
return tempSpaceInfo.available;
} }
boost::filesystem::fstream::pos_type TemporaryStorage::tell(int slotID) { uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice() {
uint64_t value = -1;
try {
boost::filesystem::path p = boost::filesystem::temp_directory_path();
boost::filesystem::space_info s = boost::filesystem::space( p );
value = s.free;
} catch(boost::filesystem::filesystem_error & e) {
Abort(e);
}
return value;
}
void TemporaryStorage::CheckIfTemporaryDeviceFull() {
boost::filesystem::path p = boost::filesystem::temp_directory_path();
boost::filesystem::space_info s = boost::filesystem::space( p );
if( (1024*1024) > s.free ) {
throw OSRMException("temporary device is full");
}
}
boost::filesystem::fstream::pos_type TemporaryStorage::Tell(const int slot_id) {
boost::filesystem::fstream::pos_type position; boost::filesystem::fstream::pos_type position;
try { try {
StreamData & data = vectorOfStreamDatas[slotID]; StreamData & data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
position = data.streamToTemporaryFile->tellp(); position = data.temp_file->tellp();
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); Abort(e);
} }
return position; return position;
} }
void TemporaryStorage::abort(boost::filesystem::filesystem_error& ) { void TemporaryStorage::Abort(const boost::filesystem::filesystem_error& e) {
removeAll(); RemoveAll();
} throw OSRMException(e.what());
void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type position) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
data.streamToTemporaryFile->seekg(position);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
} }
+47 -54
View File
@@ -28,46 +28,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef TEMPORARYSTORAGE_H_ #ifndef TEMPORARYSTORAGE_H_
#define TEMPORARYSTORAGE_H_ #define TEMPORARYSTORAGE_H_
#include <vector> #include "../Util/BoostFileSystemFix.h"
#include <fstream>
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include "../Util/OSRMException.h" #include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
//This is one big workaround for latest boost renaming woes. #include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/integer.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#if BOOST_FILESYSTEM_VERSION < 3 #include <vector>
#warning Boost Installation with Filesystem3 missing, activating workaround #include <fstream>
#include <cstdio>
namespace boost {
namespace filesystem {
inline path temp_directory_path() {
char * buffer;
buffer = tmpnam (NULL);
return path(buffer);
}
inline path unique_path(const path&) {
return temp_directory_path();
}
}
}
#endif
#ifndef BOOST_FILESYSTEM_VERSION
#define BOOST_FILESYSTEM_VERSION 3
#endif
/** /**
* This class implements a singleton file storage for temporary data. * This class implements a singleton file storage for temporary data.
* temporary slots can be accessed by other objects through an int * temporary slots can be accessed by other objects through an int
@@ -77,49 +54,65 @@ inline path unique_path(const path&) {
* -> Data is written in first phase and reread in second. * -> Data is written in first phase and reread in second.
*/ */
static boost::filesystem::path tempDirectory; static boost::filesystem::path temp_directory;
static std::string TemporaryFilePattern("OSRM-%%%%-%%%%-%%%%"); static std::string TemporaryFilePattern("OSRM-%%%%-%%%%-%%%%");
class TemporaryStorage { class TemporaryStorage {
public: public:
static TemporaryStorage & GetInstance(); static TemporaryStorage & GetInstance();
virtual ~TemporaryStorage(); virtual ~TemporaryStorage();
int allocateSlot(); int AllocateSlot();
void deallocateSlot(int slotID); void DeallocateSlot(const int slot_id);
void writeToSlot(int slotID, char * pointer, std::streamsize size); void WriteToSlot(const int slot_id, char * pointer, const std::size_t size);
void readFromSlot(int slotID, char * pointer, std::streamsize size); void ReadFromSlot(const int slot_id, char * pointer, const std::size_t size);
//returns the number of free bytes //returns the number of free bytes
unsigned getFreeBytesOnTemporaryDevice(); uint64_t GetFreeBytesOnTemporaryDevice();
boost::filesystem::fstream::pos_type tell(int slotID); boost::filesystem::fstream::pos_type Tell(const int slot_id);
void seek(int slotID, boost::filesystem::fstream::pos_type); void RemoveAll();
void removeAll();
private: private:
TemporaryStorage(); TemporaryStorage();
TemporaryStorage(TemporaryStorage const &){}; TemporaryStorage(TemporaryStorage const &){};
TemporaryStorage& operator=(TemporaryStorage const &) {
TemporaryStorage & operator=(TemporaryStorage const &) {
return *this; return *this;
} }
void abort(boost::filesystem::filesystem_error& e);
void Abort(const boost::filesystem::filesystem_error& e);
void CheckIfTemporaryDeviceFull();
struct StreamData { struct StreamData {
bool writeMode; bool write_mode;
boost::filesystem::path pathToTemporaryFile; boost::filesystem::path temp_path;
boost::shared_ptr<boost::filesystem::fstream> streamToTemporaryFile; boost::shared_ptr<boost::filesystem::fstream> temp_file;
boost::shared_ptr<boost::mutex> readWriteMutex; boost::shared_ptr<boost::mutex> readWriteMutex;
std::vector<char> buffer;
StreamData() : StreamData() :
writeMode(true), write_mode(true),
pathToTemporaryFile (boost::filesystem::unique_path(tempDirectory.append(TemporaryFilePattern.begin(), TemporaryFilePattern.end()))), temp_path(
streamToTemporaryFile(new boost::filesystem::fstream(pathToTemporaryFile, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)), boost::filesystem::unique_path(
readWriteMutex(new boost::mutex) temp_directory.append(
TemporaryFilePattern.begin(),
TemporaryFilePattern.end()
)
)
),
temp_file(
new boost::filesystem::fstream(
temp_path,
std::ios::in|std::ios::out|std::ios::trunc|std::ios::binary
)
),
readWriteMutex(boost::make_shared<boost::mutex>())
{ {
if(streamToTemporaryFile->fail()) { if( temp_file->fail() ) {
throw OSRMException("temporary file could not be created"); throw OSRMException("temporary file could not be created");
} }
} }
}; };
//vector of file streams that is used to store temporary data //vector of file streams that is used to store temporary data
std::vector<StreamData> vectorOfStreamDatas;
boost::mutex mutex; boost::mutex mutex;
std::vector<StreamData> stream_data_list;
}; };
#endif /* TEMPORARYSTORAGE_H_ */ #endif /* TEMPORARYSTORAGE_H_ */
+58 -34
View File
@@ -25,14 +25,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef BINARYHEAP_H_INCLUDED #ifndef BINARY_HEAP_H
#define BINARYHEAP_H_INCLUDED #define BINARY_HEAP_H
//Not compatible with non contiguous node ids //Not compatible with non contiguous node ids
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <cassert> #include <boost/assert.hpp>
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
@@ -43,7 +43,7 @@ template< typename NodeID, typename Key >
class ArrayStorage { class ArrayStorage {
public: public:
ArrayStorage( size_t size ) : positions( new Key[size] ) { explicit ArrayStorage( size_t size ) : positions( new Key[size] ) {
memset(positions, 0, size*sizeof(Key)); memset(positions, 0, size*sizeof(Key));
} }
@@ -65,7 +65,7 @@ template< typename NodeID, typename Key >
class MapStorage { class MapStorage {
public: public:
MapStorage( size_t ) {} explicit MapStorage( size_t ) {}
Key &operator[]( NodeID node ) { Key &operator[]( NodeID node ) {
return nodes[node]; return nodes[node];
@@ -82,15 +82,23 @@ private:
template< typename NodeID, typename Key > template< typename NodeID, typename Key >
class UnorderedMapStorage { class UnorderedMapStorage {
typedef boost::unordered_map<NodeID, Key> UnorderedMapType;
typedef typename UnorderedMapType::iterator UnorderedMapIterator;
typedef typename UnorderedMapType::const_iterator UnorderedMapConstIterator;
public: public:
UnorderedMapStorage( size_t ) { explicit UnorderedMapStorage( size_t ) {
//hash table gets 1000 Buckets //hash table gets 1000 Buckets
nodes.rehash(1000); nodes.rehash(1000);
} }
Key &operator[]( const NodeID node ) { Key & operator[]( const NodeID node ) {
return nodes[node]; return nodes[node];
}
Key const & operator[]( const NodeID node ) const {
UnorderedMapConstIterator iter = nodes.find(node);
return iter->second;
} }
void Clear() { void Clear() {
@@ -101,13 +109,13 @@ private:
boost::unordered_map< NodeID, Key > nodes; boost::unordered_map< NodeID, Key > nodes;
}; };
template<typename NodeID = unsigned> template<
struct _SimpleHeapData { typename NodeID,
NodeID parent; typename Key,
_SimpleHeapData( NodeID p ) : parent(p) { } typename Weight,
}; typename Data,
typename IndexStorage = ArrayStorage<NodeID, NodeID>
template < typename NodeID, typename Key, typename Weight, typename Data, typename IndexStorage = ArrayStorage<NodeID, NodeID> > >
class BinaryHeap { class BinaryHeap {
private: private:
BinaryHeap( const BinaryHeap& right ); BinaryHeap( const BinaryHeap& right );
@@ -116,8 +124,10 @@ public:
typedef Weight WeightType; typedef Weight WeightType;
typedef Data DataType; typedef Data DataType;
BinaryHeap( size_t maxID ) explicit BinaryHeap( size_t maxID )
: nodeIndex( maxID ) { :
nodeIndex( maxID )
{
Clear(); Clear();
} }
@@ -132,6 +142,10 @@ public:
return static_cast<Key>( heap.size() - 1 ); return static_cast<Key>( heap.size() - 1 );
} }
bool Empty() const {
return 0 == Size();
}
void Insert( NodeID node, Weight weight, const Data &data ) { void Insert( NodeID node, Weight weight, const Data &data ) {
HeapElement element; HeapElement element;
element.index = static_cast<NodeID>(insertedNodes.size()); element.index = static_cast<NodeID>(insertedNodes.size());
@@ -149,13 +163,18 @@ public:
return insertedNodes[index].data; return insertedNodes[index].data;
} }
Data const & GetData( NodeID node ) const {
const Key index = nodeIndex[node];
return insertedNodes[index].data;
}
Weight& GetKey( NodeID node ) { Weight& GetKey( NodeID node ) {
const Key index = nodeIndex[node]; const Key index = nodeIndex[node];
return insertedNodes[index].weight; return insertedNodes[index].weight;
} }
bool WasRemoved( const NodeID node ) { bool WasRemoved( const NodeID node ) {
assert( WasInserted( node ) ); BOOST_ASSERT( WasInserted( node ) );
const Key index = nodeIndex[node]; const Key index = nodeIndex[node];
return insertedNodes[index].key == 0; return insertedNodes[index].key == 0;
} }
@@ -168,12 +187,12 @@ public:
} }
NodeID Min() const { NodeID Min() const {
assert( heap.size() > 1 ); BOOST_ASSERT( heap.size() > 1 );
return insertedNodes[heap[1].index].node; return insertedNodes[heap[1].index].node;
} }
NodeID DeleteMin() { NodeID DeleteMin() {
assert( heap.size() > 1 ); BOOST_ASSERT( heap.size() > 1 );
const Key removedIndex = heap[1].index; const Key removedIndex = heap[1].index;
heap[1] = heap[heap.size()-1]; heap[1] = heap[heap.size()-1];
heap.pop_back(); heap.pop_back();
@@ -192,10 +211,10 @@ public:
} }
void DecreaseKey( NodeID node, Weight weight ) { void DecreaseKey( NodeID node, Weight weight ) {
assert( UINT_MAX != node ); BOOST_ASSERT( UINT_MAX != node );
const Key & index = nodeIndex[node]; const Key & index = nodeIndex[node];
Key & key = insertedNodes[index].key; Key & key = insertedNodes[index].key;
assert ( key >= 0 ); BOOST_ASSERT ( key >= 0 );
insertedNodes[index].weight = weight; insertedNodes[index].weight = weight;
heap[key].weight = weight; heap[key].weight = weight;
@@ -206,11 +225,13 @@ public:
private: private:
class HeapNode { class HeapNode {
public: public:
HeapNode() {
}
HeapNode( NodeID n, Key k, Weight w, Data d ) HeapNode( NodeID n, Key k, Weight w, Data d )
: node( n ), key( k ), weight( w ), data( d ) { :
} node(n),
key(k),
weight(w),
data(d)
{ }
NodeID node; NodeID node;
Key key; Key key;
@@ -230,14 +251,17 @@ private:
const Key droppingIndex = heap[key].index; const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight; const Weight weight = heap[key].weight;
Key nextKey = key << 1; Key nextKey = key << 1;
while ( nextKey < static_cast<Key>( heap.size() ) ) { while( nextKey < static_cast<Key>( heap.size() ) ){
const Key nextKeyOther = nextKey + 1; const Key nextKeyOther = nextKey + 1;
if ( ( nextKeyOther < static_cast<Key> ( heap.size() ) )&& ( heap[nextKey].weight > heap[nextKeyOther].weight) ) if (
( nextKeyOther < static_cast<Key>( heap.size() ) ) &&
( heap[nextKey].weight > heap[nextKeyOther].weight )
) {
nextKey = nextKeyOther; nextKey = nextKeyOther;
}
if ( weight <= heap[nextKey].weight ) if ( weight <= heap[nextKey].weight ){
break; break;
}
heap[key] = heap[nextKey]; heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key; insertedNodes[heap[key].index].key = key;
key = nextKey; key = nextKey;
@@ -253,7 +277,7 @@ private:
const Weight weight = heap[key].weight; const Weight weight = heap[key].weight;
Key nextKey = key >> 1; Key nextKey = key >> 1;
while ( heap[nextKey].weight > weight ) { while ( heap[nextKey].weight > weight ) {
assert( nextKey != 0 ); BOOST_ASSERT( nextKey != 0 );
heap[key] = heap[nextKey]; heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key; insertedNodes[heap[key].index].key = key;
key = nextKey; key = nextKey;
@@ -267,10 +291,10 @@ private:
void CheckHeap() { void CheckHeap() {
#ifndef NDEBUG #ifndef NDEBUG
for ( Key i = 2; i < (Key) heap.size(); ++i ) { 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 #endif
} }
}; };
#endif //#ifndef BINARYHEAP_H_INCLUDED #endif //BINARY_HEAP_H
+1 -1
View File
@@ -40,7 +40,7 @@ template<typename Data>
class ConcurrentQueue { class ConcurrentQueue {
public: public:
ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { } explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { }
inline void push(const Data & data) { inline void push(const Data & data) {
boost::mutex::scoped_lock lock(m_mutex); boost::mutex::scoped_lock lock(m_mutex);
+183
View File
@@ -0,0 +1,183 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osrm/Coordinate.h>
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include <boost/assert.hpp>
#ifndef NDEBUG
#include <bitset>
#endif
#include <iostream>
#include <limits>
FixedPointCoordinate::FixedPointCoordinate()
: lat(std::numeric_limits<int>::min()),
lon(std::numeric_limits<int>::min())
{ }
FixedPointCoordinate::FixedPointCoordinate(int lat, int lon)
: lat(lat),
lon(lon)
{
#ifndef NDEBUG
if(0 != (std::abs(lat) >> 30))
{
std::bitset<32> y(lat);
SimpleLogger().Write(logDEBUG) << "broken lat: " << lat << ", bits: " << y;
}
if(0 != (std::abs(lon) >> 30))
{
std::bitset<32> x(lon);
SimpleLogger().Write(logDEBUG) << "broken lon: " << lon << ", bits: " << x;
}
#endif
}
void FixedPointCoordinate::Reset() {
lat = std::numeric_limits<int>::min();
lon = std::numeric_limits<int>::min();
}
bool FixedPointCoordinate::isSet() const {
return (std::numeric_limits<int>::min() != lat) &&
(std::numeric_limits<int>::min() != lon);
}
bool FixedPointCoordinate::isValid() const {
if (lat > 90*COORDINATE_PRECISION ||
lat < -90*COORDINATE_PRECISION ||
lon > 180*COORDINATE_PRECISION ||
lon < -180*COORDINATE_PRECISION)
{
return false;
}
return true;
}
bool FixedPointCoordinate::operator==(const FixedPointCoordinate & other) const {
return lat == other.lat && lon == other.lon;
}
double FixedPointCoordinate::ApproximateDistance(
const int lat1,
const int lon1,
const int lat2,
const int lon2
) {
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1/COORDINATE_PRECISION;
double ln1 = lon1/COORDINATE_PRECISION;
double lt2 = lat2/COORDINATE_PRECISION;
double ln2 = lon2/COORDINATE_PRECISION;
double dlat1=lt1*(RAD);
double dlong1=ln1*(RAD);
double dlat2=lt2*(RAD);
double dlong2=ln2*(RAD);
double dLong=dlong1-dlong2;
double dLat=dlat1-dlat2;
double aHarv= pow(sin(dLat/2.0),2.0)+cos(dlat1)*cos(dlat2)*pow(sin(dLong/2.),2);
double cHarv=2.*atan2(sqrt(aHarv),sqrt(1.0-aHarv));
//earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
//The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
const double earth=6372797.560856;
return earth*cHarv;
}
double FixedPointCoordinate::ApproximateDistance(
const FixedPointCoordinate &c1,
const FixedPointCoordinate &c2
) {
return ApproximateDistance(c1.lat, c1.lon, c2.lat, c2.lon);
}
double FixedPointCoordinate::ApproximateEuclideanDistance(
const FixedPointCoordinate &c1,
const FixedPointCoordinate &c2
) {
BOOST_ASSERT(c1.lat != std::numeric_limits<int>::min());
BOOST_ASSERT(c1.lon != std::numeric_limits<int>::min());
BOOST_ASSERT(c2.lat != std::numeric_limits<int>::min());
BOOST_ASSERT(c2.lon != std::numeric_limits<int>::min());
const double RAD = 0.017453292519943295769236907684886;
const double lat1 = (c1.lat/COORDINATE_PRECISION)*RAD;
const double lon1 = (c1.lon/COORDINATE_PRECISION)*RAD;
const double lat2 = (c2.lat/COORDINATE_PRECISION)*RAD;
const double lon2 = (c2.lon/COORDINATE_PRECISION)*RAD;
const double x = (lon2-lon1) * cos((lat1+lat2)/2.);
const double y = (lat2-lat1);
const double earthRadius = 6372797.560856;
return sqrt(x*x + y*y) * earthRadius;
}
void FixedPointCoordinate::convertInternalLatLonToString(
const int value,
std::string & output
) {
char buffer[100];
buffer[11] = 0; // zero termination
char* string = printInt< 11, 6 >( buffer, value );
output = string;
}
void FixedPointCoordinate::convertInternalCoordinateToString(
const FixedPointCoordinate & coord,
std::string & output
) {
std::string tmp;
tmp.reserve(23);
convertInternalLatLonToString(coord.lon, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lat, tmp);
output += tmp;
}
void FixedPointCoordinate::convertInternalReversedCoordinateToString(
const FixedPointCoordinate & coord,
std::string & output
) {
std::string tmp;
tmp.reserve(23);
convertInternalLatLonToString(coord.lat, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
}
void FixedPointCoordinate::Output(std::ostream & out) const
{
out << "(" << lat/COORDINATE_PRECISION << "," << lon/COORDINATE_PRECISION << ")";
}
-170
View File
@@ -1,170 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_POINT_COORDINATE_H_
#define FIXED_POINT_COORDINATE_H_
#include "../DataStructures/MercatorUtil.h"
#include "../Util/StringUtil.h"
#include <cassert>
#include <cmath>
#include <climits>
#include <iostream>
static const double COORDINATE_PRECISION = 1000000.;
struct FixedPointCoordinate {
int lat;
int lon;
FixedPointCoordinate () : lat(INT_MIN), lon(INT_MIN) {}
explicit FixedPointCoordinate (int lat, int lon) : lat(lat) , lon(lon) {}
void Reset() {
lat = INT_MIN;
lon = INT_MIN;
}
bool isSet() const {
return (INT_MIN != lat) && (INT_MIN != lon);
}
inline bool isValid() const {
if(
lat > 90*COORDINATE_PRECISION ||
lat < -90*COORDINATE_PRECISION ||
lon > 180*COORDINATE_PRECISION ||
lon < -180*COORDINATE_PRECISION
) {
return false;
}
return true;
}
bool operator==(const FixedPointCoordinate & other) const {
return lat == other.lat && lon == other.lon;
}
};
inline std::ostream & operator<<(std::ostream & out, const FixedPointCoordinate & c){
out << "(" << c.lat << "," << c.lon << ")";
return out;
}
inline double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ) {
assert(lat1 != INT_MIN);
assert(lon1 != INT_MIN);
assert(lat2 != INT_MIN);
assert(lon2 != INT_MIN);
double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1/COORDINATE_PRECISION;
double ln1 = lon1/COORDINATE_PRECISION;
double lt2 = lat2/COORDINATE_PRECISION;
double ln2 = lon2/COORDINATE_PRECISION;
double dlat1=lt1*(RAD);
double dlong1=ln1*(RAD);
double dlat2=lt2*(RAD);
double dlong2=ln2*(RAD);
double dLong=dlong1-dlong2;
double dLat=dlat1-dlat2;
double aHarv= pow(sin(dLat/2.0),2.0)+cos(dlat1)*cos(dlat2)*pow(sin(dLong/2.),2);
double cHarv=2.*atan2(sqrt(aHarv),sqrt(1.0-aHarv));
//earth's radius from wikipedia varies between 6,356.750 km — 6,378.135 km (˜3,949.901 — 3,963.189 miles)
//The IUGG value for the equatorial radius of the Earth is 6378.137 km (3963.19 mile)
const double earth=6372797.560856;//I am doing miles, just change this to radius in kilometers to get distances in km
double distance=earth*cHarv;
return distance;
}
inline double ApproximateDistance(const FixedPointCoordinate &c1, const FixedPointCoordinate &c2) {
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
}
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);
const double RAD = 0.017453292519943295769236907684886;
const double lat1 = (c1.lat/COORDINATE_PRECISION)*RAD;
const double lon1 = (c1.lon/COORDINATE_PRECISION)*RAD;
const double lat2 = (c2.lat/COORDINATE_PRECISION)*RAD;
const double lon2 = (c2.lon/COORDINATE_PRECISION)*RAD;
const double x = (lon2-lon1) * cos((lat1+lat2)/2.);
const double y = (lat2-lat1);
const double earthRadius = 6372797.560856;
const double d = sqrt(x*x + y*y) * earthRadius;
return d;
}
static inline void convertInternalLatLonToString(const int value, std::string & output) {
char buffer[100];
buffer[11] = 0; // zero termination
char* string = printInt< 11, 6 >( buffer, value );
output = string;
}
static inline void convertInternalCoordinateToString(const FixedPointCoordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lon, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lat, tmp);
output += tmp;
output += " ";
}
static inline void convertInternalReversedCoordinateToString(const FixedPointCoordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lat, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
output += " ";
}
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
template<class CoordinateT>
static inline double GetAngleBetweenThreeFixedPointCoordinates (
const CoordinateT & A,
const CoordinateT & C,
const CoordinateT & B
) {
const double v1x = (A.lon - C.lon)/COORDINATE_PRECISION;
const double v1y = lat2y(A.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
const double v2x = (B.lon - C.lon)/COORDINATE_PRECISION;
const double v2y = lat2y(B.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
while(angle < 0)
angle += 360;
return angle;
}
#endif /* FIXED_POINT_COORDINATE_H_ */
+52 -54
View File
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef DEALLOCATINGVECTOR_H_ #ifndef DEALLOCATINGVECTOR_H_
#define DEALLOCATINGVECTOR_H_ #define DEALLOCATINGVECTOR_H_
#include <cassert> #include <boost/assert.hpp>
#include <cstring> #include <cstring>
#include <vector> #include <vector>
@@ -48,45 +48,32 @@ protected:
//make constructors explicit, so we do not mix random access and deallocation iterators. //make constructors explicit, so we do not mix random access and deallocation iterators.
DeallocatingVectorIteratorState(); DeallocatingVectorIteratorState();
public: public:
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r) : mData(r.mData), mIndex(r.mIndex), mBucketList(r.mBucketList) {} 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) {
explicit DeallocatingVectorIteratorState(const std::size_t idx, std::vector<ElementT *> & input_list) : mData(DEALLOCATION_VECTOR_NULL_PTR), mIndex(idx), mBucketList(input_list) {
setPointerForIndex();
} }
ElementT * mData;
std::size_t mIndex; std::size_t mIndex;
std::vector<ElementT *> & mBucketList; 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) { 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) { 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; 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 //This is a hack to make assignment operator possible with reference member
inline DeallocatingVectorIteratorState& operator= (const DeallocatingVectorIteratorState &a) { inline DeallocatingVectorIteratorState& operator= (const DeallocatingVectorIteratorState &a) {
if (this != &a) { if (this != &a) {
@@ -109,69 +96,72 @@ public:
DeallocatingVectorIterator() {} DeallocatingVectorIterator() {}
template<typename T2> template<typename T2>
DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> & r) : mState(r.mState) {} explicit 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, std::vector<ElementT *> & input_list) : mState(idx, input_list) {}
//DeallocatingVectorIterator(std::size_t idx, const std::vector<ElementT *> & input_list) : mState(idx, input_list) {} explicit DeallocatingVectorIterator(const DeallocatingVectorIteratorState & r) : mState(r) {}
DeallocatingVectorIterator(const DeallocatingVectorIteratorState & r) : mState(r) {}
template<typename T2> template<typename T2>
DeallocatingVectorIterator& operator=(const DeallocatingVectorIterator<T2> &r) { DeallocatingVectorIterator& operator=(const DeallocatingVectorIterator<T2> &r) {
if(DeallocateC) assert(false); if(DeallocateC) BOOST_ASSERT(false);
mState = r.mState; return *this; mState = r.mState; return *this;
} }
inline DeallocatingVectorIterator& operator++() { //prefix inline DeallocatingVectorIterator& operator++() { //prefix
// if(DeallocateC) assert(false); ++mState.mIndex;
++mState.mIndex; mState.setPointerForIndex(); return *this; return *this;
} }
inline DeallocatingVectorIterator& operator--() { //prefix inline DeallocatingVectorIterator& operator--() { //prefix
if(DeallocateC) assert(false); if(DeallocateC) BOOST_ASSERT(false);
--mState.mIndex; mState.setPointerForIndex(); return *this; --mState.mIndex;
return *this;
} }
inline DeallocatingVectorIterator operator++(int) { //postfix inline DeallocatingVectorIterator operator++(int) { //postfix
DeallocatingVectorIteratorState _myState(mState); DeallocatingVectorIteratorState _myState(mState);
mState.mIndex++; mState.setPointerForIndex(); mState.mIndex++;
return DeallocatingVectorIterator(_myState); return DeallocatingVectorIterator(_myState);
} }
inline DeallocatingVectorIterator operator --(int) { //postfix inline DeallocatingVectorIterator operator--(int) { //postfix
if(DeallocateC) assert(false); if(DeallocateC) BOOST_ASSERT(false);
DeallocatingVectorIteratorState _myState(mState); DeallocatingVectorIteratorState _myState(mState);
mState.mIndex--; mState.setPointerForIndex(); mState.mIndex--;
return DeallocatingVectorIterator(_myState); return DeallocatingVectorIterator(_myState);
} }
inline DeallocatingVectorIterator operator+(const difference_type& n) const { inline DeallocatingVectorIterator operator+(const difference_type& n) const {
DeallocatingVectorIteratorState _myState(mState); DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex+=n; _myState.setPointerForIndex(); _myState.mIndex+=n;
return DeallocatingVectorIterator(_myState); return DeallocatingVectorIterator(_myState);
} }
inline DeallocatingVectorIterator& operator+=(const difference_type& n) const { inline DeallocatingVectorIterator& operator+=(const difference_type& n) {
mState.mIndex+=n; return *this; mState.mIndex+=n; return *this;
} }
inline DeallocatingVectorIterator operator-(const difference_type& n) const { inline DeallocatingVectorIterator operator-(const difference_type& n) const {
if(DeallocateC) assert(false); if(DeallocateC) BOOST_ASSERT(false);
DeallocatingVectorIteratorState _myState(mState); DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex-=n; _myState.setPointerForIndex(); _myState.mIndex-=n;
return DeallocatingVectorIterator(_myState); return DeallocatingVectorIterator(_myState);
} }
inline DeallocatingVectorIterator& operator-=(const difference_type &n) const { inline DeallocatingVectorIterator& operator-=(const difference_type &n) const {
if(DeallocateC) assert(false); if(DeallocateC) BOOST_ASSERT(false);
mState.mIndex-=n; return *this; mState.mIndex-=n; return *this;
} }
inline reference operator*() const { return *mState.mData; }
inline pointer operator->() const { return mState.mData; } inline reference operator*() const {
inline reference operator[](const difference_type &n) const { std::size_t _bucket = mState.mIndex/bucketSizeC;
if(DeallocateC) assert(false); std::size_t _index = mState.mIndex%bucketSizeC;
DeallocatingVectorIteratorState _myState(mState); return (mState.mBucketList[_bucket][_index]);
_myState.mIndex += n; }
_myState.setPointerForIndex;
return _myState.mData; 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) { inline bool operator!=(const DeallocatingVectorIterator & other) {
@@ -182,12 +172,20 @@ public:
return mState == other.mState; return mState == other.mState;
} }
bool operator<(const DeallocatingVectorIterator & other) { inline bool operator<(const DeallocatingVectorIterator & other) const {
return mState < other.mState; 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) { difference_type operator-(const DeallocatingVectorIterator & other) {
if(DeallocateC) assert(false); if(DeallocateC) BOOST_ASSERT(false);
return mState.mIndex-other.mState.mIndex; return mState.mIndex-other.mState.mIndex;
} }
}; };
+16 -9
View File
@@ -41,8 +41,8 @@ template< typename EdgeDataT>
class DynamicGraph { class DynamicGraph {
public: public:
typedef EdgeDataT EdgeData; typedef EdgeDataT EdgeData;
typedef uint32_t NodeIterator; typedef unsigned NodeIterator;
typedef uint32_t EdgeIterator; typedef unsigned EdgeIterator;
class InputEdge { class InputEdge {
public: public:
@@ -57,7 +57,7 @@ class DynamicGraph {
}; };
//Constructs an empty graph with a given number of nodes. //Constructs an empty graph with a given number of nodes.
DynamicGraph( int32_t nodes ) : m_numNodes(nodes), m_numEdges(0) { explicit DynamicGraph( int32_t nodes ) : m_numNodes(nodes), m_numEdges(0) {
m_nodes.reserve( m_numNodes ); m_nodes.reserve( m_numNodes );
m_nodes.resize( m_numNodes ); m_nodes.resize( m_numNodes );
@@ -101,15 +101,15 @@ class DynamicGraph {
~DynamicGraph(){ } ~DynamicGraph(){ }
uint32_t GetNumberOfNodes() const { unsigned GetNumberOfNodes() const {
return m_numNodes; return m_numNodes;
} }
uint32_t GetNumberOfEdges() const { unsigned GetNumberOfEdges() const {
return m_numEdges; return m_numEdges;
} }
uint32_t GetOutDegree( const NodeIterator n ) const { unsigned GetOutDegree( const NodeIterator n ) const {
return m_nodes[n].edges; return m_nodes[n].edges;
} }
@@ -117,6 +117,10 @@ class DynamicGraph {
return NodeIterator( m_edges[e].target ); return NodeIterator( m_edges[e].target );
} }
void SetTarget( const EdgeIterator e, const NodeIterator n ) {
m_edges[e].target = n;
}
EdgeDataT &GetEdgeData( const EdgeIterator e ) { EdgeDataT &GetEdgeData( const EdgeIterator e ) {
return m_edges[e].data; return m_edges[e].data;
} }
@@ -143,7 +147,7 @@ class DynamicGraph {
m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges]; m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges];
} else { } else {
EdgeIterator newFirstEdge = ( EdgeIterator ) m_edges.size(); EdgeIterator newFirstEdge = ( EdgeIterator ) m_edges.size();
uint32_t newSize = node.edges * 1.1 + 2; unsigned newSize = node.edges * 1.1 + 2;
EdgeIterator requiredCapacity = newSize + m_edges.size(); EdgeIterator requiredCapacity = newSize + m_edges.size();
EdgeIterator oldCapacity = m_edges.capacity(); EdgeIterator oldCapacity = m_edges.capacity();
if ( requiredCapacity >= oldCapacity ) { if ( requiredCapacity >= oldCapacity ) {
@@ -170,9 +174,12 @@ class DynamicGraph {
//removes an edge. Invalidates edge iterators for the source node //removes an edge. Invalidates edge iterators for the source node
void DeleteEdge( const NodeIterator source, const EdgeIterator e ) { void DeleteEdge( const NodeIterator source, const EdgeIterator e ) {
Node &node = m_nodes[source]; Node &node = m_nodes[source];
#pragma omp atomic
--m_numEdges; --m_numEdges;
--node.edges; --node.edges;
const uint32_t last = node.firstEdge + node.edges; BOOST_ASSERT(UINT_MAX != node.edges);
const unsigned last = node.firstEdge + node.edges;
BOOST_ASSERT( UINT_MAX != last);
//swap with last edge //swap with last edge
m_edges[e] = m_edges[last]; m_edges[e] = m_edges[last];
makeDummy( last ); makeDummy( last );
@@ -222,7 +229,7 @@ class DynamicGraph {
//index of the first edge //index of the first edge
EdgeIterator firstEdge; EdgeIterator firstEdge;
//amount of edges //amount of edges
uint32_t edges; unsigned edges;
}; };
struct Edge { struct Edge {
+160
View File
@@ -0,0 +1,160 @@
#ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H
#include "../Util/MercatorUtil.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <limits>
struct EdgeBasedNode {
EdgeBasedNode() :
forward_edge_based_node_id(SPECIAL_NODEID),
reverse_edge_based_node_id(SPECIAL_NODEID),
u(SPECIAL_NODEID),
v(SPECIAL_NODEID),
name_id(0),
forward_weight(INVALID_EDGE_WEIGHT >> 1),
reverse_weight(INVALID_EDGE_WEIGHT >> 1),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
belongsToTinyComponent(false)
{ }
explicit EdgeBasedNode(
NodeID forward_edge_based_node_id,
NodeID reverse_edge_based_node_id,
NodeID u,
NodeID v,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
unsigned short fwd_segment_position,
bool belongs_to_tiny_component
) :
forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id),
u(u),
v(v),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
fwd_segment_position(fwd_segment_position),
belongsToTinyComponent(belongs_to_tiny_component)
{
BOOST_ASSERT(
( forward_edge_based_node_id != SPECIAL_NODEID ) ||
( reverse_edge_based_node_id != SPECIAL_NODEID )
);
}
inline static double ComputePerpendicularDistance(
const FixedPointCoordinate & coord_a,
const FixedPointCoordinate & coord_b,
const FixedPointCoordinate & query_location,
FixedPointCoordinate & nearest_location,
double & r
) {
BOOST_ASSERT( query_location.isValid() );
const double x = lat2y(query_location.lat/COORDINATE_PRECISION);
const double y = query_location.lon/COORDINATE_PRECISION;
const double a = lat2y(coord_a.lat/COORDINATE_PRECISION);
const double b = coord_a.lon/COORDINATE_PRECISION;
const double c = lat2y(coord_b.lat/COORDINATE_PRECISION);
const double d = coord_b.lon/COORDINATE_PRECISION;
double p,q/*,mX*/,nY;
if( std::abs(a-c) > std::numeric_limits<double>::epsilon() ){
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m);
q = b + m*(p - a);
} else {
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
//discretize the result to coordinate precision. it's a hack!
if( std::abs(nY) < (1./COORDINATE_PRECISION) ) {
nY = 0.;
}
r = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if( std::isnan(r) ) {
r = ((coord_b.lat == query_location.lat) && (coord_b.lon == query_location.lon)) ? 1. : 0.;
} else if( std::abs(r) <= std::numeric_limits<double>::epsilon() ) {
r = 0.;
} else if( std::abs(r-1.) <= std::numeric_limits<double>::epsilon() ) {
r = 1.;
}
BOOST_ASSERT( !std::isnan(r) );
if( r <= 0. ){
nearest_location.lat = coord_a.lat;
nearest_location.lon = coord_a.lon;
} else if( r >= 1. ){
nearest_location.lat = coord_b.lat;
nearest_location.lon = coord_b.lon;
} else {
// point lies in between
nearest_location.lat = y2lat(p)*COORDINATE_PRECISION;
nearest_location.lon = q*COORDINATE_PRECISION;
}
BOOST_ASSERT( nearest_location.isValid() );
// TODO: Replace with euclidean approximation when k-NN search is done
// const double approximated_distance = FixedPointCoordinate::ApproximateEuclideanDistance(
const double approximated_distance = FixedPointCoordinate::ApproximateDistance(
query_location,
nearest_location
);
BOOST_ASSERT( 0. <= approximated_distance );
return approximated_distance;
}
static inline FixedPointCoordinate Centroid(
const FixedPointCoordinate & a,
const FixedPointCoordinate & b
) {
FixedPointCoordinate centroid;
//The coordinates of the midpoint are given by:
//x = (x1 + x2) /2 and y = (y1 + y2) /2.
centroid.lon = (std::min(a.lon, b.lon) + std::max(a.lon, b.lon))/2;
centroid.lat = (std::min(a.lat, b.lat) + std::max(a.lat, b.lat))/2;
return centroid;
}
bool IsCompressed() {
return packed_geometry_id != SPECIAL_EDGEID;
}
NodeID forward_edge_based_node_id; // needed for edge-expanded graph
NodeID reverse_edge_based_node_id; // needed for edge-expanded graph
NodeID u; // indices into the coordinates array
NodeID v; // indices into the coordinates array
unsigned name_id; // id of the edge name
int forward_weight; // weight of the edge
int reverse_weight; // weight in the other direction (may be different)
int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
unsigned short fwd_segment_position; // segment id in a compressed geometry
bool belongsToTinyComponent;
};
#endif //EDGE_BASED_NODE_H
+26 -20
View File
@@ -25,43 +25,49 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef HASHTABLE_H_ #ifndef HASH_TABLE_H
#define HASHTABLE_H_ #define HASH_TABLE_H
#include <boost/functional/hash.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
template<typename keyT, typename valueT> template<typename Key, typename Value, typename Hash = boost::hash<Key> >
class HashTable : public boost::unordered_map<keyT, valueT> { class HashTable : public boost::unordered_map<Key, Value> {
private: private:
typedef boost::unordered_map<keyT, valueT> super; typedef boost::unordered_map<Key, Value, Hash> super;
public: public:
static Value default_value;
HashTable() : super() { } HashTable() : super() { }
HashTable(const unsigned size) : super(size) { } explicit HashTable(const unsigned size) : super(size) { }
HashTable &operator=(const HashTable &other) { inline void Add( Key const & key, Value const & value) {
super::operator = (other); super::emplace(std::make_pair(key, value));
return *this;
} }
inline void Add(const keyT& key, const valueT& value){ inline const Value Find(Key const & key) const
super::insert(std::make_pair(key, value)); {
} typename super::const_iterator iter = super::find(key);
if (iter == super::end())
inline valueT Find(const keyT& key) const { {
if(super::find(key) == super::end()) { return boost::cref(default_value);
return valueT();
} }
return boost::ref(super::find(key)->second); return boost::cref(iter->second);
} }
inline bool Holds(const keyT& key) const { inline const bool Holds( Key const & key) const
if(super::find(key) == super::end()) { {
if(super::find(key) == super::end())
{
return false; return false;
} }
return true; return true;
} }
}; };
#endif /* HASHTABLE_H_ */ template<typename Key, typename Value, typename Hash>
Value HashTable<Key, Value, Hash>::default_value;
#endif /* HASH_TABLE_H */
+88
View File
@@ -0,0 +1,88 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "HilbertValue.h"
uint64_t HilbertCode::operator() (
const FixedPointCoordinate & current_coordinate
) const {
unsigned location[2];
location[0] = current_coordinate.lat+( 90*COORDINATE_PRECISION);
location[1] = current_coordinate.lon+(180*COORDINATE_PRECISION);
TransposeCoordinate(location);
return BitInterleaving(location[0], location[1]);
}
uint64_t HilbertCode::BitInterleaving(const uint32_t latitude, const uint32_t longitude) const
{
uint64_t result = 0;
for(int8_t index = 31; index >= 0; --index){
result |= (latitude >> index) & 1;
result <<= 1;
result |= (longitude >> index) & 1;
if(0 != index){
result <<= 1;
}
}
return result;
}
void HilbertCode::TransposeCoordinate( uint32_t * X) const
{
uint32_t M = 1 << (32-1), P, Q, t;
int i;
// Inverse undo
for( Q = M; Q > 1; Q >>= 1 ) {
P=Q-1;
for( i = 0; i < 2; ++i ) {
const bool condition = (X[i] & Q);
if( condition ) {
X[0] ^= P; // invert
} else {
t = (X[0]^X[i]) & P;
X[0] ^= t;
X[i] ^= t;
}
} // exchange
}
// Gray encode
for( i = 1; i < 2; ++i ) {
X[i] ^= X[i-1];
}
t=0;
for( Q = M; Q > 1; Q >>= 1 ) {
const bool condition = (X[2-1] & Q);
if( condition ) {
t ^= Q-1;
}
} //check if this for loop is wrong
for( i = 0; i < 2; ++i ) {
X[i] ^= t;
}
}
+8 -55
View File
@@ -28,70 +28,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef HILBERTVALUE_H_ #ifndef HILBERTVALUE_H_
#define HILBERTVALUE_H_ #define HILBERTVALUE_H_
#include "Coordinate.h" #include <osrm/Coordinate.h>
#include <boost/integer.hpp> #include <boost/integer.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
// computes a 64 bit value that corresponds to the hilbert space filling curve // computes a 64 bit value that corresponds to the hilbert space filling curve
class HilbertCode : boost::noncopyable { class HilbertCode : boost::noncopyable
{
public: public:
static uint64_t GetHilbertNumberForCoordinate( uint64_t operator()
(
const FixedPointCoordinate & current_coordinate const FixedPointCoordinate & current_coordinate
) { ) const;
unsigned location[2];
location[0] = current_coordinate.lat+( 90*COORDINATE_PRECISION);
location[1] = current_coordinate.lon+(180*COORDINATE_PRECISION);
TransposeCoordinate(location);
const uint64_t result = BitInterleaving(location[0], location[1]);
return result;
}
private: private:
static inline uint64_t BitInterleaving(const uint32_t a, const uint32_t b) { inline uint64_t BitInterleaving( const uint32_t a, const uint32_t b) const;
uint64_t result = 0; inline void TransposeCoordinate( uint32_t * X) const;
for(int8_t index = 31; index >= 0; --index){
result |= (a >> index) & 1;
result <<= 1;
result |= (b >> index) & 1;
if(0 != index){
result <<= 1;
}
}
return result;
}
static inline void TransposeCoordinate( uint32_t * X) {
uint32_t M = 1 << (32-1), P, Q, t;
int i;
// Inverse undo
for( Q = M; Q > 1; Q >>= 1 ) {
P=Q-1;
for( i = 0; i < 2; ++i ) {
if( X[i] & Q ) {
X[0] ^= P; // invert
} else {
t = (X[0]^X[i]) & P;
X[0] ^= t;
X[i] ^= t;
}
} // exchange
}
// Gray encode
for( i = 1; i < 2; ++i ) {
X[i] ^= X[i-1];
}
t=0;
for( Q = M; Q > 1; Q >>= 1 ) {
if( X[2-1] & Q ) {
t ^= Q-1;
}
} //check if this for loop is wrong
for( i = 0; i < 2; ++i ) {
X[i] ^= t;
}
}
}; };
#endif /* HILBERTVALUE_H_ */ #endif /* HILBERTVALUE_H_ */
+8 -4
View File
@@ -61,7 +61,8 @@ public:
bool ra, bool ra,
bool ig, bool ig,
bool ar, bool ar,
bool cf bool cf,
bool is_split
) : _source(s), ) : _source(s),
_target(t), _target(t),
_name(n), _name(n),
@@ -72,7 +73,8 @@ public:
_roundabout(ra), _roundabout(ra),
_ignoreInGrid(ig), _ignoreInGrid(ig),
_accessRestricted(ar), _accessRestricted(ar),
_contraFlow(cf) _contraFlow(cf),
is_split(is_split)
{ {
if(ty < 0) { if(ty < 0) {
throw OSRMException("negative edge type"); throw OSRMException("negative edge type");
@@ -93,6 +95,7 @@ public:
bool ignoreInGrid() const { return _ignoreInGrid; } bool ignoreInGrid() const { return _ignoreInGrid; }
bool isAccessRestricted() const { return _accessRestricted; } bool isAccessRestricted() const { return _accessRestricted; }
bool isContraFlow() const { return _contraFlow; } bool isContraFlow() const { return _contraFlow; }
bool IsSplit() const { return is_split; }
//TODO: names need to be fixed. //TODO: names need to be fixed.
NodeID _source; NodeID _source;
@@ -106,6 +109,7 @@ public:
bool _ignoreInGrid:1; bool _ignoreInGrid:1;
bool _accessRestricted:1; bool _accessRestricted:1;
bool _contraFlow:1; bool _contraFlow:1;
bool is_split:1;
private: private:
NodeBasedEdge() { } NodeBasedEdge() { }
@@ -129,7 +133,7 @@ public:
} }
template<class EdgeT> template<class EdgeT>
EdgeBasedEdge(const EdgeT & myEdge ) : explicit EdgeBasedEdge(const EdgeT & myEdge ) :
m_source(myEdge.source), m_source(myEdge.source),
m_target(myEdge.target), m_target(myEdge.target),
m_edgeID(myEdge.data.via), m_edgeID(myEdge.data.via),
@@ -162,7 +166,7 @@ public:
m_weight(w), m_weight(w),
m_forward(f), m_forward(f),
m_backward(b) m_backward(b)
{} { }
NodeID target() const { return m_target; } NodeID target() const { return m_target; }
NodeID source() const { return m_source; } NodeID source() const { return m_source; }
+32 -8
View File
@@ -32,24 +32,48 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
struct _Node : NodeInfo{ struct ExternalMemoryNode : NodeInfo {
_Node(int _lat, int _lon, unsigned int _id, bool _bollard, bool _trafficLight) : NodeInfo(_lat, _lon, _id), bollard(_bollard), trafficLight(_trafficLight) {} ExternalMemoryNode(
_Node() : bollard(false), trafficLight(false) {} int lat,
int lon,
unsigned int id,
bool bollard,
bool traffic_light
) :
NodeInfo(lat, lon, id),
bollard(bollard),
trafficLight(traffic_light)
{ }
static _Node min_value() { ExternalMemoryNode()
return _Node(0,0,0, false, false); :
bollard(false),
trafficLight(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 { NodeID key() const {
return id; return id;
} }
bool bollard; bool bollard;
bool trafficLight; bool trafficLight;
}; };
struct ImportNode : public _Node { struct ImportNode : public ExternalMemoryNode {
HashTable<std::string, std::string> keyVals; HashTable<std::string, std::string> keyVals;
inline void Clear() { inline void Clear() {
+6 -4
View File
@@ -29,6 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INPUTREADERFACTORY_H #ifndef INPUTREADERFACTORY_H
#define INPUTREADERFACTORY_H #define INPUTREADERFACTORY_H
#include <boost/assert.hpp>
#include <bzlib.h> #include <bzlib.h>
#include <libxml/xmlreader.h> #include <libxml/xmlreader.h>
@@ -51,21 +53,21 @@ int readFromBz2Stream( void* pointer, char* buffer, int len ) {
return read; return read;
} else if(BZ_STREAM_END == context->error) { } else if(BZ_STREAM_END == context->error) {
BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused); BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused);
if(BZ_OK != context->error) {std::cerr << "Could not BZ2_bzReadGetUnused" <<std::endl; exit(-1);}; BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused");
unusedTmp = (char*)unusedTmpVoid; unusedTmp = (char*)unusedTmpVoid;
for(int i=0;i<context->nUnused;i++) { for(int i=0;i<context->nUnused;i++) {
context->unused[i] = unusedTmp[i]; context->unused[i] = unusedTmp[i];
} }
BZ2_bzReadClose(&context->error, context->bz2); BZ2_bzReadClose(&context->error, context->bz2);
if(BZ_OK != context->error) {std::cerr << "Could not BZ2_bzReadClose" <<std::endl; exit(-1);}; BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose");
context->error = BZ_STREAM_END; // set to the stream end for next call to this function context->error = BZ_STREAM_END; // set to the stream end for next call to this function
if(0 == context->nUnused && feof(context->file)) { if(0 == context->nUnused && feof(context->file)) {
return read; return read;
} else { } else {
context->bz2 = BZ2_bzReadOpen(&context->error, context->file, 0, 0, context->unused, context->nUnused); context->bz2 = BZ2_bzReadOpen(&context->error, context->file, 0, 0, context->unused, context->nUnused);
if(NULL == context->bz2){std::cerr << "Could not open file" <<std::endl; exit(-1);}; BOOST_ASSERT_MSG(NULL != context->bz2, "Could not open file");
} }
} else { std::cerr << "Could not read bz2 file" << std::endl; exit(-1); } } else { BOOST_ASSERT_MSG(false, "Could not read bz2 file"); }
} }
return read; return read;
} }
+1 -1
View File
@@ -43,7 +43,7 @@ private:
std::list<CacheEntry> itemsInCache; std::list<CacheEntry> itemsInCache;
boost::unordered_map<KeyT, typename std::list<CacheEntry>::iterator > positionMap; boost::unordered_map<KeyT, typename std::list<CacheEntry>::iterator > positionMap;
public: public:
LRUCache(unsigned c) : capacity(c) {} explicit LRUCache(unsigned c) : capacity(c) {}
bool Holds(KeyT key) { bool Holds(KeyT key) {
if(positionMap.find(key) != positionMap.end()) { if(positionMap.find(key) != positionMap.end()) {
-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_*/
+62
View File
@@ -0,0 +1,62 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ORIGINAL_EDGE_DATA_H
#define ORIGINAL_EDGE_DATA_H
#include "TurnInstructions.h"
#include "../typedefs.h"
#include <limits>
struct OriginalEdgeData{
explicit OriginalEdgeData(
NodeID via_node,
unsigned name_id,
TurnInstruction turn_instruction,
bool compressed_geometry
) :
via_node( via_node ),
name_id( name_id ),
turn_instruction( turn_instruction ),
compressed_geometry( compressed_geometry )
{ }
OriginalEdgeData() :
via_node( std::numeric_limits<unsigned>::max() ),
name_id( std::numeric_limits<unsigned>::max() ),
turn_instruction( std::numeric_limits<unsigned char>::max() ),
compressed_geometry( false )
{ }
NodeID via_node;
unsigned name_id;
TurnInstruction turn_instruction;
bool compressed_geometry;
};
#endif //ORIGINAL_EDGE_DATA_H
+1 -1
View File
@@ -38,7 +38,7 @@ public:
* @param maxValue the value that corresponds to 100% * @param maxValue the value that corresponds to 100%
* @param step the progress is shown in steps of 'step' percent * @param step the progress is shown in steps of 'step' percent
*/ */
Percent(unsigned maxValue, unsigned step = 5) { explicit Percent(unsigned maxValue, unsigned step = 5) {
reinit(maxValue, step); reinit(maxValue, step);
} }
+117 -51
View File
@@ -28,81 +28,147 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PHANTOMNODES_H_ #ifndef PHANTOMNODES_H_
#define PHANTOMNODES_H_ #define PHANTOMNODES_H_
#include "Coordinate.h" #include <osrm/Coordinate.h>
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
struct PhantomNode { struct PhantomNode
{
PhantomNode() : PhantomNode() :
edgeBasedNode(UINT_MAX), forward_node_id(SPECIAL_NODEID),
nodeBasedEdgeNameID(UINT_MAX), reverse_node_id(SPECIAL_NODEID),
weight1(INT_MAX), name_id(std::numeric_limits<unsigned>::max()),
weight2(INT_MAX), forward_weight(INVALID_EDGE_WEIGHT),
ratio(0.) reverse_weight(INVALID_EDGE_WEIGHT),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position(0)
{ } { }
NodeID edgeBasedNode; NodeID forward_node_id;
unsigned nodeBasedEdgeNameID; NodeID reverse_node_id;
int weight1; unsigned name_id;
int weight2; int forward_weight;
double ratio; int reverse_weight;
int forward_offset;
int reverse_offset;
unsigned packed_geometry_id;
FixedPointCoordinate location; FixedPointCoordinate location;
void Reset() { unsigned short fwd_segment_position;
edgeBasedNode = UINT_MAX;
nodeBasedEdgeNameID = UINT_MAX; int GetForwardWeightPlusOffset() const
weight1 = INT_MAX; {
weight2 = INT_MAX; if (SPECIAL_NODEID == forward_node_id)
ratio = 0.; {
location.Reset(); return 0;
} }
bool isBidirected() const { const int result = (forward_offset + forward_weight);
return weight2 != INT_MAX; return result;
}
bool isValid(const unsigned numberOfNodes) const {
return location.isValid() && (edgeBasedNode < numberOfNodes) && (weight1 != INT_MAX) && (ratio >= 0.) && (ratio <= 1.) && (nodeBasedEdgeNameID != UINT_MAX);
} }
bool operator==(const PhantomNode & other) const { int GetReverseWeightPlusOffset() const
{
if (SPECIAL_NODEID == reverse_node_id)
{
return 0;
}
const int result = (reverse_offset + reverse_weight);
return result;
}
void Reset()
{
forward_node_id = SPECIAL_NODEID;
name_id = SPECIAL_NODEID;
forward_weight = INVALID_EDGE_WEIGHT;
reverse_weight = INVALID_EDGE_WEIGHT;
forward_offset = 0;
reverse_offset = 0;
location.Reset();
}
bool isBidirected() const
{
return (forward_node_id != SPECIAL_NODEID) &&
(reverse_node_id != SPECIAL_NODEID);
}
bool IsCompressed() const
{
return (forward_offset != 0) || (reverse_offset != 0);
}
bool isValid(const unsigned numberOfNodes) const
{
return
location.isValid() &&
(
(forward_node_id < numberOfNodes) ||
(reverse_node_id < numberOfNodes)
) &&
(
(forward_weight != INVALID_EDGE_WEIGHT) ||
(reverse_weight != INVALID_EDGE_WEIGHT)
) &&
(name_id != std::numeric_limits<unsigned>::max()
);
}
bool operator==(const PhantomNode & other) const
{
return location == other.location; return location == other.location;
} }
}; };
struct PhantomNodes { struct PhantomNodes
PhantomNode startPhantom; {
PhantomNode targetPhantom; PhantomNode source_phantom;
void Reset() { PhantomNode target_phantom;
startPhantom.Reset();
targetPhantom.Reset(); void Reset()
{
source_phantom.Reset();
target_phantom.Reset();
} }
bool PhantomsAreOnSameNodeBasedEdge() const { bool PhantomsAreOnSameNodeBasedEdge() const
return (startPhantom.edgeBasedNode == targetPhantom.edgeBasedNode); {
return (source_phantom.forward_node_id == target_phantom.forward_node_id);
} }
bool AtLeastOnePhantomNodeIsUINTMAX() const { bool AtLeastOnePhantomNodeIsInvalid() const
return !(startPhantom.edgeBasedNode == UINT_MAX || targetPhantom.edgeBasedNode == UINT_MAX); {
return ((source_phantom.forward_node_id == SPECIAL_NODEID) && (source_phantom.reverse_node_id == SPECIAL_NODEID)) ||
((target_phantom.forward_node_id == SPECIAL_NODEID) && (target_phantom.reverse_node_id == SPECIAL_NODEID));
} }
bool PhantomNodesHaveEqualLocation() const { bool PhantomNodesHaveEqualLocation() const
return startPhantom == targetPhantom; {
return source_phantom == target_phantom;
} }
}; };
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn){ inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn)
out << "Node1: " << pn.startPhantom.edgeBasedNode << std::endl; {
out << "Node2: " << pn.targetPhantom.edgeBasedNode << std::endl; out << "source_coord: " << pn.source_phantom.location << "\n";
out << "startCoord: " << pn.startPhantom.location << std::endl; out << "target_coord: " << pn.target_phantom.location << std::endl;
out << "targetCoord: " << pn.targetPhantom.location << std::endl;
return out; return out;
} }
inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn){ inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn)
out << "node: " << pn.edgeBasedNode << ", name: " << pn.nodeBasedEdgeNameID << ", w1: " << pn.weight1 << ", w2: " << pn.weight2 << ", ratio: " << pn.ratio << ", loc: " << pn.location; {
out << "node1: " << pn.forward_node_id << ", " <<
"node2: " << pn.reverse_node_id << ", " <<
"name: " << pn.name_id << ", " <<
"fwd-w: " << pn.forward_weight << ", " <<
"rev-w: " << pn.reverse_weight << ", " <<
"fwd-o: " << pn.forward_offset << ", " <<
"rev-o: " << pn.reverse_offset << ", " <<
"geom: " << pn.packed_geometry_id << ", " <<
"pos: " << pn.fwd_segment_position << ", " <<
"loc: " << pn.location;
return out; return out;
} }
struct NodesOfEdge {
NodeID edgeBasedNode;
double ratio;
FixedPointCoordinate projectedPoint;
};
#endif /* PHANTOMNODES_H_ */ #endif /* PHANTOMNODES_H_ */
+12 -22
View File
@@ -28,32 +28,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef QUERYEDGE_H_ #ifndef QUERYEDGE_H_
#define QUERYEDGE_H_ #define QUERYEDGE_H_
#include "TurnInstructions.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <climits>
struct OriginalEdgeData{
explicit OriginalEdgeData(
NodeID viaNode,
unsigned nameID,
TurnInstruction turnInstruction
) : viaNode(viaNode), nameID(nameID), turnInstruction(turnInstruction) {}
OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {}
NodeID viaNode;
unsigned nameID;
TurnInstruction turnInstruction;
};
struct QueryEdge { struct QueryEdge {
NodeID source; NodeID source;
NodeID target; NodeID target;
struct EdgeData { struct EdgeData {
NodeID id:31; NodeID id:31;
bool shortcut:1; bool shortcut:1;
int distance:30; int distance:30;
bool forward:1; bool forward:1;
bool backward:1; bool backward:1;
} data; } data;
bool operator<( const QueryEdge& right ) const { bool operator<( const QueryEdge& right ) const {
@@ -64,9 +49,14 @@ struct QueryEdge {
} }
bool operator== ( const QueryEdge& right ) const { bool operator== ( const QueryEdge& right ) const {
return ( source == right.source && target == right.target && data.distance == right.data.distance && return (
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward source == right.source &&
&& data.id == right.data.id target == right.target &&
data.distance == right.data.distance &&
data.shortcut == right.data.shortcut &&
data.forward == right.data.forward &&
data.backward == right.data.backward &&
data.id == right.data.id
); );
} }
}; };
+16 -14
View File
@@ -25,16 +25,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _NODE_COORDS_H #ifndef QUERY_NODE_H
#define _NODE_COORDS_H #define QUERY_NODE_H
#include "Coordinate.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/assert.hpp> #include <osrm/Coordinate.h>
#include <cstddef> #include <boost/assert.hpp>
#include <climits>
#include <limits> #include <limits>
@@ -42,8 +40,14 @@ struct NodeInfo {
typedef NodeID key_type; //type of NodeID typedef NodeID key_type; //type of NodeID
typedef int value_type; //type of lat,lons typedef int value_type; //type of lat,lons
NodeInfo(int _lat, int _lon, NodeID _id) : lat(_lat), lon(_lon), id(_id) {} NodeInfo(int lat, int lon, NodeID id) : lat(lat), lon(lon), id(id) { }
NodeInfo() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {} NodeInfo()
:
lat(std::numeric_limits<int>::max()),
lon(std::numeric_limits<int>::max()),
id(std::numeric_limits<unsigned>::max())
{ }
int lat; int lat;
int lon; int lon;
NodeID id; NodeID id;
@@ -68,18 +72,16 @@ struct NodeInfo {
switch(n) { switch(n) {
case 1: case 1:
return lat; return lat;
break; // break;
case 0: case 0:
return lon; return lon;
break; // break;
default: default:
BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX;
break; break;
} }
BOOST_ASSERT_MSG(false, "should not happen"); BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX; return std::numeric_limits<unsigned>::max();
} }
}; };
#endif //_NODE_COORDS_H #endif //QUERY_NODE_H
+40 -7
View File
@@ -28,29 +28,62 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RAWROUTEDATA_H_ #ifndef RAWROUTEDATA_H_
#define RAWROUTEDATA_H_ #define RAWROUTEDATA_H_
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/PhantomNodes.h" #include "../DataStructures/PhantomNodes.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <limits>
#include <vector> #include <vector>
struct _PathData { struct PathData {
_PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { } PathData() :
node(UINT_MAX),
name_id(UINT_MAX),
durationOfSegment(UINT_MAX),
turnInstruction(UCHAR_MAX)
{ }
PathData(
NodeID no,
unsigned na,
unsigned tu,
unsigned dur
) :
node(no),
name_id(na),
durationOfSegment(dur),
turnInstruction(tu)
{ }
NodeID node; NodeID node;
unsigned nameID; unsigned name_id;
unsigned durationOfSegment; unsigned durationOfSegment;
short turnInstruction; short turnInstruction;
}; };
struct RawRouteData { struct RawRouteData {
std::vector< _PathData > computedShortestPath; std::vector< std::vector<PathData> > unpacked_path_segments;
std::vector< _PathData > computedAlternativePath; std::vector< PathData > unpacked_alternative;
std::vector< PhantomNodes > segmentEndCoordinates; std::vector< PhantomNodes > segmentEndCoordinates;
std::vector< FixedPointCoordinate > rawViaNodeCoordinates; std::vector< FixedPointCoordinate > rawViaNodeCoordinates;
unsigned checkSum; unsigned checkSum;
int lengthOfShortestPath; int lengthOfShortestPath;
int lengthOfAlternativePath; int lengthOfAlternativePath;
RawRouteData() : checkSum(UINT_MAX), lengthOfShortestPath(INT_MAX), lengthOfAlternativePath(INT_MAX) {} bool source_traversed_in_reverse;
bool target_traversed_in_reverse;
bool alt_source_traversed_in_reverse;
bool alt_target_traversed_in_reverse;
RawRouteData() :
checkSum(UINT_MAX),
lengthOfShortestPath(INT_MAX),
lengthOfAlternativePath(INT_MAX),
source_traversed_in_reverse(false),
target_traversed_in_reverse(false),
alt_source_traversed_in_reverse(false),
alt_target_traversed_in_reverse(false)
{ }
}; };
#endif /* RAWROUTEDATA_H_ */ #endif /* RAWROUTEDATA_H_ */
+42 -31
View File
@@ -29,7 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define RESTRICTION_H_ #define RESTRICTION_H_
#include "../typedefs.h" #include "../typedefs.h"
#include <climits>
#include <limits>
struct TurnRestriction { struct TurnRestriction {
NodeID viaNode; NodeID viaNode;
@@ -58,14 +59,13 @@ struct TurnRestriction {
bool unused7:1; bool unused7:1;
} flags; } flags;
TurnRestriction(NodeID viaNode) : explicit TurnRestriction(NodeID viaNode) :
viaNode(viaNode), viaNode(viaNode),
fromNode(UINT_MAX), fromNode(std::numeric_limits<unsigned>::max()),
toNode(UINT_MAX) { toNode(std::numeric_limits<unsigned>::max()) {
} }
TurnRestriction(const bool isOnly = false) : explicit TurnRestriction(const bool isOnly = false) :
viaNode(UINT_MAX), viaNode(UINT_MAX),
fromNode(UINT_MAX), fromNode(UINT_MAX),
toNode(UINT_MAX) { toNode(UINT_MAX) {
@@ -73,13 +73,13 @@ struct TurnRestriction {
} }
}; };
struct _RawRestrictionContainer { struct InputRestrictionContainer {
TurnRestriction restriction;
EdgeID fromWay; EdgeID fromWay;
EdgeID toWay; EdgeID toWay;
unsigned viaNode; unsigned viaNode;
TurnRestriction restriction;
_RawRestrictionContainer( InputRestrictionContainer(
EdgeID fromWay, EdgeID fromWay,
EdgeID toWay, EdgeID toWay,
NodeID vn, NodeID vn,
@@ -91,47 +91,58 @@ struct _RawRestrictionContainer {
{ {
restriction.viaNode = vn; restriction.viaNode = vn;
} }
_RawRestrictionContainer( explicit InputRestrictionContainer(
bool isOnly = false bool isOnly = false
) : ) :
fromWay(UINT_MAX), fromWay(std::numeric_limits<unsigned>::max()),
toWay(UINT_MAX), toWay(std::numeric_limits<unsigned>::max()),
viaNode(UINT_MAX) viaNode(std::numeric_limits<unsigned>::max())
{ {
restriction.flags.isOnly = isOnly; restriction.flags.isOnly = isOnly;
} }
static _RawRestrictionContainer min_value() { static InputRestrictionContainer min_value() {
return _RawRestrictionContainer(0, 0, 0, 0); return InputRestrictionContainer(0, 0, 0, 0);
} }
static _RawRestrictionContainer max_value() { static InputRestrictionContainer max_value() {
return _RawRestrictionContainer(UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX); return InputRestrictionContainer(
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max()
);
} }
}; };
struct CmpRestrictionContainerByFrom : public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> { struct CmpRestrictionContainerByFrom {
typedef _RawRestrictionContainer value_type; typedef InputRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const { inline bool operator()(
const InputRestrictionContainer & a,
const InputRestrictionContainer & b
) const {
return a.fromWay < b.fromWay; return a.fromWay < b.fromWay;
} }
value_type max_value() { inline value_type max_value() const {
return _RawRestrictionContainer::max_value(); return InputRestrictionContainer::max_value();
} }
value_type min_value() { inline value_type min_value() const {
return _RawRestrictionContainer::min_value(); return InputRestrictionContainer::min_value();
} }
}; };
struct CmpRestrictionContainerByTo: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> { struct CmpRestrictionContainerByTo {
typedef _RawRestrictionContainer value_type; typedef InputRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const { inline bool operator()(
const InputRestrictionContainer & a,
const InputRestrictionContainer & b
) const {
return a.toWay < b.toWay; return a.toWay < b.toWay;
} }
value_type max_value() { value_type max_value() const {
return _RawRestrictionContainer::max_value(); return InputRestrictionContainer::max_value();
} }
value_type min_value() { value_type min_value() const {
return _RawRestrictionContainer::min_value(); 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;
+20 -24
View File
@@ -25,48 +25,44 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SEARCHENGINE_H_ #ifndef SEARCHENGINE_H
#define SEARCHENGINE_H_ #define SEARCHENGINE_H
#include "Coordinate.h" #include "SearchEngineData.h"
#include "NodeInformationHelpDesk.h"
#include "PhantomNodes.h" #include "PhantomNodes.h"
#include "QueryEdge.h" #include "QueryEdge.h"
#include "SearchEngineData.h"
#include "../RoutingAlgorithms/AlternativePathRouting.h" #include "../RoutingAlgorithms/AlternativePathRouting.h"
#include "../RoutingAlgorithms/ShortestPathRouting.h" #include "../RoutingAlgorithms/ShortestPathRouting.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <climits> #include <climits>
#include <string> #include <string>
#include <vector> #include <vector>
template<class DataFacadeT>
class SearchEngine { class SearchEngine {
private: private:
SearchEngineData _queryData; DataFacadeT * facade;
SearchEngineData engine_working_data;
public: public:
ShortestPathRouting<SearchEngineData> shortestPath; ShortestPathRouting<DataFacadeT> shortest_path;
AlternativeRouting<SearchEngineData> alternativePaths; AlternativeRouting <DataFacadeT> alternative_path;
SearchEngine( QueryObjectsStorage * query_objects ); explicit SearchEngine( DataFacadeT * facade )
~SearchEngine(); :
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
+45 -21
View File
@@ -27,41 +27,65 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "SearchEngineData.h" #include "SearchEngineData.h"
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage() { void SearchEngineData::InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes)
if(!forwardHeap.get()) { {
forwardHeap.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes())); if (forwardHeap.get())
} else { {
forwardHeap->Clear(); forwardHeap->Clear();
} }
if(!backwardHeap.get()) { else
backwardHeap.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes())); {
} else { forwardHeap.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap.get())
{
backwardHeap->Clear(); backwardHeap->Clear();
} }
else
{
backwardHeap.reset(new QueryHeap(number_of_nodes));
}
} }
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage() { void SearchEngineData::InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes)
if(!forwardHeap2.get()) { {
forwardHeap2.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes())); if (forwardHeap2.get())
} else { {
forwardHeap2->Clear(); forwardHeap2->Clear();
} }
if(!backwardHeap2.get()) { else
backwardHeap2.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes())); {
} else { forwardHeap2.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap2.get())
{
backwardHeap2->Clear(); backwardHeap2->Clear();
} }
else
{
backwardHeap2.reset(new QueryHeap(number_of_nodes));
}
} }
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage() { void SearchEngineData::InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes)
if(!forwardHeap3.get()) { {
forwardHeap3.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes())); if (forwardHeap3.get())
} else { {
forwardHeap3->Clear(); forwardHeap3->Clear();
} }
if(!backwardHeap3.get()) { else
backwardHeap3.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes())); {
} else { forwardHeap3.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap3.get())
{
backwardHeap3->Clear(); backwardHeap3->Clear();
} }
else
{
backwardHeap3.reset(new QueryHeap(number_of_nodes));
}
} }
+13 -20
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 "BinaryHeap.h"
#include "QueryEdge.h" #include "QueryEdge.h"
#include "StaticGraph.h" #include "StaticGraph.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../typedefs.h" #include "../typedefs.h"
@@ -39,25 +41,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct _HeapData { struct _HeapData {
NodeID parent; NodeID parent;
_HeapData( NodeID p ) : parent(p) { } /* explicit */ _HeapData( NodeID p ) : parent(p) { }
}; };
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
typedef BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> > QueryHeapType; // typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
typedef boost::thread_specific_ptr<QueryHeapType> SearchEngineHeapPtr;
struct SearchEngineData { struct SearchEngineData {
typedef QueryGraph Graph; typedef BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> > QueryHeap;
typedef QueryHeapType QueryHeap; typedef boost::thread_specific_ptr<QueryHeap> SearchEngineHeapPtr;
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;
static SearchEngineHeapPtr forwardHeap; static SearchEngineHeapPtr forwardHeap;
static SearchEngineHeapPtr backwardHeap; static SearchEngineHeapPtr backwardHeap;
@@ -66,9 +57,11 @@ struct SearchEngineData {
static SearchEngineHeapPtr forwardHeap3; static SearchEngineHeapPtr forwardHeap3;
static SearchEngineHeapPtr backwardHeap3; 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
+40 -10
View File
@@ -28,24 +28,54 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SEGMENTINFORMATION_H_ #ifndef SEGMENTINFORMATION_H_
#define SEGMENTINFORMATION_H_ #define SEGMENTINFORMATION_H_
#include "Coordinate.h"
#include "TurnInstructions.h" #include "TurnInstructions.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <climits> #include <osrm/Coordinate.h>
// Struct fits everything in one cache line
struct SegmentInformation { struct SegmentInformation {
FixedPointCoordinate location; FixedPointCoordinate location;
NodeID nameID; NodeID name_id;
double length;
unsigned duration; unsigned duration;
double bearing; double length;
TurnInstruction turnInstruction; short bearing; //more than enough [0..3600] fits into 12 bits
TurnInstruction turn_instruction;
bool necessary; bool necessary;
SegmentInformation(const FixedPointCoordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec) {} explicit SegmentInformation(
SegmentInformation(const FixedPointCoordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr) : const FixedPointCoordinate & location,
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {} const NodeID name_id,
const unsigned duration,
const double length,
const TurnInstruction turn_instruction,
const bool necessary
) :
location(location),
name_id(name_id),
duration(duration),
length(length),
bearing(0),
turn_instruction(turn_instruction),
necessary(necessary)
{ }
explicit SegmentInformation(
const FixedPointCoordinate & location,
const NodeID name_id,
const unsigned duration,
const double length,
const TurnInstruction turn_instruction
) :
location(location),
name_id(name_id),
duration(duration),
length(length),
bearing(0),
turn_instruction(turn_instruction),
necessary(turn_instruction != 0)
{ }
}; };
#endif /* SEGMENTINFORMATION_H_ */ #endif /* SEGMENTINFORMATION_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 */
+197
View File
@@ -0,0 +1,197 @@
/*
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:
explicit ShMemIterator(DataT * x) : p(x) {}
ShMemIterator(const ShMemIterator & mit) : p(mit.p) {}
ShMemIterator& operator++() {
++p;
return *this;
}
ShMemIterator operator++(int) {
ShMemIterator tmp(*this);
operator++();
return tmp;
}
ShMemIterator operator+(std::ptrdiff_t diff) {
ShMemIterator tmp(p+diff);
return tmp;
}
bool operator==(const ShMemIterator& rhs) {
return p==rhs.p;
}
bool operator!=(const ShMemIterator& rhs) {
return p!=rhs.p;
}
DataT& operator*() {
return *p;
}
};
template<typename DataT>
class SharedMemoryWrapper {
private:
DataT * m_ptr;
std::size_t m_size;
public:
SharedMemoryWrapper() :
m_ptr(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; }
bool empty() const { return 0 == size(); }
DataT & operator[](const unsigned index) {
BOOST_ASSERT_MSG(index < m_size, "invalid size");
return m_ptr[index];
}
const DataT & operator[](const unsigned index) const {
BOOST_ASSERT_MSG(index < m_size, "invalid size");
return m_ptr[index];
}
};
template<>
class SharedMemoryWrapper<bool> {
private:
unsigned * m_ptr;
std::size_t m_size;
public:
SharedMemoryWrapper() :
m_ptr(NULL),
m_size(0)
{ }
SharedMemoryWrapper(unsigned * ptr, std::size_t size) :
m_ptr(ptr),
m_size(size)
{ }
void swap( SharedMemoryWrapper<bool> & other ) {
BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
std::swap( m_size, other.m_size);
std::swap( m_ptr , other.m_ptr );
}
// 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;
// }
bool at(const std::size_t index) const {
// BOOST_ASSERT_MSG(index < m_size, "invalid size");
const unsigned bucket = index / 32;
const unsigned offset = index % 32;
return m_ptr[bucket] & (1 << offset);
}
// ShMemIterator<DataT> begin() const {
// return ShMemIterator<DataT>(m_ptr);
// }
// ShMemIterator<DataT> end() const {
// return ShMemIterator<DataT>(m_ptr+m_size);
// }
std::size_t size() const { return m_size; }
bool empty() const { return 0 == size(); }
bool operator[](const unsigned index) {
BOOST_ASSERT_MSG(index < m_size, "invalid size");
const unsigned bucket = index / 32;
const unsigned offset = index % 32;
return m_ptr[bucket] & (1 << offset);
}
};
template<typename DataT, bool UseSharedMemory>
struct ShM {
typedef typename boost::conditional<
UseSharedMemory,
SharedMemoryWrapper<DataT>,
std::vector<DataT>
>::type vector;
};
#endif //SHARED_MEMORY_VECTOR_WRAPPER_H
+29 -24
View File
@@ -29,13 +29,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define STATICGRAPH_H_INCLUDED #define STATICGRAPH_H_INCLUDED
#include "../DataStructures/Percent.h" #include "../DataStructures/Percent.h"
#include "../DataStructures/SharedMemoryVectorWrapper.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
template< typename EdgeDataT> template< typename EdgeDataT, bool UseSharedMemory = false>
class StaticGraph { class StaticGraph {
public: public:
typedef NodeID NodeIterator; typedef NodeID NodeIterator;
@@ -47,8 +48,9 @@ public:
NodeIterator source; NodeIterator source;
NodeIterator target; NodeIterator target;
bool operator<( const InputEdge& right ) const { bool operator<( const InputEdge& right ) const {
if ( source != right.source ) if ( source != right.source ) {
return source < right.source; return source < right.source;
}
return target < right.target; return target < right.target;
} }
}; };
@@ -89,16 +91,16 @@ public:
} }
} }
StaticGraph( std::vector<_StrNode> & nodes, std::vector<_StrEdge> & edges) { StaticGraph(
_numNodes = nodes.size(); typename ShM<_StrNode, UseSharedMemory>::vector & nodes,
typename ShM<_StrEdge, UseSharedMemory>::vector & edges
) {
_numNodes = nodes.size()-1;
_numEdges = edges.size(); _numEdges = edges.size();
_nodes.swap(nodes); _nodes.swap(nodes);
_edges.swap(edges); _edges.swap(edges);
//Add dummy node to end of _nodes array;
_nodes.push_back(_nodes.back());
#ifndef NDEBUG #ifndef NDEBUG
Percent p(GetNumberOfNodes()); Percent p(GetNumberOfNodes());
for(unsigned u = 0; u < GetNumberOfNodes(); ++u) { for(unsigned u = 0; u < GetNumberOfNodes(); ++u) {
@@ -110,16 +112,18 @@ public:
if(eid2 == UINT_MAX) { if(eid2 == UINT_MAX) {
SimpleLogger().Write(logWARNING) << SimpleLogger().Write(logWARNING) <<
"cannot find first segment of edge (" << "cannot find first segment of edge (" <<
u << "," << data.id << "," << v << ")"; u << "," << data.id << "," << v << "), eid: " << eid;
data.shortcut = false; data.shortcut = false;
BOOST_ASSERT(false);
} }
eid2 = FindEdgeInEitherDirection(data.id, v); eid2 = FindEdgeInEitherDirection(data.id, v);
if(eid2 == UINT_MAX) { if(eid2 == UINT_MAX) {
SimpleLogger().Write(logWARNING) << SimpleLogger().Write(logWARNING) <<
"cannot find second segment of edge (" << "cannot find second segment of edge (" <<
u << "," << data.id << "," << v << ")"; u << "," << data.id << "," << v << "), eid2: " << eid2;
data.shortcut = false; data.shortcut = false;
BOOST_ASSERT(false);
} }
} }
} }
@@ -136,34 +140,34 @@ public:
return _numEdges; return _numEdges;
} }
unsigned GetOutDegree( const NodeIterator &n ) const { unsigned GetOutDegree( const NodeIterator n ) const {
return BeginEdges(n)-EndEdges(n) - 1; 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 ); return NodeIterator( _edges[e].target );
} }
inline EdgeDataT &GetEdgeData( const EdgeIterator &e ) { inline EdgeDataT &GetEdgeData( const EdgeIterator e ) {
return _edges[e].data; return _edges[e].data;
} }
const EdgeDataT &GetEdgeData( const EdgeIterator &e ) const { const EdgeDataT &GetEdgeData( const EdgeIterator e ) const {
return _edges[e].data; return _edges[e].data;
} }
EdgeIterator BeginEdges( const NodeIterator &n ) const { EdgeIterator BeginEdges( const NodeIterator n ) const {
return EdgeIterator( _nodes[n].firstEdge ); return EdgeIterator( _nodes.at(n).firstEdge );
} }
EdgeIterator EndEdges( const NodeIterator &n ) const { EdgeIterator EndEdges( const NodeIterator n ) const {
return EdgeIterator( _nodes[n+1].firstEdge ); return EdgeIterator( _nodes.at(n+1).firstEdge );
} }
//searches for a specific edge //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; EdgeIterator smallestEdge = SPECIAL_EDGEID;
EdgeWeight smallestWeight = UINT_MAX; EdgeWeight smallestWeight = INVALID_EDGE_WEIGHT;
for ( EdgeIterator edge = BeginEdges( from ); edge < EndEdges(from); edge++ ) { for ( EdgeIterator edge = BeginEdges( from ); edge < EndEdges(from); edge++ ) {
const NodeID target = GetTarget(edge); const NodeID target = GetTarget(edge);
const EdgeWeight weight = GetEdgeData(edge).distance; const EdgeWeight weight = GetEdgeData(edge).distance;
@@ -174,17 +178,18 @@ public:
return smallestEdge; 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 ); EdgeIterator tmp = FindEdge( from, to );
return (UINT_MAX != tmp ? tmp : FindEdge( to, from )); 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 ); EdgeIterator tmp = FindEdge( from, to );
if(UINT_MAX == tmp) { if(UINT_MAX == tmp) {
tmp = FindEdge( to, from ); tmp = FindEdge( to, from );
if(UINT_MAX != tmp) if(UINT_MAX != tmp) {
result = true; result = true;
}
} }
return tmp; return tmp;
} }
@@ -194,8 +199,8 @@ private:
NodeIterator _numNodes; NodeIterator _numNodes;
EdgeIterator _numEdges; EdgeIterator _numEdges;
std::vector< _StrNode > _nodes; typename ShM< _StrNode, UseSharedMemory >::vector _nodes;
std::vector< _StrEdge > _edges; typename ShM< _StrEdge, UseSharedMemory >::vector _edges;
}; };
#endif // STATICGRAPH_H_INCLUDED #endif // STATICGRAPH_H_INCLUDED
+7 -7
View File
@@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef STATICKDTREE_H_INCLUDED #ifndef STATICKDTREE_H_INCLUDED
#define STATICKDTREE_H_INCLUDED #define STATICKDTREE_H_INCLUDED
#include <cassert> #include <boost/assert.hpp>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <stack> #include <stack>
@@ -99,9 +99,9 @@ public:
} }
}; };
StaticKDTree( std::vector< InputPoint > * points ){ explicit StaticKDTree( std::vector< InputPoint > * points ){
assert( k > 0 ); BOOST_ASSERT( k > 0 );
assert ( points->size() > 0 ); BOOST_ASSERT ( points->size() > 0 );
size = points->size(); size = points->size();
kdtree = new InputPoint[size]; kdtree = new InputPoint[size];
for ( Iterator i = 0; i != size; ++i ) { for ( Iterator i = 0; i != size; ++i ) {
@@ -207,13 +207,13 @@ private:
}; };
class Less { class Less {
public: public:
Less( unsigned d ) { explicit Less( unsigned d ) {
dimension = d; dimension = d;
assert( dimension < k ); BOOST_ASSERT( dimension < k );
} }
bool operator() ( const InputPoint& left, const InputPoint& right ) { bool operator() ( const InputPoint& left, const InputPoint& right ) {
assert( dimension < k ); BOOST_ASSERT( dimension < k );
return left.coordinates[dimension] < right.coordinates[dimension]; return left.coordinates[dimension] < right.coordinates[dimension];
} }
private: private:
+209 -325
View File
@@ -28,16 +28,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef STATICRTREE_H_ #ifndef STATICRTREE_H_
#define STATICRTREE_H_ #define STATICRTREE_H_
#include "MercatorUtil.h"
#include "Coordinate.h"
#include "PhantomNodes.h"
#include "DeallocatingVector.h" #include "DeallocatingVector.h"
#include "HilbertValue.h" #include "HilbertValue.h"
#include "PhantomNodes.h"
#include "QueryNode.h"
#include "SharedMemoryFactory.h"
#include "SharedMemoryVectorWrapper.h"
#include "../Util/MercatorUtil.h"
#include "../Util/OSRMException.h" #include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h" #include "../Util/TimingUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
@@ -47,7 +52,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/algorithm/minmax_element.hpp> #include <boost/algorithm/minmax_element.hpp>
#include <boost/range/algorithm_ext/erase.hpp> #include <boost/range/algorithm_ext/erase.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/type_traits.hpp>
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
@@ -63,9 +70,9 @@ const static uint32_t RTREE_LEAF_NODE_SIZE = 1170;
static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtree_stream; static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtree_stream;
template<class DataT> template<class DataT, class CoordinateListT = std::vector<FixedPointCoordinate>, bool UseSharedMemory = false>
class StaticRTree : boost::noncopyable { class StaticRTree : boost::noncopyable {
private: public:
struct RectangleInt2D { struct RectangleInt2D {
RectangleInt2D() : RectangleInt2D() :
min_lon(INT_MAX), min_lon(INT_MAX),
@@ -77,22 +84,35 @@ private:
int32_t min_lat, max_lat; int32_t min_lat, max_lat;
inline void InitializeMBRectangle( inline void InitializeMBRectangle(
const DataT * objects, DataT const * objects,
const uint32_t element_count const uint32_t element_count,
const std::vector<NodeInfo> & coordinate_list
) { ) {
for(uint32_t i = 0; i < element_count; ++i) { for(uint32_t i = 0; i < element_count; ++i) {
min_lon = std::min( min_lon = std::min(
min_lon, std::min(objects[i].lon1, objects[i].lon2) min_lon, std::min(
coordinate_list.at(objects[i].u).lon,
coordinate_list.at(objects[i].v).lon
)
); );
max_lon = std::max( max_lon = std::max(
max_lon, std::max(objects[i].lon1, objects[i].lon2) max_lon, std::max(
coordinate_list.at(objects[i].u).lon,
coordinate_list.at(objects[i].v).lon
)
); );
min_lat = std::min( min_lat = std::min(
min_lat, std::min(objects[i].lat1, objects[i].lat2) min_lat, std::min(
coordinate_list.at(objects[i].u).lat,
coordinate_list.at(objects[i].v).lat
)
); );
max_lat = std::max( max_lat = std::max(
max_lat, std::max(objects[i].lat1, objects[i].lat2) max_lat, std::max(
coordinate_list.at(objects[i].u).lat,
coordinate_list.at(objects[i].v).lat
)
); );
} }
} }
@@ -120,10 +140,10 @@ private:
FixedPointCoordinate lower_left (other.min_lat, other.min_lon); FixedPointCoordinate lower_left (other.min_lat, other.min_lon);
return ( return (
Contains(upper_left) Contains(upper_left ) ||
|| Contains(upper_right) Contains(upper_right) ||
|| Contains(lower_right) Contains(lower_right) ||
|| Contains(lower_left) Contains(lower_left )
); );
} }
@@ -136,7 +156,7 @@ private:
double min_dist = std::numeric_limits<double>::max(); double min_dist = std::numeric_limits<double>::max();
min_dist = std::min( min_dist = std::min(
min_dist, min_dist,
ApproximateDistance( FixedPointCoordinate::ApproximateDistance(
location.lat, location.lat,
location.lon, location.lon,
max_lat, max_lat,
@@ -145,7 +165,7 @@ private:
); );
min_dist = std::min( min_dist = std::min(
min_dist, min_dist,
ApproximateDistance( FixedPointCoordinate::ApproximateDistance(
location.lat, location.lat,
location.lon, location.lon,
max_lat, max_lat,
@@ -154,7 +174,7 @@ private:
); );
min_dist = std::min( min_dist = std::min(
min_dist, min_dist,
ApproximateDistance( FixedPointCoordinate::ApproximateDistance(
location.lat, location.lat,
location.lon, location.lon,
min_lat, min_lat,
@@ -163,7 +183,7 @@ private:
); );
min_dist = std::min( min_dist = std::min(
min_dist, min_dist,
ApproximateDistance( FixedPointCoordinate::ApproximateDistance(
location.lat, location.lat,
location.lon, location.lon,
min_lat, min_lat,
@@ -184,41 +204,41 @@ private:
min_max_dist = std::min( min_max_dist = std::min(
min_max_dist, min_max_dist,
std::max( std::max(
ApproximateDistance(location, upper_left ), FixedPointCoordinate::ApproximateDistance(location, upper_left ),
ApproximateDistance(location, upper_right) FixedPointCoordinate::ApproximateDistance(location, upper_right)
) )
); );
min_max_dist = std::min( min_max_dist = std::min(
min_max_dist, min_max_dist,
std::max( std::max(
ApproximateDistance(location, upper_right), FixedPointCoordinate::ApproximateDistance(location, upper_right),
ApproximateDistance(location, lower_right) FixedPointCoordinate::ApproximateDistance(location, lower_right)
) )
); );
min_max_dist = std::min( min_max_dist = std::min(
min_max_dist, min_max_dist,
std::max( std::max(
ApproximateDistance(location, lower_right), FixedPointCoordinate::ApproximateDistance(location, lower_right),
ApproximateDistance(location, lower_left ) FixedPointCoordinate::ApproximateDistance(location, lower_left )
) )
); );
min_max_dist = std::min( min_max_dist = std::min(
min_max_dist, min_max_dist,
std::max( std::max(
ApproximateDistance(location, lower_left ), FixedPointCoordinate::ApproximateDistance(location, lower_left ),
ApproximateDistance(location, upper_left ) FixedPointCoordinate::ApproximateDistance(location, upper_left )
) )
); );
return min_max_dist; return min_max_dist;
} }
inline bool Contains(const FixedPointCoordinate & location) const { inline bool Contains(const FixedPointCoordinate & location) const {
bool lats_contained = const bool lats_contained =
(location.lat > min_lat) && (location.lat < max_lat); (location.lat > min_lat) && (location.lat < max_lat);
bool lons_contained = const bool lons_contained =
(location.lon > min_lon) && (location.lon < max_lon); (location.lon > min_lon) && (location.lon < max_lon);
return lats_contained && lons_contained; return lats_contained && lons_contained;
} }
@@ -237,6 +257,16 @@ private:
typedef RectangleInt2D RectangleT; 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 { struct WrappedInputElement {
explicit WrappedInputElement( explicit WrappedInputElement(
const uint32_t _array_index, const uint32_t _array_index,
@@ -259,14 +289,6 @@ private:
DataT objects[RTREE_LEAF_NODE_SIZE]; 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 { struct QueryCandidate {
explicit QueryCandidate( explicit QueryCandidate(
const uint32_t n_id, const uint32_t n_id,
@@ -280,40 +302,53 @@ private:
} }
}; };
std::vector<TreeNode> m_search_tree; typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
uint64_t m_element_count; uint64_t m_element_count;
const std::string m_leaf_node_filename; const std::string m_leaf_node_filename;
boost::shared_ptr<CoordinateListT> m_coordinate_list;
public: public:
//Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1] //Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
explicit StaticRTree( explicit StaticRTree(
std::vector<DataT> & input_data_vector, std::vector<DataT> & input_data_vector,
const std::string tree_node_filename, const std::string tree_node_filename,
const std::string leaf_node_filename const std::string leaf_node_filename,
const std::vector<NodeInfo> & coordinate_list
) )
: m_element_count(input_data_vector.size()), : m_element_count(input_data_vector.size()),
m_leaf_node_filename(leaf_node_filename) m_leaf_node_filename(leaf_node_filename)
{ {
SimpleLogger().Write() << SimpleLogger().Write() <<
"constructing r-tree of " << m_element_count << "constructing r-tree of " << m_element_count <<
" elements"; " edge elements build on-top of " << coordinate_list.size() << " coordinates";
double time1 = get_timestamp(); double time1 = get_timestamp();
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count); std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
HilbertCode get_hilbert_number;
//generate auxiliary vector of hilbert-values //generate auxiliary vector of hilbert-values
#pragma omp parallel for schedule(guided) #pragma omp parallel for schedule(guided)
for(uint64_t element_counter = 0; element_counter < m_element_count; ++element_counter) { for(uint64_t element_counter = 0; element_counter < m_element_count; ++element_counter) {
input_wrapper_vector[element_counter].m_array_index = element_counter; input_wrapper_vector[element_counter].m_array_index = element_counter;
//Get Hilbert-Value for centroid in mercartor projection //Get Hilbert-Value for centroid in mercartor projection
DataT & current_element = input_data_vector[element_counter]; DataT const & current_element = input_data_vector[element_counter];
FixedPointCoordinate current_centroid = current_element.Centroid(); FixedPointCoordinate current_centroid = DataT::Centroid(
FixedPointCoordinate(
coordinate_list.at(current_element.u).lat,
coordinate_list.at(current_element.u).lon
),
FixedPointCoordinate(
coordinate_list.at(current_element.v).lat,
coordinate_list.at(current_element.v).lon
)
);
current_centroid.lat = COORDINATE_PRECISION*lat2y(current_centroid.lat/COORDINATE_PRECISION); current_centroid.lat = COORDINATE_PRECISION*lat2y(current_centroid.lat/COORDINATE_PRECISION);
uint64_t current_hilbert_value = HilbertCode::GetHilbertNumberForCoordinate(current_centroid); uint64_t current_hilbert_value = get_hilbert_number(current_centroid);
input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value; input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value;
} }
//open leaf file //open leaf file
boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary); boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
leaf_node_file.write((char*) &m_element_count, sizeof(uint64_t)); leaf_node_file.write((char*) &m_element_count, sizeof(uint64_t));
@@ -328,6 +363,7 @@ public:
LeafNode current_leaf; LeafNode current_leaf;
TreeNode current_node; TreeNode current_node;
//SimpleLogger().Write() << "reading " << tree_size << " tree nodes in " << (sizeof(TreeNode)*tree_size) << " bytes";
for(uint32_t current_element_index = 0; RTREE_LEAF_NODE_SIZE > current_element_index; ++current_element_index) { for(uint32_t current_element_index = 0; RTREE_LEAF_NODE_SIZE > current_element_index; ++current_element_index) {
if(m_element_count > (processed_objects_count + current_element_index)) { if(m_element_count > (processed_objects_count + current_element_index)) {
uint32_t index_of_next_object = input_wrapper_vector[processed_objects_count + current_element_index].m_array_index; uint32_t index_of_next_object = input_wrapper_vector[processed_objects_count + current_element_index].m_array_index;
@@ -337,7 +373,11 @@ public:
} }
//generate tree node that resemble the objects in leaf and store it for next level //generate tree node that resemble the objects in leaf and store it for next level
current_node.minimum_bounding_rectangle.InitializeMBRectangle(current_leaf.objects, current_leaf.object_count); current_node.minimum_bounding_rectangle.InitializeMBRectangle(
current_leaf.objects,
current_leaf.object_count,
coordinate_list
);
current_node.child_is_on_disk = true; current_node.child_is_on_disk = true;
current_node.children[0] = tree_nodes_in_level.size(); current_node.children[0] = tree_nodes_in_level.size();
tree_nodes_in_level.push_back(current_node); tree_nodes_in_level.push_back(current_node);
@@ -385,6 +425,7 @@ public:
//reverse and renumber tree to have root at index 0 //reverse and renumber tree to have root at index 0
std::reverse(m_search_tree.begin(), m_search_tree.end()); std::reverse(m_search_tree.begin(), m_search_tree.end());
#pragma omp parallel for schedule(guided) #pragma omp parallel for schedule(guided)
for(uint32_t i = 0; i < m_search_tree.size(); ++i) { for(uint32_t i = 0; i < m_search_tree.size(); ++i) {
TreeNode & current_tree_node = m_search_tree[i]; TreeNode & current_tree_node = m_search_tree[i];
@@ -414,11 +455,12 @@ public:
//Read-only operation for queries //Read-only operation for queries
explicit StaticRTree( explicit StaticRTree(
const std::string & node_filename, const boost::filesystem::path & node_file,
const std::string & leaf_filename const boost::filesystem::path & leaf_file,
) : m_leaf_node_filename(leaf_filename) { const boost::shared_ptr<CoordinateListT> coordinate_list
) : m_leaf_node_filename( leaf_file.string() ) {
//open tree node file and load into RAM. //open tree node file and load into RAM.
boost::filesystem::path node_file(node_filename); m_coordinate_list = coordinate_list;
if ( !boost::filesystem::exists( node_file ) ) { if ( !boost::filesystem::exists( node_file ) ) {
throw OSRMException("ram index file does not exist"); throw OSRMException("ram index file does not exist");
@@ -430,13 +472,11 @@ public:
uint32_t tree_size = 0; uint32_t tree_size = 0;
tree_node_file.read((char*)&tree_size, sizeof(uint32_t)); tree_node_file.read((char*)&tree_size, sizeof(uint32_t));
//SimpleLogger().Write() << "reading " << tree_size << " tree nodes in " << (sizeof(TreeNode)*tree_size) << " bytes";
m_search_tree.resize(tree_size); m_search_tree.resize(tree_size);
tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size); tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size);
tree_node_file.close(); tree_node_file.close();
//open leaf node file and store thread specific pointer //open leaf node file and store thread specific pointer
boost::filesystem::path leaf_file(leaf_filename);
if ( !boost::filesystem::exists( leaf_file ) ) { if ( !boost::filesystem::exists( leaf_file ) ) {
throw OSRMException("mem index file does not exist"); throw OSRMException("mem index file does not exist");
} }
@@ -451,154 +491,37 @@ public:
//SimpleLogger().Write() << tree_size << " nodes in search tree"; //SimpleLogger().Write() << tree_size << " nodes in search tree";
//SimpleLogger().Write() << m_element_count << " elements in leafs"; //SimpleLogger().Write() << m_element_count << " elements in leafs";
} }
/*
inline void FindKNearestPhantomNodesForCoordinate(
const FixedPointCoordinate & location,
const unsigned zoom_level,
const unsigned candidate_count,
std::vector<std::pair<PhantomNode, double> > & result_vector
) const {
bool ignore_tiny_components = (zoom_level <= 14); explicit StaticRTree(
DataT nearest_edge; TreeNode * tree_node_ptr,
const uint32_t number_of_nodes,
uint32_t io_count = 0; const boost::filesystem::path & leaf_file,
uint32_t explored_tree_nodes_count = 0; boost::shared_ptr<CoordinateListT> coordinate_list
SimpleLogger().Write() << "searching for coordinate " << input_coordinate; ) : m_search_tree(tree_node_ptr, number_of_nodes),
double min_dist = std::numeric_limits<double>::max(); m_leaf_node_filename(leaf_file.string()),
double min_max_dist = std::numeric_limits<double>::max(); m_coordinate_list(coordinate_list)
bool found_a_nearest_edge = false; {
//open leaf node file and store thread specific pointer
FixedPointCoordinate nearest, current_start_coordinate, current_end_coordinate; if ( !boost::filesystem::exists( leaf_file ) ) {
throw OSRMException("mem index file does not exist");
//initialize queue with root element }
std::priority_queue<QueryCandidate> traversal_queue; if ( 0 == boost::filesystem::file_size( leaf_file ) ) {
traversal_queue.push(QueryCandidate(0, m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate))); throw OSRMException("mem index file is empty");
BOOST_ASSERT_MSG(std::numberic_limits<double>::epsilon() > (0. - traversal_queue.top().min_dist), "Root element in NN Search has min dist != 0.");
while(!traversal_queue.empty()) {
const QueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop();
++explored_tree_nodes_count;
bool prune_downward = (current_query_node.min_dist >= min_max_dist);
bool prune_upward = (current_query_node.min_dist >= min_dist);
if( !prune_downward && !prune_upward ) { //downward pruning
TreeNode & current_tree_node = m_search_tree[current_query_node.node_id];
if (current_tree_node.child_is_on_disk) {
LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
++io_count;
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
DataT & current_edge = current_leaf_node.objects[i];
if(ignore_tiny_components && current_edge.belongsToTinyComponent) {
continue;
}
double current_ratio = 0.;
double current_perpendicular_distance = ComputePerpendicularDistance(
input_coordinate,
FixedPointCoordinate(current_edge.lat1, current_edge.lon1),
FixedPointCoordinate(current_edge.lat2, current_edge.lon2),
nearest,
&current_ratio
);
if(
current_perpendicular_distance < min_dist
&& !DoubleEpsilonCompare(
current_perpendicular_distance,
min_dist
)
) { //found a new minimum
min_dist = current_perpendicular_distance;
result_phantom_node.edgeBasedNode = current_edge.id;
result_phantom_node.nodeBasedEdgeNameID = current_edge.nameID;
result_phantom_node.weight1 = current_edge.weight;
result_phantom_node.weight2 = INT_MAX;
result_phantom_node.location = nearest;
current_start_coordinate.lat = current_edge.lat1;
current_start_coordinate.lon = current_edge.lon1;
current_end_coordinate.lat = current_edge.lat2;
current_end_coordinate.lon = current_edge.lon2;
nearest_edge = current_edge;
found_a_nearest_edge = true;
} else if(
DoubleEpsilonCompare(current_perpendicular_distance, min_dist) &&
1 == abs(current_edge.id - result_phantom_node.edgeBasedNode )
&& CoordinatesAreEquivalent(
current_start_coordinate,
FixedPointCoordinate(
current_edge.lat1,
current_edge.lon1
),
FixedPointCoordinate(
current_edge.lat2,
current_edge.lon2
),
current_end_coordinate
)
) {
result_phantom_node.edgeBasedNode = std::min(current_edge.id, result_phantom_node.edgeBasedNode);
result_phantom_node.weight2 = current_edge.weight;
}
}
} else {
//traverse children, prune if global mindist is smaller than local one
for (uint32_t i = 0; i < current_tree_node.child_count; ++i) {
const int32_t child_id = current_tree_node.children[i];
TreeNode & child_tree_node = m_search_tree[child_id];
RectangleT & child_rectangle = child_tree_node.minimum_bounding_rectangle;
const double current_min_dist = child_rectangle.GetMinDist(input_coordinate);
const double current_min_max_dist = child_rectangle.GetMinMaxDist(input_coordinate);
if( current_min_max_dist < min_max_dist ) {
min_max_dist = current_min_max_dist;
}
if (current_min_dist > min_max_dist) {
continue;
}
if (current_min_dist > min_dist) { //upward pruning
continue;
}
traversal_queue.push(QueryCandidate(child_id, current_min_dist));
}
}
}
} }
const double distance_to_edge = boost::filesystem::ifstream leaf_node_file( leaf_file, std::ios::binary );
ApproximateDistance ( leaf_node_file.read((char*)&m_element_count, sizeof(uint64_t));
FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1), leaf_node_file.close();
result_phantom_node.location
);
const double length_of_edge = if( thread_local_rtree_stream.get() ) {
ApproximateDistance( thread_local_rtree_stream->close();
FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1),
FixedPointCoordinate(nearest_edge.lat2, nearest_edge.lon2)
);
const double ratio = (found_a_nearest_edge ?
std::min(1., distance_to_edge/ length_of_edge ) : 0 );
result_phantom_node.weight1 *= ratio;
if(INT_MAX != result_phantom_node.weight2) {
result_phantom_node.weight2 *= (1.-ratio);
}
result_phantom_node.ratio = ratio;
//Hack to fix rounding errors and wandering via nodes.
if(std::abs(input_coordinate.lon - result_phantom_node.location.lon) == 1) {
result_phantom_node.location.lon = input_coordinate.lon;
}
if(std::abs(input_coordinate.lat - result_phantom_node.location.lat) == 1) {
result_phantom_node.location.lat = input_coordinate.lat;
} }
SimpleLogger().Write() << "mindist: " << min_distphantom_node.isBidirected() ? "yes" : "no"); //SimpleLogger().Write() << tree_size << " nodes in search tree";
return found_a_nearest_edge; //SimpleLogger().Write() << m_element_count << " elements in leafs";
} }
//Read-only operation for queries
*/
bool LocateClosestEndPointForCoordinate( bool LocateClosestEndPointForCoordinate(
const FixedPointCoordinate & input_coordinate, const FixedPointCoordinate & input_coordinate,
FixedPointCoordinate & result_coordinate, FixedPointCoordinate & result_coordinate,
@@ -637,43 +560,40 @@ public:
current_leaf_node current_leaf_node
); );
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) { for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
const DataT & current_edge = current_leaf_node.objects[i]; DataT const & current_edge = current_leaf_node.objects[i];
if( if(
ignore_tiny_components && ignore_tiny_components &&
current_edge.belongsToTinyComponent current_edge.belongsToTinyComponent
) { ) {
continue; continue;
} }
if(current_edge.isIgnored()) {
continue;
}
double current_minimum_distance = ApproximateDistance( double current_minimum_distance = FixedPointCoordinate::ApproximateDistance(
input_coordinate.lat, input_coordinate.lat,
input_coordinate.lon, input_coordinate.lon,
current_edge.lat1, m_coordinate_list->at(current_edge.u).lat,
current_edge.lon1 m_coordinate_list->at(current_edge.u).lon
); );
if( current_minimum_distance < min_dist ) { if( current_minimum_distance < min_dist ) {
//found a new minimum //found a new minimum
min_dist = current_minimum_distance; min_dist = current_minimum_distance;
result_coordinate.lat = current_edge.lat1; result_coordinate.lat = m_coordinate_list->at(current_edge.u).lat;
result_coordinate.lon = current_edge.lon1; result_coordinate.lon = m_coordinate_list->at(current_edge.u).lon;
found_a_nearest_edge = true; found_a_nearest_edge = true;
} }
current_minimum_distance = ApproximateDistance( current_minimum_distance = FixedPointCoordinate::ApproximateDistance(
input_coordinate.lat, input_coordinate.lat,
input_coordinate.lon, input_coordinate.lon,
current_edge.lat2, m_coordinate_list->at(current_edge.v).lat,
current_edge.lon2 m_coordinate_list->at(current_edge.v).lon
); );
if( current_minimum_distance < min_dist ) { if( current_minimum_distance < min_dist ) {
//found a new minimum //found a new minimum
min_dist = current_minimum_distance; min_dist = current_minimum_distance;
result_coordinate.lat = current_edge.lat2; result_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
result_coordinate.lon = current_edge.lon2; result_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
found_a_nearest_edge = true; found_a_nearest_edge = true;
} }
} }
@@ -705,7 +625,6 @@ public:
return found_a_nearest_edge; return found_a_nearest_edge;
} }
bool FindPhantomNodeForCoordinate( bool FindPhantomNodeForCoordinate(
const FixedPointCoordinate & input_coordinate, const FixedPointCoordinate & input_coordinate,
PhantomNode & result_phantom_node, PhantomNode & result_phantom_node,
@@ -715,7 +634,7 @@ public:
bool ignore_tiny_components = (zoom_level <= 14); bool ignore_tiny_components = (zoom_level <= 14);
DataT nearest_edge; DataT nearest_edge;
uint32_t io_count = 0; // uint32_t io_count = 0;
uint32_t explored_tree_nodes_count = 0; uint32_t explored_tree_nodes_count = 0;
//SimpleLogger().Write() << "searching for coordinate " << input_coordinate; //SimpleLogger().Write() << "searching for coordinate " << input_coordinate;
double min_dist = std::numeric_limits<double>::max(); double min_dist = std::numeric_limits<double>::max();
@@ -727,15 +646,14 @@ public:
//initialize queue with root element //initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue; std::priority_queue<QueryCandidate> traversal_queue;
double current_min_dist = m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate); double current_min_dist = m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate);
traversal_queue.push( traversal_queue.push( QueryCandidate(0, current_min_dist) );
QueryCandidate(0, current_min_dist)
);
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(
std::numeric_limits<double>::epsilon() > (0. - traversal_queue.top().min_dist), std::numeric_limits<double>::epsilon() > (0. - traversal_queue.top().min_dist),
"Root element in NN Search has min dist != 0." "Root element in NN Search has min dist != 0."
); );
LeafNode current_leaf_node;
while(!traversal_queue.empty()) { while(!traversal_queue.empty()) {
const QueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop(); const QueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop();
@@ -745,70 +663,51 @@ public:
if( !prune_downward && !prune_upward ) { //downward pruning if( !prune_downward && !prune_upward ) { //downward pruning
TreeNode & current_tree_node = m_search_tree[current_query_node.node_id]; TreeNode & current_tree_node = m_search_tree[current_query_node.node_id];
if (current_tree_node.child_is_on_disk) { if (current_tree_node.child_is_on_disk) {
LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node); LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
++io_count; // ++io_count;
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) { for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
DataT & current_edge = current_leaf_node.objects[i]; DataT & current_edge = current_leaf_node.objects[i];
if(ignore_tiny_components && current_edge.belongsToTinyComponent) { if(ignore_tiny_components && current_edge.belongsToTinyComponent) {
continue; continue;
} }
if(current_edge.isIgnored()) {
continue;
}
double current_ratio = 0.; double current_ratio = 0.;
double current_perpendicular_distance = ComputePerpendicularDistance( const double current_perpendicular_distance = current_edge.ComputePerpendicularDistance(
input_coordinate, m_coordinate_list->at(current_edge.u),
FixedPointCoordinate(current_edge.lat1, current_edge.lon1), m_coordinate_list->at(current_edge.v),
FixedPointCoordinate(current_edge.lat2, current_edge.lon2), input_coordinate,
nearest, nearest,
&current_ratio current_ratio
); );
BOOST_ASSERT( 0. <= current_perpendicular_distance );
if( if(
current_perpendicular_distance < min_dist ( current_perpendicular_distance < min_dist ) &&
&& !DoubleEpsilonCompare( !DoubleEpsilonCompare(
current_perpendicular_distance, current_perpendicular_distance,
min_dist min_dist
) )
) { //found a new minimum ) { //found a new minimum
min_dist = current_perpendicular_distance; min_dist = current_perpendicular_distance;
result_phantom_node.edgeBasedNode = current_edge.id; //TODO: use assignment c'tor in PhantomNode
result_phantom_node.nodeBasedEdgeNameID = current_edge.nameID; result_phantom_node.forward_node_id = current_edge.forward_edge_based_node_id;
result_phantom_node.weight1 = current_edge.weight; result_phantom_node.reverse_node_id = current_edge.reverse_edge_based_node_id;
result_phantom_node.weight2 = INT_MAX; result_phantom_node.name_id = current_edge.name_id;
result_phantom_node.forward_weight = current_edge.forward_weight;
result_phantom_node.reverse_weight = current_edge.reverse_weight;
result_phantom_node.forward_offset = current_edge.forward_offset;
result_phantom_node.reverse_offset = current_edge.reverse_offset;
result_phantom_node.packed_geometry_id = current_edge.packed_geometry_id;
result_phantom_node.fwd_segment_position = current_edge.fwd_segment_position;
result_phantom_node.location = nearest; result_phantom_node.location = nearest;
current_start_coordinate.lat = current_edge.lat1; current_start_coordinate.lat = m_coordinate_list->at(current_edge.u).lat;
current_start_coordinate.lon = current_edge.lon1; current_start_coordinate.lon = m_coordinate_list->at(current_edge.u).lon;
current_end_coordinate.lat = current_edge.lat2; current_end_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
current_end_coordinate.lon = current_edge.lon2; current_end_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
nearest_edge = current_edge; nearest_edge = current_edge;
found_a_nearest_edge = true; found_a_nearest_edge = true;
} else if(
DoubleEpsilonCompare(current_perpendicular_distance, min_dist) &&
1 == abs(current_edge.id - result_phantom_node.edgeBasedNode )
&& CoordinatesAreEquivalent(
current_start_coordinate,
FixedPointCoordinate(
current_edge.lat1,
current_edge.lon1
),
FixedPointCoordinate(
current_edge.lat2,
current_edge.lon2
),
current_end_coordinate
)
) {
BOOST_ASSERT_MSG(current_edge.id != result_phantom_node.edgeBasedNode, "IDs not different");
result_phantom_node.weight2 = current_edge.weight;
if(current_edge.id < result_phantom_node.edgeBasedNode) {
result_phantom_node.edgeBasedNode = current_edge.id;
std::swap(result_phantom_node.weight1, result_phantom_node.weight2);
std::swap(current_end_coordinate, current_start_coordinate);
}
} }
} }
} else { } else {
@@ -822,10 +721,10 @@ public:
if( current_min_max_dist < min_max_dist ) { if( current_min_max_dist < min_max_dist ) {
min_max_dist = current_min_max_dist; min_max_dist = current_min_max_dist;
} }
if (current_min_dist > min_max_dist) { if( current_min_dist > min_max_dist ) {
continue; continue;
} }
if (current_min_dist > min_dist) { //upward pruning if( current_min_dist > min_dist ) { //upward pruning
continue; continue;
} }
traversal_queue.push(QueryCandidate(child_id, current_min_dist)); traversal_queue.push(QueryCandidate(child_id, current_min_dist));
@@ -834,17 +733,6 @@ public:
} }
} }
const double ratio = (found_a_nearest_edge ?
std::min(1., ApproximateDistance(current_start_coordinate,
result_phantom_node.location)/ApproximateDistance(current_start_coordinate, current_end_coordinate)
) : 0
);
result_phantom_node.weight1 *= ratio;
if(INT_MAX != result_phantom_node.weight2) {
result_phantom_node.weight2 *= (1.-ratio);
}
result_phantom_node.ratio = ratio;
//Hack to fix rounding errors and wandering via nodes. //Hack to fix rounding errors and wandering via nodes.
if(std::abs(input_coordinate.lon - result_phantom_node.location.lon) == 1) { if(std::abs(input_coordinate.lon - result_phantom_node.location.lon) == 1) {
result_phantom_node.location.lon = input_coordinate.lon; result_phantom_node.location.lon = input_coordinate.lon;
@@ -853,8 +741,47 @@ public:
result_phantom_node.location.lat = input_coordinate.lat; result_phantom_node.location.lat = input_coordinate.lat;
} }
return found_a_nearest_edge; double ratio = 0.;
if( found_a_nearest_edge) {
const double distance_1 = FixedPointCoordinate::ApproximateDistance(
current_start_coordinate,
result_phantom_node.location
);
const double distance_2 = FixedPointCoordinate::ApproximateDistance(
current_start_coordinate,
current_end_coordinate
);
ratio = distance_1/distance_2;
ratio = std::min(1., ratio);
}
// SimpleLogger().Write(logDEBUG) << "[rtree] result_phantom_node.forward_offset: " << result_phantom_node.forward_offset;
// SimpleLogger().Write(logDEBUG) << "[rtree] result_phantom_node.reverse_offset: " << result_phantom_node.reverse_offset;
// SimpleLogger().Write(logDEBUG) << "[rtree] result_phantom_node.forward_weight: " << result_phantom_node.forward_weight;
// SimpleLogger().Write(logDEBUG) << "[rtree] result_phantom_node.reverse_weight: " << result_phantom_node.reverse_weight;
if (SPECIAL_NODEID != result_phantom_node.forward_node_id)
{
result_phantom_node.forward_weight *= ratio;
}
if (SPECIAL_NODEID != result_phantom_node.reverse_node_id)
{
result_phantom_node.reverse_weight *= (1.-ratio);
}
// SimpleLogger().Write(logDEBUG) << "[rtree] result location: " << result_phantom_node.location << ", start: " << current_start_coordinate << ", end: " << current_end_coordinate;
// SimpleLogger().Write(logDEBUG) << "[rtree] fwd node: " << result_phantom_node.forward_node_id << ", rev node: " << result_phantom_node.reverse_node_id;
// SimpleLogger().Write(logDEBUG) << "[rtree] fwd weight: " << result_phantom_node.forward_weight << ", rev weight: " << result_phantom_node.reverse_weight;
// SimpleLogger().Write(logDEBUG) << "[rtree] fwd offset: " << result_phantom_node.forward_offset << ", rev offset: " << result_phantom_node.reverse_offset;
// SimpleLogger().Write(logDEBUG) << "[rtree] bidirected: " << (result_phantom_node.isBidirected() ? "y" : "n");
// SimpleLogger().Write(logDEBUG) << "[rtree] name id: " << result_phantom_node.name_id;
// SimpleLogger().Write(logDEBUG) << "[rtree] geom id: " << result_phantom_node.packed_geometry_id;
// SimpleLogger().Write(logDEBUG) << "[rtree] ratio: " << ratio;
return found_a_nearest_edge;
} }
private: private:
@@ -879,60 +806,17 @@ private:
thread_local_rtree_stream->read((char *)&result_node, sizeof(LeafNode)); thread_local_rtree_stream->read((char *)&result_node, sizeof(LeafNode));
} }
inline double ComputePerpendicularDistance( inline bool EdgesAreEquivalent(
const FixedPointCoordinate& inputPoint, const FixedPointCoordinate & a,
const FixedPointCoordinate& source, const FixedPointCoordinate & b,
const FixedPointCoordinate& target, const FixedPointCoordinate & c,
FixedPointCoordinate& nearest, double *r) const { const FixedPointCoordinate & d
const double x = inputPoint.lat/COORDINATE_PRECISION; ) const {
const double y = inputPoint.lon/COORDINATE_PRECISION;
const double a = source.lat/COORDINATE_PRECISION;
const double b = source.lon/COORDINATE_PRECISION;
const double c = target.lat/COORDINATE_PRECISION;
const double d = target.lon/COORDINATE_PRECISION;
double p,q,mX,nY;
if(std::fabs(a-c) > std::numeric_limits<double>::epsilon() ){
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m);
q = b + m*(p - a);
} else {
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
mX = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if(std::isnan(mX)) {
*r = (target == inputPoint) ? 1. : 0.;
} else {
*r = mX;
}
if(*r<=0.){
nearest.lat = source.lat;
nearest.lon = source.lon;
return ((b - y)*(b - y) + (a - x)*(a - x));
// return std::sqrt(((b - y)*(b - y) + (a - x)*(a - x)));
} else if(*r >= 1.){
nearest.lat = target.lat;
nearest.lon = target.lon;
return ((d - y)*(d - y) + (c - x)*(c - x));
// return std::sqrt(((d - y)*(d - y) + (c - x)*(c - x)));
}
// point lies in between
nearest.lat = p*COORDINATE_PRECISION;
nearest.lon = q*COORDINATE_PRECISION;
// return std::sqrt((p-x)*(p-x) + (q-y)*(q-y));
return (p-x)*(p-x) + (q-y)*(q-y);
}
inline bool CoordinatesAreEquivalent(const FixedPointCoordinate & a, const FixedPointCoordinate & b, const FixedPointCoordinate & c, const FixedPointCoordinate & d) const {
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c); return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
} }
inline bool DoubleEpsilonCompare(const double d1, const double d2) const { inline bool DoubleEpsilonCompare(const double d1, const double d2) const {
return (std::fabs(d1 - d2) < std::numeric_limits<double>::epsilon() ); return (std::abs(d1 - d2) < std::numeric_limits<double>::epsilon() );
} }
}; };
-2
View File
@@ -92,6 +92,4 @@ struct TurnInstructionsClass : boost::noncopyable {
}; };
static TurnInstructionsClass TurnInstructions;
#endif /* TURNINSTRUCTIONS_H_ */ #endif /* TURNINSTRUCTIONS_H_ */
+1 -1
View File
@@ -54,7 +54,7 @@ public:
} }
}; };
XORFastHashStorage( size_t ) : positions(2<<16), currentTimestamp(0) { } explicit XORFastHashStorage( size_t ) : positions(2<<16), currentTimestamp(0) { }
inline HashCell& operator[]( const NodeID node ) { inline HashCell& operator[]( const NodeID node ) {
unsigned short position = fastHash(node); unsigned short position = fastHash(node);
+18 -13
View File
@@ -28,36 +28,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef BASE_DESCRIPTOR_H_ #ifndef BASE_DESCRIPTOR_H_
#define BASE_DESCRIPTOR_H_ #define BASE_DESCRIPTOR_H_
#include "../DataStructures/HashTable.h"
#include "../DataStructures/PhantomNodes.h" #include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h" #include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngine.h"
#include "../Server/BasicDatastructures.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <cassert> #include <osrm/Reply.h>
#include <cmath>
#include <cstdio>
#include <string> #include <string>
#include <vector> #include <vector>
struct _DescriptorConfig { struct DescriptorConfig {
_DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(true), z(18) {} DescriptorConfig() :
instructions(true),
geometry(true),
encode_geometry(true),
zoom_level(18)
{ }
bool instructions; bool instructions;
bool geometry; bool geometry;
bool encodeGeometry; bool encode_geometry;
unsigned short z; unsigned short zoom_level;
}; };
template<class DataFacadeT>
class BaseDescriptor { class BaseDescriptor {
public: public:
BaseDescriptor() { } BaseDescriptor() { }
//Maybe someone can explain the pure virtual destructor thing to me (dennis) //Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BaseDescriptor() { } virtual ~BaseDescriptor() { }
virtual void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngine &sEngine) = 0; virtual void Run(
virtual void SetConfig(const _DescriptorConfig & config) = 0; const RawRouteData & rawRoute,
const PhantomNodes & phantomNodes,
DataFacadeT * facade,
http::Reply & reply
) = 0;
virtual void SetConfig(const DescriptorConfig & config) = 0;
}; };
#endif /* BASE_DESCRIPTOR_H_ */ #endif /* BASE_DESCRIPTOR_H_ */
+81 -161
View File
@@ -31,190 +31,110 @@ DescriptionFactory::DescriptionFactory() : entireLength(0) { }
DescriptionFactory::~DescriptionFactory() { } DescriptionFactory::~DescriptionFactory() { }
inline double DescriptionFactory::DegreeToRadian(const double degree) const { inline double DescriptionFactory::DegreeToRadian(const double degree) const
return degree * (M_PI/180); {
return degree * (M_PI/180.);
} }
inline double DescriptionFactory::RadianToDegree(const double radian) const { inline double DescriptionFactory::RadianToDegree(const double radian) const
return radian * (180/M_PI); {
return radian * (180./M_PI);
} }
double DescriptionFactory::GetBearing( double DescriptionFactory::GetBearing(const FixedPointCoordinate & A, const FixedPointCoordinate & B) const
const FixedPointCoordinate & A, {
const FixedPointCoordinate & B double delta_long = DegreeToRadian(B.lon/COORDINATE_PRECISION - A.lon/COORDINATE_PRECISION);
) const {
double deltaLong = DegreeToRadian(B.lon/COORDINATE_PRECISION - A.lon/COORDINATE_PRECISION);
double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION); const double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION);
double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION); const double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION);
double y = sin(deltaLong) * cos(lat2); const double y = sin(delta_long) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong); const double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_long);
double result = RadianToDegree(atan2(y, x)); double result = RadianToDegree(atan2(y, x));
while(result <= 0.) while (result < 0.)
{
result += 360.; result += 360.;
while(result >= 360.) }
result -= 360.;
while (result >= 360.)
{
result -= 360.;
}
return result; return result;
} }
void DescriptionFactory::SetStartSegment(const PhantomNode & _startPhantom) { void DescriptionFactory::SetStartSegment(const PhantomNode & source, const bool source_traversed_in_reverse)
startPhantom = _startPhantom; {
AppendSegment(_startPhantom.location, _PathData(0, _startPhantom.nodeBasedEdgeNameID, 10, _startPhantom.weight1)); start_phantom = source;
AppendSegment(
source.location,
PathData(0, source.name_id, 10, source.forward_weight)
);
} }
void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) { void DescriptionFactory::SetEndSegment(const PhantomNode & target, const bool target_traversed_in_reverse)
targetPhantom = _targetPhantom; {
pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) ); target_phantom = target;
pathDescription.push_back(
SegmentInformation(
target.location,
target.name_id,
0,
target.reverse_weight,
0,
true
)
);
} }
void DescriptionFactory::AppendSegment(const FixedPointCoordinate & coordinate, const _PathData & data ) { void DescriptionFactory::AppendSegment(const FixedPointCoordinate & coordinate, const PathData & path_point)
if(1 == pathDescription.size() && pathDescription.back().location == coordinate) { {
pathDescription.back().nameID = data.nameID; if ((1 == pathDescription.size()) && ( pathDescription.back().location == coordinate))
} else { {
pathDescription.push_back(SegmentInformation(coordinate, data.nameID, 0, data.durationOfSegment, data.turnInstruction) ); pathDescription.back().name_id = path_point.name_id;
} }
}
void DescriptionFactory::AppendEncodedPolylineString(std::string & output, bool isEncoded) {
if(isEncoded)
pc.printEncodedString(pathDescription, output);
else else
pc.printUnencodedString(pathDescription, output); {
} pathDescription.push_back(
SegmentInformation(coordinate, path_point.name_id, path_point.durationOfSegment, 0, path_point.turnInstruction)
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; void DescriptionFactory::AppendEncodedPolylineString(
unsigned durationOfSegment = 0; const bool return_encoded,
unsigned indexOfSegmentBegin = 0; std::vector<std::string> & output
) {
std::string string0 = sEngine.GetEscapedNameForNameID(pathDescription[0].nameID); std::string temp;
std::string string1; if(return_encoded) {
polyline_compressor.printEncodedString(pathDescription, temp);
/*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";
}
} else { } else {
pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio); polyline_compressor.printUnencodedString(pathDescription, temp);
} }
if(std::numeric_limits<double>::epsilon() > pathDescription[0].length) { output.push_back(temp);
//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;
} }
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time) { void DescriptionFactory::AppendEncodedPolylineString(
summary.startName = startPhantom.nodeBasedEdgeNameID; std::vector<std::string> &output
summary.destName = targetPhantom.nodeBasedEdgeNameID; ) 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::BuildRouteSummary(
const double distance,
const unsigned time
) {
summary.startName = start_phantom.name_id;
summary.destName = target_phantom.name_id;
summary.BuildDurationAndLengthStrings(distance, time); summary.BuildDurationAndLengthStrings(distance, time);
} }
+140 -17
View File
@@ -30,13 +30,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Algorithms/DouglasPeucker.h" #include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h" #include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/Coordinate.h" #include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/SearchEngine.h" #include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SegmentInformation.h" #include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <limits> #include <limits>
#include <vector> #include <vector>
@@ -44,24 +46,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* and produces the description plus the encoded polyline */ * and produces the description plus the encoded polyline */
class DescriptionFactory { class DescriptionFactory {
DouglasPeucker<SegmentInformation> dp; DouglasPeucker polyline_generalizer;
PolylineCompressor pc; PolylineCompressor polyline_compressor;
PhantomNode startPhantom, targetPhantom; PhantomNode start_phantom, target_phantom;
double DegreeToRadian(const double degree) const; double DegreeToRadian(const double degree) const;
double RadianToDegree(const double degree) const; double RadianToDegree(const double degree) const;
public: public:
struct _RouteSummary { struct RouteSummary {
std::string lengthString; std::string lengthString;
std::string durationString; std::string durationString;
unsigned startName; unsigned startName;
unsigned destName; unsigned destName;
_RouteSummary() : lengthString("0"), durationString("0"), startName(0), destName(0) {} RouteSummary() :
void BuildDurationAndLengthStrings(const double distance, const unsigned time) { lengthString("0"),
durationString("0"),
startName(0),
destName(0)
{}
void BuildDurationAndLengthStrings(
const double distance,
const unsigned time
) {
//compute distance/duration for route summary //compute distance/duration for route summary
intToString(round(distance), lengthString); intToString(round(distance), lengthString);
int travelTime = time/10 + 1; int travel_time = round(time/10.);
intToString(travelTime, durationString); intToString(std::max(travel_time, 1), durationString);
} }
} summary; } summary;
@@ -72,14 +83,126 @@ public:
DescriptionFactory(); DescriptionFactory();
virtual ~DescriptionFactory(); virtual ~DescriptionFactory();
double GetBearing(const FixedPointCoordinate& C, const FixedPointCoordinate& B) const; double GetBearing(const FixedPointCoordinate& C, const FixedPointCoordinate& B) const;
void AppendEncodedPolylineString(std::string &output); void AppendEncodedPolylineString(std::vector<std::string> &output) const;
void AppendUnencodedPolylineString(std::string &output); void AppendUnencodedPolylineString(std::vector<std::string> &output) const;
void AppendSegment(const FixedPointCoordinate & coordinate, const _PathData & data); void AppendSegment(const FixedPointCoordinate & coordinate, const PathData & data);
void BuildRouteSummary(const double distance, const unsigned time); void BuildRouteSummary(const double distance, const unsigned time);
void SetStartSegment(const PhantomNode & startPhantom); void SetStartSegment(const PhantomNode & start_phantom, const bool source_traversed_in_reverse);
void SetEndSegment(const PhantomNode & startPhantom); void SetEndSegment(const PhantomNode & start_phantom, const bool target_traversed_in_reverse);
void AppendEncodedPolylineString(std::string & output, bool isEncoded); void AppendEncodedPolylineString(
void Run(const SearchEngine &sEngine, const unsigned zoomLevel); const bool return_encoded,
std::vector<std::string> & output
);
template<class DataFacadeT>
void Run(
const DataFacadeT * facade,
const unsigned zoomLevel
) {
if( pathDescription.empty() ) {
return;
}
/** starts at index 1 */
pathDescription[0].length = 0;
for (unsigned i = 1; i < pathDescription.size(); ++i)
{
//move down names by one, q&d hack
pathDescription[i-1].name_id = pathDescription[i].name_id;
pathDescription[i].length = FixedPointCoordinate::ApproximateEuclideanDistance(pathDescription[i-1].location, pathDescription[i].location);
}
/*Simplify turn instructions
Input :
10. Turn left on B 36 for 20 km
11. Continue on B 35; B 36 for 2 km
12. Continue on B 36 for 13 km
becomes:
10. Turn left on B 36 for 35 km
*/
//TODO: rework to check only end and start of string.
// stl string is way to expensive
// unsigned lastTurn = 0;
// for(unsigned i = 1; i < pathDescription.size(); ++i) {
// string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].name_id);
// if(TurnInstructionsClass::GoStraight == pathDescription[i].turn_instruction) {
// if(std::string::npos != string0.find(string1+";")
// || std::string::npos != string0.find(";"+string1)
// || std::string::npos != string0.find(string1+" ;")
// || std::string::npos != string0.find("; "+string1)
// ){
// SimpleLogger().Write() << "->next correct: " << string0 << " contains " << string1;
// for(; lastTurn != i; ++lastTurn)
// pathDescription[lastTurn].name_id = pathDescription[i].name_id;
// pathDescription[i].turn_instruction = 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].name_id = pathDescription[i-1].name_id;
// pathDescription[i].turn_instruction = TurnInstructionsClass::NoTurn;
// }
// }
// if (TurnInstructionsClass::NoTurn != pathDescription[i].turn_instruction) {
// lastTurn = i;
// }
// string0 = string1;
// }
double segment_length = 0.;
unsigned segment_duration = 0;
unsigned segment_start_index = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
entireLength += pathDescription[i].length;
segment_length += pathDescription[i].length;
segment_duration += pathDescription[i].duration;
pathDescription[segment_start_index].length = segment_length;
pathDescription[segment_start_index].duration = segment_duration;
if(TurnInstructionsClass::NoTurn != pathDescription[i].turn_instruction) {
BOOST_ASSERT(pathDescription[i].necessary);
segment_length = 0;
segment_duration = 0;
segment_start_index = i;
}
}
//Post-processing to remove empty or nearly empty path segments
if(std::numeric_limits<double>::epsilon() > pathDescription.back().length) {
if(pathDescription.size() > 2){
pathDescription.pop_back();
pathDescription.back().necessary = true;
pathDescription.back().turn_instruction = TurnInstructionsClass::NoTurn;
target_phantom.name_id = (pathDescription.end()-2)->name_id;
}
}
if(std::numeric_limits<double>::epsilon() > pathDescription[0].length) {
if(pathDescription.size() > 2) {
pathDescription.erase(pathDescription.begin());
pathDescription[0].turn_instruction = TurnInstructionsClass::HeadOn;
pathDescription[0].necessary = true;
start_phantom.name_id = pathDescription[0].name_id;
}
}
//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*10;
}
}
return;
}
}; };
#endif /* DESCRIPTIONFACTORY_H_ */ #endif /* DESCRIPTIONFACTORY_H_ */
+59 -26
View File
@@ -32,42 +32,75 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
class GPXDescriptor : public BaseDescriptor{ template<class DataFacadeT>
class GPXDescriptor : public BaseDescriptor<DataFacadeT> {
private: private:
_DescriptorConfig config; DescriptorConfig config;
FixedPointCoordinate current; FixedPointCoordinate current;
std::string tmp; std::string tmp;
public: public:
void SetConfig(const _DescriptorConfig& c) { config = c; } 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\"?>"); //TODO: reorder parameters
reply.content += "<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" xmlns=\"http://www.topografix.com/GPX/1/1\" " void Run(
const RawRouteData &raw_route,
const PhantomNodes &phantom_node_list,
DataFacadeT * facade,
http::Reply & reply
) {
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\" " "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd" "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.push_back(
reply.content += "<rte>"; "<metadata><copyright author=\"Project OSRM\"><license>Data (c)"
if(rawRoute.lengthOfShortestPath != INT_MAX && rawRoute.computedShortestPath.size()) { " OpenStreetMap contributors (ODbL)</license></copyright>"
convertInternalLatLonToString(phantomNodes.startPhantom.location.lat, tmp); "</metadata>");
reply.content += "<rtept lat=\"" + tmp + "\" "; reply.content.push_back("<rte>");
convertInternalLatLonToString(phantomNodes.startPhantom.location.lon, tmp); bool found_route = (raw_route.lengthOfShortestPath != INT_MAX) &&
reply.content += "lon=\"" + tmp + "\"></rtept>"; (raw_route.unpacked_path_segments[0].size());
if( found_route ) {
FixedPointCoordinate::convertInternalLatLonToString(
phantom_node_list.source_phantom.location.lat,
tmp
);
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
FixedPointCoordinate::convertInternalLatLonToString(
phantom_node_list.source_phantom.location.lon,
tmp
);
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedShortestPath) { for(unsigned i=0; i < raw_route.unpacked_path_segments.size(); ++i){
sEngine.GetCoordinatesForNodeID(pathData.node, current); BOOST_FOREACH(
const PathData & pathData,
raw_route.unpacked_path_segments[i]
) {
current = facade->GetCoordinateOfNode(pathData.node);
convertInternalLatLonToString(current.lat, tmp); FixedPointCoordinate::convertInternalLatLonToString(current.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" "; reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
convertInternalLatLonToString(current.lon, tmp); FixedPointCoordinate::convertInternalLatLonToString(current.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>"; reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
}
} }
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lat, tmp); // Add the via point or the end coordinate
reply.content += "<rtept lat=\"" + tmp + "\" "; FixedPointCoordinate::convertInternalLatLonToString(
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lon, tmp); phantom_node_list.target_phantom.location.lat,
reply.content += "lon=\"" + tmp + "\"></rtept>"; tmp
);
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
FixedPointCoordinate::convertInternalLatLonToString(
phantom_node_list.target_phantom.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_
+397 -259
View File
@@ -41,32 +41,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm> #include <algorithm>
class JSONDescriptor : public BaseDescriptor{ template<class DataFacadeT>
class JSONDescriptor : public BaseDescriptor<DataFacadeT> {
private: private:
_DescriptorConfig config; // TODO: initalize in c'tor
DescriptionFactory descriptionFactory; DataFacadeT * facade;
DescriptionFactory alternateDescriptionFactory; DescriptorConfig config;
DescriptionFactory description_factory;
DescriptionFactory alternate_descriptionFactory;
FixedPointCoordinate current; FixedPointCoordinate current;
unsigned numberOfEnteredRestrictedAreas; unsigned entered_restricted_area_count;
struct RoundAbout{ struct RoundAbout{
RoundAbout() : RoundAbout() :
startIndex(INT_MAX), start_index(INT_MAX),
nameID(INT_MAX), name_id(INT_MAX),
leaveAtExit(INT_MAX) leave_at_exit(INT_MAX)
{} {}
int startIndex; int start_index;
int nameID; int name_id;
int leaveAtExit; int leave_at_exit;
} roundAbout; } round_about;
struct Segment { struct Segment {
Segment() : nameID(-1), length(-1), position(-1) {} Segment() : name_id(-1), length(-1), position(-1) {}
Segment(int n, int l, int p) : nameID(n), length(l), position(p) {} Segment(int n, int l, int p) : name_id(n), length(l), position(p) {}
int nameID; int name_id;
int length; int length;
int position; int position;
}; };
std::vector<Segment> shortestSegments, alternativeSegments; std::vector<Segment> shortest_path_segments, alternative_path_segments;
std::vector<unsigned> shortest_leg_end_indices, alternative_leg_end_indices;
struct RouteNames { struct RouteNames {
std::string shortestPathName1; std::string shortestPathName1;
@@ -76,207 +80,321 @@ private:
}; };
public: public:
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {} JSONDescriptor() :
void SetConfig(const _DescriptorConfig & c) { config = c; } facade(NULL),
entered_restricted_area_count(0)
{
shortest_leg_end_indices.push_back(0);
alternative_leg_end_indices.push_back(0);
}
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngine &sEngine) { void SetConfig(const DescriptorConfig & c) { config = c; }
WriteHeaderToOutput(reply.content); int DescribeLeg(
const std::vector<PathData> route_leg,
const PhantomNodes & leg_phantoms
) {
int added_element_count = 0;
//Get all the coordinates for the computed route
FixedPointCoordinate current_coordinate;
BOOST_FOREACH(const PathData & path_data, route_leg) {
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
description_factory.AppendSegment(current_coordinate, path_data);
++added_element_count;
}
// description_factory.SetEndSegment( leg_phantoms.target_phantom );
++added_element_count;
BOOST_ASSERT( (int)(route_leg.size() + 1) == added_element_count );
return added_element_count;
}
if(rawRoute.lengthOfShortestPath != INT_MAX) { void Run(
descriptionFactory.SetStartSegment(phantomNodes.startPhantom); const RawRouteData & raw_route,
reply.content += "0," const PhantomNodes & phantom_nodes,
"\"status_message\": \"Found route between points\","; // TODO: move facade initalization to c'tor
DataFacadeT * f,
http::Reply & reply
) {
facade = f;
reply.content.push_back(
"{\"status\":"
);
//Get all the coordinates for the computed route if (INVALID_EDGE_WEIGHT == raw_route.lengthOfShortestPath)
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedShortestPath) { {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
descriptionFactory.AppendSegment(current, pathData );
}
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
} else {
//We do not need to do much, if there is no route ;-) //We do not need to do much, if there is no route ;-)
reply.content += "207," reply.content.push_back(
"\"status_message\": \"Cannot find route between points\","; "207,\"status_message\": \"Cannot find route between points\"}"
);
return;
} }
descriptionFactory.Run(sEngine, config.z); SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.lengthOfShortestPath;
reply.content += "\"route_geometry\": ";
if(config.geometry) {
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
} else {
reply.content += "[]";
}
reply.content += "," //check if first segment is non-zero
"\"route_instructions\": ["; std::string road_name;
numberOfEnteredRestrictedAreas = 0; road_name = facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id);
if(config.instructions) {
BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, sEngine, shortestSegments); // for each unpacked segment add the leg to the description
} else { BOOST_ASSERT( raw_route.unpacked_path_segments.size() == raw_route.segmentEndCoordinates.size() );
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction); {
const std::vector<PathData> & leg_path = raw_route.unpacked_path_segments[i];
FixedPointCoordinate current_coordinate;
BOOST_FOREACH(const PathData & path_data, leg_path)
{
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
road_name = facade->GetEscapedNameForNameID(path_data.name_id);
} }
} }
reply.content += "],";
descriptionFactory.BuildRouteSummary(descriptionFactory.entireLength, rawRoute.lengthOfShortestPath - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenalty));
reply.content += "\"route_summary\":"; //check if last segment is non-zero
reply.content += "{"; road_name = facade->GetEscapedNameForNameID(phantom_nodes.target_phantom.name_id);
reply.content += "\"total_distance\":";
reply.content += descriptionFactory.summary.lengthString; description_factory.SetStartSegment(phantom_nodes.source_phantom, raw_route.source_traversed_in_reverse);
reply.content += "," reply.content.push_back("0,"
"\"total_time\":"; "\"status_message\": \"Found route between points\",");
reply.content += descriptionFactory.summary.durationString;
reply.content += "," BOOST_ASSERT( raw_route.unpacked_path_segments.size() == raw_route.segmentEndCoordinates.size() );
"\"start_point\":\""; for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName); {
reply.content += "\"," const int added_segments = DescribeLeg(
"\"end_point\":\""; raw_route.unpacked_path_segments[i],
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName); raw_route.segmentEndCoordinates[i]
reply.content += "\""; );
reply.content += "}"; BOOST_ASSERT( 0 < added_segments );
reply.content +=","; shortest_leg_end_indices.push_back(
added_segments + shortest_leg_end_indices.back()
);
}
description_factory.SetEndSegment(phantom_nodes.target_phantom, raw_route.target_traversed_in_reverse);
description_factory.Run(facade, config.zoom_level);
reply.content.push_back("\"route_geometry\": ");
if(config.geometry) {
description_factory.AppendEncodedPolylineString(
config.encode_geometry,
reply.content
);
} else {
reply.content.push_back("[]");
}
reply.content.push_back(",\"route_instructions\": [");
if(config.instructions) {
BuildTextualDescription(
description_factory,
reply,
raw_route.lengthOfShortestPath,
facade,
shortest_path_segments
);
}
reply.content.push_back("],");
description_factory.BuildRouteSummary(
description_factory.entireLength,
raw_route.lengthOfShortestPath
);
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 //only one alternative route is computed at this time, so this is hardcoded
if(rawRoute.lengthOfAlternativePath != INT_MAX) { if(raw_route.lengthOfAlternativePath != INVALID_EDGE_WEIGHT)
alternateDescriptionFactory.SetStartSegment(phantomNodes.startPhantom); {
alternate_descriptionFactory.SetStartSegment(phantom_nodes.source_phantom, raw_route.alt_source_traversed_in_reverse);
//Get all the coordinates for the computed route //Get all the coordinates for the computed route
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedAlternativePath) { BOOST_FOREACH(const PathData & path_data, raw_route.unpacked_alternative) {
sEngine.GetCoordinatesForNodeID(pathData.node, current); current = facade->GetCoordinateOfNode(path_data.node);
alternateDescriptionFactory.AppendSegment(current, pathData ); alternate_descriptionFactory.AppendSegment(current, path_data );
} }
alternateDescriptionFactory.SetEndSegment(phantomNodes.targetPhantom); alternate_descriptionFactory.SetEndSegment(phantom_nodes.target_phantom, raw_route.alt_target_traversed_in_reverse);
} }
alternateDescriptionFactory.Run(sEngine, config.z); alternate_descriptionFactory.Run(facade, config.zoom_level);
//give an array of alternative routes // //give an array of alternative routes
reply.content += "\"alternative_geometries\": ["; reply.content.push_back("\"alternative_geometries\": [");
if(config.geometry && INT_MAX != rawRoute.lengthOfAlternativePath) { if(config.geometry && INT_MAX != raw_route.lengthOfAlternativePath) {
//Generate the linestrings for each alternative //Generate the linestrings for each alternative
alternateDescriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry); alternate_descriptionFactory.AppendEncodedPolylineString(
config.encode_geometry,
reply.content
);
} }
reply.content += "],"; reply.content.push_back("],");
reply.content += "\"alternative_instructions\":["; reply.content.push_back("\"alternative_instructions\":[");
numberOfEnteredRestrictedAreas = 0; if(INT_MAX != raw_route.lengthOfAlternativePath) {
if(INT_MAX != rawRoute.lengthOfAlternativePath) { reply.content.push_back("[");
reply.content += "[";
//Generate instructions for each alternative //Generate instructions for each alternative
if(config.instructions) { if(config.instructions) {
BuildTextualDescription(alternateDescriptionFactory, reply, rawRoute.lengthOfAlternativePath, sEngine, alternativeSegments); BuildTextualDescription(
} else { alternate_descriptionFactory,
BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) { reply,
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; raw_route.lengthOfAlternativePath,
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction); facade,
} alternative_path_segments
);
} }
reply.content += "]"; reply.content.push_back("]");
} }
reply.content += "],"; reply.content.push_back("],");
reply.content += "\"alternative_summaries\":["; reply.content.push_back("\"alternative_summaries\":[");
if(INT_MAX != rawRoute.lengthOfAlternativePath) { if(INT_MAX != raw_route.lengthOfAlternativePath) {
//Generate route summary (length, duration) for each alternative //Generate route summary (length, duration) for each alternative
alternateDescriptionFactory.BuildRouteSummary(alternateDescriptionFactory.entireLength, rawRoute.lengthOfAlternativePath - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenalty)); alternate_descriptionFactory.BuildRouteSummary(
reply.content += "{"; alternate_descriptionFactory.entireLength,
reply.content += "\"total_distance\":"; raw_route.lengthOfAlternativePath
reply.content += alternateDescriptionFactory.summary.lengthString; );
reply.content += "," reply.content.push_back("{");
"\"total_time\":"; reply.content.push_back("\"total_distance\":");
reply.content += alternateDescriptionFactory.summary.durationString; reply.content.push_back(
reply.content += "," alternate_descriptionFactory.summary.lengthString
"\"start_point\":\""; );
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName); reply.content.push_back(","
reply.content += "\"," "\"total_time\":");
"\"end_point\":\""; reply.content.push_back(
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName); alternate_descriptionFactory.summary.durationString
reply.content += "\""; );
reply.content += "}"; 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 // //Get Names for both routes
RouteNames routeNames; RouteNames routeNames;
GetRouteNames(shortestSegments, alternativeSegments, sEngine, routeNames); GetRouteNames(shortest_path_segments, alternative_path_segments, facade, routeNames);
reply.content += "\"route_name\":[\""; reply.content.push_back("\"route_name\":[\"");
reply.content += routeNames.shortestPathName1; reply.content.push_back(routeNames.shortestPathName1);
reply.content += "\",\""; reply.content.push_back("\",\"");
reply.content += routeNames.shortestPathName2; reply.content.push_back(routeNames.shortestPathName2);
reply.content += "\"]," reply.content.push_back("\"],"
"\"alternative_names\":["; "\"alternative_names\":[");
reply.content += "[\""; reply.content.push_back("[\"");
reply.content += routeNames.alternativePathName1; reply.content.push_back(routeNames.alternativePathName1);
reply.content += "\",\""; reply.content.push_back("\",\"");
reply.content += routeNames.alternativePathName2; reply.content.push_back(routeNames.alternativePathName2);
reply.content += "\"]"; reply.content.push_back("\"]");
reply.content += "],"; reply.content.push_back("],");
//list all viapoints so that the client may display it //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);
else
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates[i], tmp);
reply.content += tmp; BOOST_ASSERT( !raw_route.segmentEndCoordinates.empty() );
reply.content += "],";
} std::string tmp;
reply.content += "["; FixedPointCoordinate::convertInternalReversedCoordinateToString(
if(rawRoute.segmentEndCoordinates.back().startPhantom.location.isSet()) raw_route.segmentEndCoordinates.front().source_phantom.location,
convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates.back().targetPhantom.location, tmp); tmp
else );
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates.back(), tmp); reply.content.push_back("[");
reply.content += tmp; reply.content.push_back(tmp);
reply.content += "]"; reply.content.push_back("]");
BOOST_FOREACH(const PhantomNodes & nodes, raw_route.segmentEndCoordinates) {
tmp.clear();
FixedPointCoordinate::convertInternalReversedCoordinateToString(
nodes.target_phantom.location,
tmp
);
reply.content.push_back(",[");
reply.content.push_back(tmp);
reply.content.push_back("]");
} }
reply.content += "],";
reply.content += "\"hint_data\": {"; reply.content.push_back("],");
reply.content += "\"checksum\":"; reply.content.push_back("\"via_indices\":[");
intToString(rawRoute.checkSum, tmp); BOOST_FOREACH(const unsigned index, shortest_leg_end_indices) {
reply.content += tmp; tmp.clear();
reply.content += ", \"locations\": ["; intToString(index, tmp);
reply.content.push_back(tmp);
if( index != shortest_leg_end_indices.back() ) {
reply.content.push_back(",");
}
}
reply.content.push_back("],\"alternative_indices\":[");
if(INT_MAX != raw_route.lengthOfAlternativePath) {
reply.content.push_back("0,");
tmp.clear();
intToString(alternate_descriptionFactory.pathDescription.size(), tmp);
reply.content.push_back(tmp);
}
reply.content.push_back("],");
reply.content.push_back("\"hint_data\": {");
reply.content.push_back("\"checksum\":");
intToString(raw_route.checkSum, tmp);
reply.content.push_back(tmp);
reply.content.push_back(", \"locations\": [");
std::string hint; std::string hint;
for(unsigned i = 0; i < rawRoute.segmentEndCoordinates.size(); ++i) { for(unsigned i = 0; i < raw_route.segmentEndCoordinates.size(); ++i) {
reply.content += "\""; reply.content.push_back("\"");
EncodeObjectToBase64(rawRoute.segmentEndCoordinates[i].startPhantom, hint); EncodeObjectToBase64(raw_route.segmentEndCoordinates[i].source_phantom, hint);
reply.content += hint; reply.content.push_back(hint);
reply.content += "\", "; reply.content.push_back("\", ");
} }
EncodeObjectToBase64(rawRoute.segmentEndCoordinates.back().targetPhantom, hint); EncodeObjectToBase64(raw_route.segmentEndCoordinates.back().target_phantom, hint);
reply.content += "\""; reply.content.push_back("\"");
reply.content += hint; reply.content.push_back(hint);
reply.content += "\"]"; reply.content.push_back("\"]");
reply.content += "},"; reply.content.push_back("}}");
reply.content += "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"";
reply.content += "}";
} }
void GetRouteNames(std::vector<Segment> & shortestSegments, std::vector<Segment> & alternativeSegments, const SearchEngine &sEngine, RouteNames & routeNames) { // construct routes names
/*** extract names for both alternatives ***/ void GetRouteNames(
std::vector<Segment> & shortest_path_segments,
std::vector<Segment> & alternative_path_segments,
const DataFacadeT * facade,
RouteNames & routeNames
) {
Segment shortestSegment1, shortestSegment2; Segment shortestSegment1, shortestSegment2;
Segment alternativeSegment1, alternativeSegment2; Segment alternativeSegment1, alternativeSegment2;
if(0 < shortestSegments.size()) { if(0 < shortest_path_segments.size()) {
sort(shortestSegments.begin(), shortestSegments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) ); sort(shortest_path_segments.begin(), shortest_path_segments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
shortestSegment1 = shortestSegments[0]; shortestSegment1 = shortest_path_segments[0];
if(0 < alternativeSegments.size()) { if(0 < alternative_path_segments.size()) {
sort(alternativeSegments.begin(), alternativeSegments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) ); sort(alternative_path_segments.begin(), alternative_path_segments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
alternativeSegment1 = alternativeSegments[0]; alternativeSegment1 = alternative_path_segments[0];
} }
std::vector<Segment> shortestDifference(shortestSegments.size()); std::vector<Segment> shortestDifference(shortest_path_segments.size());
std::vector<Segment> alternativeDifference(alternativeSegments.size()); std::vector<Segment> alternativeDifference(alternative_path_segments.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::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(); int size_of_difference = shortestDifference.size();
if(0 < size_of_difference ) { if(0 < size_of_difference ) {
int i = 0; 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; ++i;
} }
if(i < size_of_difference ) { if(i < size_of_difference ) {
@@ -284,11 +402,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(); size_of_difference = alternativeDifference.size();
if(0 < size_of_difference ) { if(0 < size_of_difference ) {
int i = 0; 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; ++i;
} }
if(i < size_of_difference ) { if(i < size_of_difference ) {
@@ -301,104 +419,124 @@ public:
if(alternativeSegment1.position > alternativeSegment2.position) if(alternativeSegment1.position > alternativeSegment2.position)
std::swap(alternativeSegment1, alternativeSegment2); std::swap(alternativeSegment1, alternativeSegment2);
routeNames.shortestPathName1 = sEngine.GetEscapedNameForNameID(shortestSegment1.nameID); routeNames.shortestPathName1 = facade->GetEscapedNameForNameID(
routeNames.shortestPathName2 = sEngine.GetEscapedNameForNameID(shortestSegment2.nameID); shortestSegment1.name_id
);
routeNames.shortestPathName2 = facade->GetEscapedNameForNameID(
shortestSegment2.name_id
);
routeNames.alternativePathName1 = sEngine.GetEscapedNameForNameID(alternativeSegment1.nameID); routeNames.alternativePathName1 = facade->GetEscapedNameForNameID(
routeNames.alternativePathName2 = sEngine.GetEscapedNameForNameID(alternativeSegment2.nameID); alternativeSegment1.name_id
);
routeNames.alternativePathName2 = facade->GetEscapedNameForNameID(
alternativeSegment2.name_id
);
} }
} }
inline void WriteHeaderToOutput(std::string & output) { //TODO: reorder parameters
output += "{" inline void BuildTextualDescription(
"\"version\": 0.3," DescriptionFactory & description_factory,
"\"status\":"; http::Reply & reply,
} const int route_length,
const DataFacadeT * facade,
inline void BuildTextualDescription(DescriptionFactory & descriptionFactory, http::Reply & reply, const int lengthOfRoute, const SearchEngine &sEngine, std::vector<Segment> & segmentVector) { std::vector<Segment> & route_segments_list
) {
//Segment information has following format: //Segment information has following format:
//["instruction","streetname",length,position,time,"length","earth_direction",azimuth] //["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
//Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5] //Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5]
//See also: http://developers.cloudmade.com/wiki/navengine/JSON_format unsigned necessary_segments_running_index = 0;
unsigned prefixSumOfNecessarySegments = 0; round_about.leave_at_exit = 0;
roundAbout.leaveAtExit = 0; round_about.name_id = 0;
roundAbout.nameID = 0; std::string temp_dist, temp_length, temp_duration, temp_bearing, temp_instruction;
std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction;
//Fetch data from Factory and generate a string from it. //Fetch data from Factory and generate a string from it.
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) { BOOST_FOREACH(const SegmentInformation & segment, description_factory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; TurnInstruction current_instruction = segment.turn_instruction & TurnInstructionsClass::InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction); entered_restricted_area_count += (current_instruction != segment.turn_instruction);
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) { if (TurnInstructionsClass::TurnIsNecessary( current_instruction) )
if(TurnInstructions.EnterRoundAbout == currentInstruction) { {
roundAbout.nameID = segment.nameID; if (TurnInstructionsClass::EnterRoundAbout == current_instruction)
roundAbout.startIndex = prefixSumOfNecessarySegments; {
} else { round_about.name_id = segment.name_id;
if(0 != prefixSumOfNecessarySegments){ round_about.start_index = necessary_segments_running_index;
reply.content += ",";
}
reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == currentInstruction) {
intToString(TurnInstructions.EnterRoundAbout, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "-";
intToString(roundAbout.leaveAtExit+1, tmpInstruction);
reply.content += tmpInstruction;
roundAbout.leaveAtExit = 0;
} else {
intToString(currentInstruction, tmpInstruction);
reply.content += tmpInstruction;
}
reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
reply.content += "\",";
intToString(segment.length, tmpDist);
reply.content += tmpDist;
reply.content += ",";
intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content += tmpLength;
reply.content += ",";
intToString(segment.duration/10, tmpDuration);
reply.content += tmpDuration;
reply.content += ",\"";
intToString(segment.length, tmpLength);
reply.content += tmpLength;
reply.content += "m\",\"";
reply.content += Azimuth::Get(segment.bearing);
reply.content += "\",";
intToString(round(segment.bearing), tmpBearing);
reply.content += tmpBearing;
reply.content += "]";
segmentVector.push_back( Segment(segment.nameID, segment.length, segmentVector.size() ));
} }
} else if(TurnInstructions.StayOnRoundAbout == currentInstruction) { else
++roundAbout.leaveAtExit; {
if (0 != necessary_segments_running_index)
{
reply.content.push_back(",");
}
reply.content.push_back("[\"");
if(TurnInstructionsClass::LeaveRoundAbout == current_instruction) {
intToString(TurnInstructionsClass::EnterRoundAbout, temp_instruction);
reply.content.push_back(temp_instruction);
reply.content.push_back("-");
intToString(round_about.leave_at_exit+1, temp_instruction);
reply.content.push_back(temp_instruction);
round_about.leave_at_exit = 0;
} else {
intToString(current_instruction, temp_instruction);
reply.content.push_back(temp_instruction);
}
reply.content.push_back("\",\"");
reply.content.push_back(facade->GetEscapedNameForNameID(segment.name_id));
reply.content.push_back("\",");
intToString(segment.length, temp_dist);
reply.content.push_back(temp_dist);
reply.content.push_back(",");
intToString(necessary_segments_running_index, temp_length);
reply.content.push_back(temp_length);
reply.content.push_back(",");
intToString(round(segment.duration/10.), temp_duration);
reply.content.push_back(temp_duration);
reply.content.push_back(",\"");
intToString(segment.length, temp_length);
reply.content.push_back(temp_length);
reply.content.push_back("m\",\"");
double bearing_value = round(segment.bearing/10.);
reply.content.push_back(Azimuth::Get(bearing_value));
reply.content.push_back("\",");
intToString(bearing_value, temp_bearing);
reply.content.push_back(temp_bearing);
reply.content.push_back("]");
route_segments_list.push_back(
Segment(
segment.name_id,
segment.length,
route_segments_list.size()
)
);
}
} else if(TurnInstructionsClass::StayOnRoundAbout == current_instruction) {
++round_about.leave_at_exit;
} }
if(segment.necessary) if(segment.necessary)
++prefixSumOfNecessarySegments; ++necessary_segments_running_index;
} }
if(INT_MAX != lengthOfRoute) { if(INT_MAX != route_length) {
reply.content += ",[\""; reply.content.push_back(",[\"");
intToString(TurnInstructions.ReachedYourDestination, tmpInstruction); intToString(TurnInstructionsClass::ReachedYourDestination, temp_instruction);
reply.content += tmpInstruction; reply.content.push_back(temp_instruction);
reply.content += "\",\""; reply.content.push_back("\",\"");
reply.content += "\","; reply.content.push_back("\",");
reply.content += "0"; reply.content.push_back("0");
reply.content += ","; reply.content.push_back(",");
intToString(prefixSumOfNecessarySegments-1, tmpLength); intToString(necessary_segments_running_index-1, temp_length);
reply.content += tmpLength; reply.content.push_back(temp_length);
reply.content += ","; reply.content.push_back(",");
reply.content += "0"; reply.content.push_back("0");
reply.content += ",\""; reply.content.push_back(",\"");
reply.content += "\",\""; reply.content.push_back("\",\"");
reply.content += Azimuth::Get(0.0); reply.content.push_back(Azimuth::Get(0.0));
reply.content += "\","; reply.content.push_back("\",");
reply.content += "0.0"; reply.content.push_back("0.0");
reply.content += "]"; reply.content.push_back("]");
} }
} }
}; };
#endif /* JSON_DESCRIPTOR_H_ */ #endif /* JSON_DESCRIPTOR_H_ */
+58 -23
View File
@@ -26,22 +26,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "BaseParser.h" #include "BaseParser.h"
#include "ExtractionWay.h"
#include "ScriptingEnvironment.h"
BaseParser::BaseParser(ExtractorCallbacks* ec, ScriptingEnvironment& se) : #include "../DataStructures/ImportNode.h"
extractor_callbacks(ec), scriptingEnvironment(se), luaState(NULL), use_turn_restrictions(true) { #include "../Util/LuaUtil.h"
luaState = se.getLuaStateForThreadID(0); #include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/foreach.hpp>
#include <boost/regex.hpp>
BaseParser::BaseParser(
ExtractorCallbacks * extractor_callbacks,
ScriptingEnvironment & scripting_environment
) : extractor_callbacks(extractor_callbacks),
lua_state(scripting_environment.getLuaStateForThreadID(0)),
scripting_environment(scripting_environment),
use_turn_restrictions(true)
{
ReadUseRestrictionsSetting(); ReadUseRestrictionsSetting();
ReadRestrictionExceptions(); ReadRestrictionExceptions();
} }
void BaseParser::ReadUseRestrictionsSetting() { void BaseParser::ReadUseRestrictionsSetting() {
if( 0 != luaL_dostring( luaState, "return use_turn_restrictions\n") ) { if( 0 != luaL_dostring( lua_state, "return use_turn_restrictions\n") ) {
throw OSRMException( throw OSRMException("ERROR occured in scripting block");
/*lua_tostring( luaState, -1 ) + */"ERROR occured in scripting block"
);
} }
if( lua_isboolean( luaState, -1) ) { if( lua_isboolean( lua_state, -1) ) {
use_turn_restrictions = lua_toboolean(luaState, -1); use_turn_restrictions = lua_toboolean(lua_state, -1);
} }
if( use_turn_restrictions ) { if( use_turn_restrictions ) {
SimpleLogger().Write() << "Using turn restrictions"; SimpleLogger().Write() << "Using turn restrictions";
@@ -51,16 +66,18 @@ void BaseParser::ReadUseRestrictionsSetting() {
} }
void BaseParser::ReadRestrictionExceptions() { void BaseParser::ReadRestrictionExceptions() {
if(lua_function_exists(luaState, "get_exceptions" )) { if(lua_function_exists(lua_state, "get_exceptions" )) {
//get list of turn restriction exceptions //get list of turn restriction exceptions
luabind::call_function<void>( luabind::call_function<void>(
luaState, lua_state,
"get_exceptions", "get_exceptions",
boost::ref(restriction_exceptions) boost::ref(restriction_exceptions)
); );
SimpleLogger().Write() << "Found " << restriction_exceptions.size() << " exceptions to turn restriction"; const unsigned exception_count = restriction_exceptions.size();
SimpleLogger().Write() <<
"Found " << exception_count << " exceptions to turn restrictions:";
BOOST_FOREACH(const std::string & str, restriction_exceptions) { BOOST_FOREACH(const std::string & str, restriction_exceptions) {
SimpleLogger().Write() << " " << str; SimpleLogger().Write() << " " << str;
} }
} else { } else {
SimpleLogger().Write() << "Found no exceptions to turn restrictions"; SimpleLogger().Write() << "Found no exceptions to turn restrictions";
@@ -74,20 +91,32 @@ void BaseParser::report_errors(lua_State *L, const int status) const {
} }
} }
void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* localLuaState) { void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* local_lua_state) {
luabind::call_function<void>( localLuaState, "node_function", boost::ref(n) ); luabind::call_function<void>(
local_lua_state,
"node_function",
boost::ref(n)
);
} }
void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) { void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* local_lua_state) {
luabind::call_function<void>( localLuaState, "way_function", boost::ref(w) ); luabind::call_function<void>(
local_lua_state,
"way_function",
boost::ref(w)
);
} }
bool BaseParser::ShouldIgnoreRestriction(const std::string & except_tag_string) const { bool BaseParser::ShouldIgnoreRestriction(
const std::string & except_tag_string
) const {
//should this restriction be ignored? yes if there's an overlap between: //should this restriction be ignored? yes if there's an overlap between:
//a) the list of modes in the except tag of the restriction (except_tag_string), ex: except=bus;bicycle // a) the list of modes in the except tag of the restriction
//b) the lua profile defines a hierachy of modes, ex: [access, vehicle, bicycle] // (except_tag_string), eg: except=bus;bicycle
// b) the lua profile defines a hierachy of modes,
// eg: [access, vehicle, bicycle]
if( "" == except_tag_string ) { if( except_tag_string.empty() ) {
return false; return false;
} }
@@ -95,8 +124,14 @@ bool BaseParser::ShouldIgnoreRestriction(const std::string & except_tag_string)
//only a few exceptions are actually defined. //only a few exceptions are actually defined.
std::vector<std::string> exceptions; std::vector<std::string> exceptions;
boost::algorithm::split_regex(exceptions, except_tag_string, boost::regex("[;][ ]*")); boost::algorithm::split_regex(exceptions, except_tag_string, boost::regex("[;][ ]*"));
BOOST_FOREACH(std::string& str, exceptions) { BOOST_FOREACH(std::string& current_string, exceptions) {
if( restriction_exceptions.end() != std::find(restriction_exceptions.begin(), restriction_exceptions.end(), str) ) { std::vector<std::string>::const_iterator string_iterator;
string_iterator = std::find(
restriction_exceptions.begin(),
restriction_exceptions.end(),
current_string
);
if( restriction_exceptions.end() != string_iterator ) {
return true; return true;
} }
} }
+20 -14
View File
@@ -28,11 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef BASEPARSER_H_ #ifndef BASEPARSER_H_
#define BASEPARSER_H_ #define BASEPARSER_H_
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
extern "C" { extern "C" {
#include <lua.h> #include <lua.h>
#include <lauxlib.h> #include <lauxlib.h>
@@ -40,29 +35,40 @@ extern "C" {
} }
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <string>
#include <vector>
class ExtractorCallbacks;
class ScriptingEnvironment;
struct ExtractionWay;
struct ImportNode;
class BaseParser : boost::noncopyable { class BaseParser : boost::noncopyable {
public: public:
BaseParser(ExtractorCallbacks* ec, ScriptingEnvironment& se); BaseParser(
ExtractorCallbacks * extractor_callbacks,
ScriptingEnvironment & scripting_environment
);
virtual ~BaseParser() {} virtual ~BaseParser() {}
virtual bool ReadHeader() = 0; virtual bool ReadHeader() = 0;
virtual bool Parse() = 0; virtual bool Parse() = 0;
virtual void ParseNodeInLua(ImportNode& n, lua_State* luaStateForThread); virtual void ParseNodeInLua(ImportNode & n, lua_State* thread_lua_state);
virtual void ParseWayInLua(ExtractionWay& n, lua_State* luaStateForThread); virtual void ParseWayInLua(ExtractionWay & n, lua_State* thread_lua_state);
virtual void report_errors(lua_State *L, const int status) const; virtual void report_errors(lua_State * lua_state, const int status) const;
protected: protected:
virtual void ReadUseRestrictionsSetting(); virtual void ReadUseRestrictionsSetting();
virtual void ReadRestrictionExceptions(); virtual void ReadRestrictionExceptions();
virtual bool ShouldIgnoreRestriction(const std::string& except_tag_string) const; virtual bool ShouldIgnoreRestriction(
const std::string & except_tag_string
) const;
ExtractorCallbacks* extractor_callbacks; ExtractorCallbacks * extractor_callbacks;
ScriptingEnvironment& scriptingEnvironment; lua_State * lua_state;
lua_State* luaState; ScriptingEnvironment & scripting_environment;
std::vector<std::string> restriction_exceptions; std::vector<std::string> restriction_exceptions;
bool use_turn_restrictions; bool use_turn_restrictions;
}; };
#endif /* BASEPARSER_H_ */ #endif /* BASEPARSER_H_ */
+291 -159
View File
@@ -26,267 +26,385 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "ExtractionContainers.h" #include "ExtractionContainers.h"
#include "ExtractionWay.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
void ExtractionContainers::PrepareData(const std::string & output_file_name, const std::string restrictionsFileName, const unsigned amountOfRAM) { #include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <stxxl/sort>
ExtractionContainers::ExtractionContainers() {
//Check if stxxl can be instantiated
stxxl::vector<unsigned> dummy_vector;
name_list.push_back("");
}
ExtractionContainers::~ExtractionContainers() {
used_node_id_list.clear();
all_nodes_list.clear();
all_edges_list.clear();
name_list.clear();
restrictions_list.clear();
way_start_end_id_list.clear();
}
void ExtractionContainers::PrepareData(
const std::string & output_file_name,
const std::string & restrictions_file_name
) {
try { try {
unsigned usedNodeCounter = 0; unsigned number_of_used_nodes = 0;
unsigned usedEdgeCounter = 0; unsigned number_of_used_edges = 0;
double time = get_timestamp(); 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; 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; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp(); time = get_timestamp();
std::cout << "[extractor] Erasing duplicate nodes ... " << std::flush; std::cout << "[extractor] Erasing duplicate nodes ... " << std::flush;
stxxl::vector<NodeID>::iterator NewEnd = std::unique ( usedNodeIDs.begin(),usedNodeIDs.end() ) ; stxxl::vector<NodeID>::iterator NewEnd = std::unique ( used_node_id_list.begin(),used_node_id_list.end() ) ;
usedNodeIDs.resize ( NewEnd - usedNodeIDs.begin() ); used_node_id_list.resize ( NewEnd - used_node_id_list.begin() );
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp(); time = get_timestamp();
std::cout << "[extractor] Sorting all nodes ... " << std::flush; 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; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp(); time = get_timestamp();
std::cout << "[extractor] Sorting used ways ... " << std::flush; 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 << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] Sorting restrctns. by from... " << std::flush; 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 << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] Fixing restriction starts ... " << std::flush; std::cout << "[extractor] Fixing restriction starts ... " << std::flush;
STXXLRestrictionsVector::iterator restrictionsIT = restrictionsVector.begin(); STXXLRestrictionsVector::iterator restrictions_iterator = restrictions_list.begin();
STXXLWayIDStartEndVector::iterator wayStartAndEndEdgeIT = wayStartEndVector.begin(); STXXLWayIDStartEndVector::iterator way_start_and_end_iterator = way_start_end_id_list.begin();
while(wayStartAndEndEdgeIT != wayStartEndVector.end() && restrictionsIT != restrictionsVector.end()) { while(
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->fromWay){ way_start_and_end_iterator != way_start_end_id_list.end() &&
++wayStartAndEndEdgeIT; restrictions_iterator != restrictions_list.end()
) {
if(way_start_and_end_iterator->wayID < restrictions_iterator->fromWay){
++way_start_and_end_iterator;
continue; continue;
} }
if(wayStartAndEndEdgeIT->wayID > restrictionsIT->fromWay) {
++restrictionsIT; if(way_start_and_end_iterator->wayID > restrictions_iterator->fromWay) {
++restrictions_iterator;
continue; continue;
} }
assert(wayStartAndEndEdgeIT->wayID == restrictionsIT->fromWay);
NodeID viaNode = restrictionsIT->restriction.viaNode;
if(wayStartAndEndEdgeIT->firstStart == viaNode) { BOOST_ASSERT(way_start_and_end_iterator->wayID == restrictions_iterator->fromWay);
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->firstTarget; NodeID via_node_id = restrictions_iterator->restriction.viaNode;
} else if(wayStartAndEndEdgeIT->firstTarget == viaNode) {
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->firstStart; if(way_start_and_end_iterator->firstStart == via_node_id) {
} else if(wayStartAndEndEdgeIT->lastStart == viaNode) { restrictions_iterator->restriction.fromNode = way_start_and_end_iterator->firstTarget;
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->lastTarget; } else if(way_start_and_end_iterator->firstTarget == via_node_id) {
} else if(wayStartAndEndEdgeIT->lastTarget == viaNode) { restrictions_iterator->restriction.fromNode = way_start_and_end_iterator->firstStart;
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->lastStart; } 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; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp(); time = get_timestamp();
std::cout << "[extractor] Sorting restrctns. by to ... " << std::flush; 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; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp(); time = get_timestamp();
unsigned usableRestrictionsCounter(0); unsigned usableRestrictionsCounter(0);
std::cout << "[extractor] Fixing restriction ends ... " << std::flush; std::cout << "[extractor] Fixing restriction ends ... " << std::flush;
restrictionsIT = restrictionsVector.begin(); restrictions_iterator = restrictions_list.begin();
wayStartAndEndEdgeIT = wayStartEndVector.begin(); way_start_and_end_iterator = way_start_end_id_list.begin();
while(wayStartAndEndEdgeIT != wayStartEndVector.end() && restrictionsIT != restrictionsVector.end()) { while(
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->toWay){ way_start_and_end_iterator != way_start_end_id_list.end() &&
++wayStartAndEndEdgeIT; restrictions_iterator != restrictions_list.end()
) {
if(way_start_and_end_iterator->wayID < restrictions_iterator->toWay){
++way_start_and_end_iterator;
continue; continue;
} }
if(wayStartAndEndEdgeIT->wayID > restrictionsIT->toWay) { if(way_start_and_end_iterator->wayID > restrictions_iterator->toWay) {
++restrictionsIT; ++restrictions_iterator;
continue; continue;
} }
NodeID viaNode = restrictionsIT->restriction.viaNode; NodeID via_node_id = restrictions_iterator->restriction.viaNode;
if(wayStartAndEndEdgeIT->lastStart == viaNode) { if(way_start_and_end_iterator->lastStart == via_node_id) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->lastTarget; restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastTarget;
} else if(wayStartAndEndEdgeIT->lastTarget == viaNode) { } else if(way_start_and_end_iterator->lastTarget == via_node_id) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->lastStart; restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastStart;
} else if(wayStartAndEndEdgeIT->firstStart == viaNode) { } else if(way_start_and_end_iterator->firstStart == via_node_id) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstTarget; restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstTarget;
} else if(wayStartAndEndEdgeIT->firstTarget == viaNode) { } else if(way_start_and_end_iterator->firstTarget == via_node_id) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstStart; restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstStart;
} }
if( if(
UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictions_iterator->restriction.fromNode &&
UINT_MAX != restrictionsIT->restriction.toNode UINT_MAX != restrictions_iterator->restriction.toNode
) { ) {
++usableRestrictionsCounter; ++usableRestrictionsCounter;
} }
++restrictionsIT; ++restrictions_iterator;
} }
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
SimpleLogger().Write() << "usable restrictions: " << usableRestrictionsCounter; SimpleLogger().Write() << "usable restrictions: " << usableRestrictionsCounter;
//serialize restrictions //serialize restrictions
std::ofstream restrictionsOutstream; std::ofstream restrictions_out_stream;
restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary); restrictions_out_stream.open(restrictions_file_name.c_str(), std::ios::binary);
restrictionsOutstream.write((char*)&uuid, sizeof(UUID)); restrictions_out_stream.write((char*)&uuid, sizeof(UUID));
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned)); restrictions_out_stream.write(
(char*)&usableRestrictionsCounter,
sizeof(unsigned)
);
for( for(
restrictionsIT = restrictionsVector.begin(); restrictions_iterator = restrictions_list.begin();
restrictionsIT != restrictionsVector.end(); restrictions_iterator != restrictions_list.end();
++restrictionsIT ++restrictions_iterator
) { ) {
if( if(
UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictions_iterator->restriction.fromNode &&
UINT_MAX != restrictionsIT->restriction.toNode 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; std::ofstream file_out_stream;
fout.open(output_file_name.c_str(), std::ios::binary); file_out_stream.open(output_file_name.c_str(), std::ios::binary);
fout.write((char*)&uuid, sizeof(UUID)); file_out_stream.write((char*)&uuid, sizeof(UUID));
fout.write((char*)&usedNodeCounter, sizeof(unsigned)); file_out_stream.write((char*)&number_of_used_nodes, sizeof(unsigned));
time = get_timestamp(); time = get_timestamp();
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush; std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
STXXLNodeVector::iterator nodesIT = allNodes.begin(); //identify all used nodes by a merging step of two sorted lists
STXXLNodeIDVector::iterator usedNodeIDsIT = usedNodeIDs.begin(); STXXLNodeVector::iterator node_iterator = all_nodes_list.begin();
while(usedNodeIDsIT != usedNodeIDs.end() && nodesIT != allNodes.end()) { STXXLNodeIDVector::iterator node_id_iterator = used_node_id_list.begin();
if(*usedNodeIDsIT < nodesIT->id){ while(
++usedNodeIDsIT; 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; continue;
} }
if(*usedNodeIDsIT > nodesIT->id) { if(*node_id_iterator > node_iterator->id) {
++nodesIT; ++node_iterator;
continue; continue;
} }
if(*usedNodeIDsIT == nodesIT->id) { BOOST_ASSERT( *node_id_iterator == node_iterator->id);
fout.write((char*)&(*nodesIT), sizeof(_Node));
++usedNodeCounter; file_out_stream.write(
++usedNodeIDsIT; (char*)&(*node_iterator),
++nodesIT; sizeof(ExternalMemoryNode)
} );
++number_of_used_nodes;
++node_id_iterator;
++node_iterator;
} }
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] setting number of nodes ... " << std::flush; std::cout << "[extractor] setting number of nodes ... " << std::flush;
std::ios::pos_type positionInFile = fout.tellp(); std::ios::pos_type previous_file_position = file_out_stream.tellp();
fout.seekp(std::ios::beg+sizeof(UUID)); file_out_stream.seekp(std::ios::beg+sizeof(UUID));
fout.write((char*)&usedNodeCounter, sizeof(unsigned)); file_out_stream.write((char*)&number_of_used_nodes, sizeof(unsigned));
fout.seekp(positionInFile); file_out_stream.seekp(previous_file_position);
std::cout << "ok" << std::endl; std::cout << "ok" << std::endl;
time = get_timestamp(); time = get_timestamp();
// Sort edges by start. // Sort edges by start.
std::cout << "[extractor] Sorting edges by start ... " << std::flush; 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; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp(); time = get_timestamp();
std::cout << "[extractor] Setting start coords ... " << std::flush; 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 // Traverse list of edges and nodes in parallel and set start coord
nodesIT = allNodes.begin(); node_iterator = all_nodes_list.begin();
STXXLEdgeVector::iterator edgeIT = allEdges.begin(); STXXLEdgeVector::iterator edge_iterator = all_edges_list.begin();
while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) { while(
if(edgeIT->start < nodesIT->id){ edge_iterator != all_edges_list.end() &&
++edgeIT; node_iterator != all_nodes_list.end()
) {
if(edge_iterator->start < node_iterator->id){
++edge_iterator;
continue; continue;
} }
if(edgeIT->start > nodesIT->id) { if(edge_iterator->start > node_iterator->id) {
nodesIT++; node_iterator++;
continue; continue;
} }
if(edgeIT->start == nodesIT->id) {
edgeIT->startCoord.lat = nodesIT->lat; BOOST_ASSERT(edge_iterator->start == node_iterator->id);
edgeIT->startCoord.lon = nodesIT->lon; edge_iterator->startCoord.lat = node_iterator->lat;
++edgeIT; edge_iterator->startCoord.lon = node_iterator->lon;
} ++edge_iterator;
} }
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp(); time = get_timestamp();
// Sort Edges by target // Sort Edges by target
std::cout << "[extractor] Sorting edges by target ... " << std::flush; 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; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp(); time = get_timestamp();
std::cout << "[extractor] Setting target coords ... " << std::flush; std::cout << "[extractor] Setting target coords ... " << std::flush;
// Traverse list of edges and nodes in parallel and set target coord // Traverse list of edges and nodes in parallel and set target coord
nodesIT = allNodes.begin(); node_iterator = all_nodes_list.begin();
edgeIT = allEdges.begin(); edge_iterator = all_edges_list.begin();
while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) { while(
if(edgeIT->target < nodesIT->id){ edge_iterator != all_edges_list.end() &&
++edgeIT; node_iterator != all_nodes_list.end()
) {
if(edge_iterator->target < node_iterator->id){
++edge_iterator;
continue; continue;
} }
if(edgeIT->target > nodesIT->id) { if(edge_iterator->target > node_iterator->id) {
++nodesIT; ++node_iterator;
continue; continue;
} }
if(edgeIT->target == nodesIT->id) { BOOST_ASSERT(edge_iterator->target == node_iterator->id);
if(edgeIT->startCoord.lat != INT_MIN && edgeIT->startCoord.lon != INT_MIN) { if(edge_iterator->startCoord.lat != INT_MIN && edge_iterator->startCoord.lon != INT_MIN) {
edgeIT->targetCoord.lat = nodesIT->lat; edge_iterator->targetCoord.lat = node_iterator->lat;
edgeIT->targetCoord.lon = nodesIT->lon; edge_iterator->targetCoord.lon = node_iterator->lon;
double distance = ApproximateDistance(edgeIT->startCoord.lat, edgeIT->startCoord.lon, nodesIT->lat, nodesIT->lon); const double distance = FixedPointCoordinate::ApproximateDistance(
assert(edgeIT->speed != -1); edge_iterator->startCoord.lat,
double weight = ( distance * 10. ) / (edgeIT->speed / 3.6); edge_iterator->startCoord.lon,
int intWeight = std::max(1, (int)std::floor((edgeIT->isDurationSet ? edgeIT->speed : weight)+.5) ); node_iterator->lat,
int intDist = std::max(1, (int)distance); node_iterator->lon
short zero = 0; );
short one = 1;
fout.write((char*)&edgeIT->start, sizeof(unsigned)); BOOST_ASSERT(edge_iterator->speed != -1);
fout.write((char*)&edgeIT->target, sizeof(unsigned)); const double weight = ( distance * 10. ) / (edge_iterator->speed / 3.6);
fout.write((char*)&intDist, sizeof(int)); int integer_weight = std::max( 1, (int)std::floor((edge_iterator->isDurationSet ? edge_iterator->speed : weight)+.5) );
switch(edgeIT->direction) { int integer_distance = std::max( 1, (int)distance );
case ExtractionWay::notSure: short zero = 0;
fout.write((char*)&zero, sizeof(short)); short one = 1;
break;
case ExtractionWay::oneway:
fout.write((char*)&one, sizeof(short));
break;
case ExtractionWay::bidirectional:
fout.write((char*)&zero, sizeof(short));
break; file_out_stream.write((char*)&edge_iterator->start, sizeof(unsigned));
case ExtractionWay::opposite: file_out_stream.write((char*)&edge_iterator->target, sizeof(unsigned));
fout.write((char*)&one, sizeof(short)); file_out_stream.write((char*)&integer_distance, sizeof(int));
break; switch(edge_iterator->direction) {
default: case ExtractionWay::notSure:
std::cerr << "[error] edge with no direction: " << edgeIT->direction << std::endl; file_out_stream.write((char*)&zero, sizeof(short));
assert(false); break;
break; case ExtractionWay::oneway:
} file_out_stream.write((char*)&one, sizeof(short));
fout.write((char*)&intWeight, sizeof(int)); break;
assert(edgeIT->type >= 0); case ExtractionWay::bidirectional:
fout.write((char*)&edgeIT->type, sizeof(short)); file_out_stream.write((char*)&zero, sizeof(short));
fout.write((char*)&edgeIT->nameID, sizeof(unsigned));
fout.write((char*)&edgeIT->isRoundabout, sizeof(bool)); break;
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool)); case ExtractionWay::opposite:
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool)); file_out_stream.write((char*)&one, sizeof(short));
fout.write((char*)&edgeIT->isContraFlow, sizeof(bool)); break;
++usedEdgeCounter; default:
throw OSRMException("edge has broken direction");
} }
++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)
);
file_out_stream.write(
(char *) &edge_iterator->is_split,
sizeof(bool)
);
++number_of_used_edges;
} }
++edge_iterator;
} }
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] setting number of edges ... " << std::flush; std::cout << "[extractor] setting number of edges ... " << std::flush;
fout.seekp(positionInFile); file_out_stream.seekp(previous_file_position);
fout.write((char*)&usedEdgeCounter, sizeof(unsigned)); file_out_stream.write((char*)&number_of_used_edges, sizeof(unsigned));
fout.close(); file_out_stream.close();
std::cout << "ok" << std::endl; std::cout << "ok" << std::endl;
time = get_timestamp(); time = get_timestamp();
@@ -297,32 +415,46 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con
std::ios::binary std::ios::binary
); );
const unsigned number_of_ways = name_list.size()+1; //write number of names
name_file_stream.write((char *)&(number_of_ways), sizeof(unsigned)); 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; 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( name_file_stream.write(
(char *)&(name_lengths_prefix_sum), (char *)&(name_lengths_prefix_sum),
sizeof(unsigned) sizeof(unsigned)
); );
name_lengths_prefix_sum += strlen(str.c_str()); name_lengths_prefix_sum += temp_string.length();
} }
//duplicate on purpose!
name_file_stream.write( name_file_stream.write(
(char *)&(name_lengths_prefix_sum), (char *)&(name_lengths_prefix_sum),
sizeof(unsigned) sizeof(unsigned)
); );
//duplicate on purpose!
name_file_stream.write((char *)&(name_lengths_prefix_sum), sizeof(unsigned)); //write all chars consecutively
BOOST_FOREACH(const std::string & str, name_list) { BOOST_FOREACH(const std::string & temp_string, name_list) {
const unsigned lengthOfRawString = strlen(str.c_str()); const unsigned string_length = temp_string.length();
name_file_stream.write(str.c_str(), lengthOfRawString); name_file_stream.write(temp_string.c_str(), string_length);
} }
name_file_stream.close(); name_file_stream.close();
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
SimpleLogger().Write() << SimpleLogger().Write() << "Processed " <<
"Processed " << usedNodeCounter << " nodes and " << usedEdgeCounter << " edges"; number_of_used_nodes << " nodes and " <<
number_of_used_edges << " edges";
} catch ( const std::exception& e ) { } catch ( const std::exception& e ) {
std::cerr << "Caught Execption:" << e.what() << std::endl; std::cerr << "Caught Execption:" << e.what() << std::endl;
+17 -33
View File
@@ -28,53 +28,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef EXTRACTIONCONTAINERS_H_ #ifndef EXTRACTIONCONTAINERS_H_
#define EXTRACTIONCONTAINERS_H_ #define EXTRACTIONCONTAINERS_H_
#include "InternalExtractorEdge.h"
#include "ExtractorStructs.h" #include "ExtractorStructs.h"
#include "../Util/SimpleLogger.h" #include "../DataStructures/Restriction.h"
#include "../Util/TimingUtil.h"
#include "../Util/UUID.h" #include "../Util/UUID.h"
#include <boost/foreach.hpp> #include <stxxl/vector>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <stxxl.h>
class ExtractionContainers { class ExtractionContainers {
public: public:
typedef stxxl::vector<NodeID> STXXLNodeIDVector; typedef stxxl::vector<NodeID> STXXLNodeIDVector;
typedef stxxl::vector<_Node> STXXLNodeVector; typedef stxxl::vector<ExternalMemoryNode> STXXLNodeVector;
typedef stxxl::vector<InternalExtractorEdge> STXXLEdgeVector; typedef stxxl::vector<InternalExtractorEdge> STXXLEdgeVector;
typedef stxxl::vector<std::string> STXXLStringVector; typedef stxxl::vector<std::string> STXXLStringVector;
typedef stxxl::vector<_RawRestrictionContainer> STXXLRestrictionsVector; typedef stxxl::vector<InputRestrictionContainer> STXXLRestrictionsVector;
typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector; typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
STXXLNodeIDVector used_node_id_list;
STXXLNodeIDVector usedNodeIDs; STXXLNodeVector all_nodes_list;
STXXLNodeVector allNodes; STXXLEdgeVector all_edges_list;
STXXLEdgeVector allEdges;
STXXLStringVector name_list; STXXLStringVector name_list;
STXXLRestrictionsVector restrictionsVector; STXXLRestrictionsVector restrictions_list;
STXXLWayIDStartEndVector wayStartEndVector; STXXLWayIDStartEndVector way_start_end_id_list;
const UUID uuid; const UUID uuid;
ExtractionContainers() { ExtractionContainers();
//Check if another instance of stxxl is already running or if there is a general problem
stxxl::vector<unsigned> testForRunningInstance;
name_list.push_back("");
}
virtual ~ExtractionContainers() { virtual ~ExtractionContainers();
usedNodeIDs.clear();
allNodes.clear();
allEdges.clear();
name_list.clear();
restrictionsVector.clear();
wayStartEndVector.clear();
}
void PrepareData( void PrepareData(
const std::string & output_file_name, const std::string & output_file_name,
const std::string restrictionsFileName, const std::string & restrictions_file_name
const unsigned amountOfRAM
); );
}; };
+8 -8
View File
@@ -75,13 +75,13 @@ inline unsigned parseDuration(const std::string &s) {
return UINT_MAX; return UINT_MAX;
} }
inline int parseMaxspeed(std::string input) { //call-by-value on purpose. // inline int parseMaxspeed(std::string input) { //call-by-value on purpose.
boost::algorithm::to_lower(input); // boost::algorithm::to_lower(input);
int n = stringToInt(input); // int n = stringToInt(input);
if (input.find("mph") != std::string::npos || input.find("mp/h") != std::string::npos) { // if (input.find("mph") != std::string::npos || input.find("mp/h") != std::string::npos) {
n = (n*1609)/1000; // n = (n*1609)/1000;
} // }
return n; // return n;
} // }
#endif /* EXTRACTIONHELPERFUNCTIONS_H_ */ #endif /* EXTRACTIONHELPERFUNCTIONS_H_ */
+78
View File
@@ -0,0 +1,78 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EXTRACTION_WAY_H
#define EXTRACTION_WAY_H
#include "../DataStructures/HashTable.h"
#include "../typedefs.h"
#include <string>
#include <vector>
struct ExtractionWay {
ExtractionWay() {
Clear();
}
inline void Clear(){
id = UINT_MAX;
nameID = UINT_MAX;
path.clear();
keyVals.clear();
direction = ExtractionWay::notSure;
speed = -1;
backward_speed = -1;
duration = -1;
type = -1;
access = true;
roundabout = false;
isAccessRestricted = false;
ignoreInGrid = false;
}
enum Directions {
notSure = 0, oneway, bidirectional, opposite
};
unsigned id;
unsigned nameID;
double speed;
double backward_speed;
double duration;
Directions direction;
std::string name;
short type;
bool access;
bool roundabout;
bool isAccessRestricted;
bool ignoreInGrid;
std::vector< NodeID > path;
HashTable<std::string, std::string> keyVals;
};
#endif //EXTRACTION_WAY_H
+64 -40
View File
@@ -26,24 +26,43 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "ExtractorCallbacks.h" #include "ExtractorCallbacks.h"
#include "ExtractionContainers.h"
#include "ExtractionWay.h"
ExtractorCallbacks::ExtractorCallbacks() {externalMemory = NULL; stringMap = NULL; } #include "../DataStructures/Restriction.h"
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap) { #include "../DataStructures/ImportNode.h"
externalMemory = ext; #include "../Util/SimpleLogger.h"
stringMap = strMap;
} #include <osrm/Coordinate.h>
#include <string>
#include <vector>
ExtractorCallbacks::ExtractorCallbacks()
:
string_map(NULL),
externalMemory(NULL)
{ }
ExtractorCallbacks::ExtractorCallbacks(
ExtractionContainers * ext,
boost::unordered_map<std::string, NodeID> * string_map
) :
string_map(string_map),
externalMemory(ext)
{ }
ExtractorCallbacks::~ExtractorCallbacks() { } ExtractorCallbacks::~ExtractorCallbacks() { }
/** warning: caller needs to take care of synchronization! */ /** 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) { 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) { bool ExtractorCallbacks::restrictionFunction(const InputRestrictionContainer &r) {
externalMemory->restrictionsVector.push_back(r); externalMemory->restrictions_list.push_back(r);
return true; return true;
} }
@@ -62,18 +81,18 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
parsed_way.speed = parsed_way.duration/(parsed_way.path.size()-1); parsed_way.speed = parsed_way.duration/(parsed_way.path.size()-1);
} }
if(std::numeric_limits<double>::epsilon() >= fabs(-1. - parsed_way.speed)){ if(std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.speed)){
SimpleLogger().Write(logDEBUG) << SimpleLogger().Write(logDEBUG) <<
"found way with bogus speed, id: " << parsed_way.id; "found way with bogus speed, id: " << parsed_way.id;
return; return;
} }
//Get the unique identifier for the street name //Get the unique identifier for the street name
const StringMap::const_iterator string_map_iterator = stringMap->find(parsed_way.name); const boost::unordered_map<std::string, NodeID>::const_iterator & string_map_iterator = string_map->find(parsed_way.name);
if(stringMap->end() == string_map_iterator) { if(string_map->end() == string_map_iterator) {
parsed_way.nameID = externalMemory->name_list.size(); parsed_way.nameID = externalMemory->name_list.size();
externalMemory->name_list.push_back(parsed_way.name); externalMemory->name_list.push_back(parsed_way.name);
stringMap->insert(std::make_pair(parsed_way.name, parsed_way.nameID)); string_map->insert(std::make_pair(parsed_way.name, parsed_way.nameID));
} else { } else {
parsed_way.nameID = string_map_iterator->second; parsed_way.nameID = string_map_iterator->second;
} }
@@ -86,45 +105,50 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
const bool split_bidirectional_edge = (parsed_way.backward_speed > 0) && (parsed_way.speed != parsed_way.backward_speed); 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) { 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], InternalExtractorEdge(
parsed_way.path[n+1], parsed_way.path[n],
parsed_way.type, parsed_way.path[n+1],
(split_bidirectional_edge ? ExtractionWay::oneway : parsed_way.direction), parsed_way.type,
parsed_way.speed, (split_bidirectional_edge ? ExtractionWay::oneway : parsed_way.direction),
parsed_way.nameID, parsed_way.speed,
parsed_way.roundabout, parsed_way.nameID,
parsed_way.ignoreInGrid, parsed_way.roundabout,
(0 < parsed_way.duration), parsed_way.ignoreInGrid,
parsed_way.isAccessRestricted (0 < parsed_way.duration),
parsed_way.isAccessRestricted,
false,
split_bidirectional_edge
) )
); );
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 //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 if(split_bidirectional_edge) { //Only true if the way should be split
std::reverse( parsed_way.path.begin(), parsed_way.path.end() ); 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) { 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], InternalExtractorEdge(
parsed_way.path[n+1], parsed_way.path[n],
parsed_way.type, parsed_way.path[n+1],
ExtractionWay::oneway, parsed_way.type,
parsed_way.backward_speed, ExtractionWay::oneway,
parsed_way.nameID, parsed_way.backward_speed,
parsed_way.roundabout, parsed_way.nameID,
parsed_way.ignoreInGrid, parsed_way.roundabout,
(0 < parsed_way.duration), parsed_way.ignoreInGrid,
parsed_way.isAccessRestricted, (0 < parsed_way.duration),
(ExtractionWay::oneway == parsed_way.direction) parsed_way.isAccessRestricted,
(ExtractionWay::oneway == parsed_way.direction),
split_bidirectional_edge
) )
); );
} }
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()));
} }
} }
} }
+15 -16
View File
@@ -28,36 +28,35 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef EXTRACTORCALLBACKS_H_ #ifndef EXTRACTORCALLBACKS_H_
#define EXTRACTORCALLBACKS_H_ #define EXTRACTORCALLBACKS_H_
#include "ExtractionContainers.h" #include "../typedefs.h"
#include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h"
#include "../DataStructures/Coordinate.h"
#include <cfloat>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include <boost/unordered_map.hpp>
#include <string> #include <string>
#include <vector>
struct ExternalMemoryNode;
class ExtractionContainers;
struct ExtractionWay;
struct InputRestrictionContainer;
class ExtractorCallbacks{ class ExtractorCallbacks{
private: private:
StringMap * stringMap;
boost::unordered_map<std::string, NodeID> * string_map;
ExtractionContainers * externalMemory; ExtractionContainers * externalMemory;
ExtractorCallbacks(); ExtractorCallbacks();
public: public:
explicit ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap); explicit ExtractorCallbacks(
ExtractionContainers * ext,
boost::unordered_map<std::string, NodeID> * string_map
);
~ExtractorCallbacks(); ~ExtractorCallbacks();
/** warning: caller needs to take care of synchronization! */ /** 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! */ /** warning: caller needs to take care of synchronization! */
void wayFunction(ExtractionWay &w); void wayFunction(ExtractionWay &w);
+40 -138
View File
@@ -28,64 +28,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef EXTRACTORSTRUCTS_H_ #ifndef EXTRACTORSTRUCTS_H_
#define EXTRACTORSTRUCTS_H_ #define EXTRACTORSTRUCTS_H_
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h" #include "../DataStructures/ImportNode.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Restriction.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include <boost/unordered_map.hpp>
#include <climits>
#include <string> #include <string>
typedef boost::unordered_map<std::string, NodeID > StringMap;
typedef boost::unordered_map<std::string, std::pair<int, short> > StringToIntPairMap;
struct ExtractionWay {
ExtractionWay() {
Clear();
}
inline void Clear(){
id = UINT_MAX;
nameID = UINT_MAX;
path.clear();
keyVals.clear();
direction = ExtractionWay::notSure;
speed = -1;
backward_speed = -1;
duration = -1;
type = -1;
access = true;
roundabout = false;
isAccessRestricted = false;
ignoreInGrid = false;
}
enum Directions {
notSure = 0, oneway, bidirectional, opposite
};
Directions direction;
unsigned id;
unsigned nameID;
std::string name;
double speed;
double backward_speed;
double duration;
short type;
bool access;
bool roundabout;
bool isAccessRestricted;
bool ignoreInGrid;
std::vector< NodeID > path;
HashTable<std::string, std::string> keyVals;
};
struct ExtractorRelation { struct ExtractorRelation {
ExtractorRelation() : type(unknown){} ExtractorRelation() : type(unknown){}
enum { enum {
@@ -94,49 +42,34 @@ struct ExtractorRelation {
HashTable<std::string, std::string> keyVals; HashTable<std::string, std::string> keyVals;
}; };
struct InternalExtractorEdge {
InternalExtractorEdge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) {};
InternalExtractorEdge(NodeID s, NodeID t) : start(s), target(t), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) { }
InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp): start(s), target(t), type(tp), direction(d), speed(sp), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) { }
InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar), isContraFlow(false) {
assert(0 <= type);
}
InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar, bool icf): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar), isContraFlow(icf) {
assert(0 <= type);
}
NodeID start;
NodeID target;
short type;
short direction;
double speed;
unsigned nameID;
bool isRoundabout;
bool ignoreInGrid;
bool isDurationSet;
bool isAccessRestricted;
bool isContraFlow;
FixedPointCoordinate startCoord;
FixedPointCoordinate targetCoord;
static InternalExtractorEdge min_value() {
return InternalExtractorEdge(0,0);
}
static InternalExtractorEdge max_value() {
return InternalExtractorEdge((std::numeric_limits<unsigned>::max)(), (std::numeric_limits<unsigned>::max)());
}
};
struct _WayIDStartAndEndEdge { struct _WayIDStartAndEndEdge {
unsigned wayID; unsigned wayID;
NodeID firstStart; NodeID firstStart;
NodeID firstTarget; NodeID firstTarget;
NodeID lastStart; NodeID lastStart;
NodeID lastTarget; NodeID lastTarget;
_WayIDStartAndEndEdge() : wayID(UINT_MAX), firstStart(UINT_MAX), firstTarget(UINT_MAX), lastStart(UINT_MAX), lastTarget(UINT_MAX) {} _WayIDStartAndEndEdge()
_WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt) : wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt) {} :
wayID(UINT_MAX),
firstStart(UINT_MAX),
firstTarget(UINT_MAX),
lastStart(UINT_MAX),
lastTarget(UINT_MAX)
{ }
explicit _WayIDStartAndEndEdge(
unsigned w,
NodeID fs,
NodeID ft,
NodeID ls,
NodeID lt
) :
wayID(w),
firstStart(fs),
firstTarget(ft),
lastStart(ls),
lastTarget(lt)
{ }
static _WayIDStartAndEndEdge min_value() { static _WayIDStartAndEndEdge min_value() {
return _WayIDStartAndEndEdge((std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)()); return _WayIDStartAndEndEdge((std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)(), (std::numeric_limits<unsigned>::min)());
@@ -146,9 +79,12 @@ struct _WayIDStartAndEndEdge {
} }
}; };
struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDStartAndEndEdge, bool> { struct CmpWayByID {
typedef _WayIDStartAndEndEdge value_type; typedef _WayIDStartAndEndEdge value_type;
bool operator () (const _WayIDStartAndEndEdge & a, const _WayIDStartAndEndEdge & b) const { bool operator ()(
const _WayIDStartAndEndEdge & a,
const _WayIDStartAndEndEdge & b
) const {
return a.wayID < b.wayID; return a.wayID < b.wayID;
} }
value_type max_value() { value_type max_value() {
@@ -159,9 +95,12 @@ struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDSta
} }
}; };
struct Cmp : public std::binary_function<NodeID, NodeID, bool> { struct Cmp {
typedef NodeID value_type; typedef NodeID value_type;
bool operator () (const NodeID a, const NodeID b) const { bool operator ()(
const NodeID a,
const NodeID b
) const {
return a < b; return a < b;
} }
value_type max_value() { value_type max_value() {
@@ -172,57 +111,20 @@ struct Cmp : public std::binary_function<NodeID, NodeID, bool> {
} }
}; };
struct CmpNodeByID : public std::binary_function<_Node, _Node, bool> { struct CmpNodeByID {
typedef _Node value_type; typedef ExternalMemoryNode value_type;
bool operator () (const _Node & a, const _Node & b) const { bool operator () (
const ExternalMemoryNode & a,
const ExternalMemoryNode & b
) const {
return a.id < b.id; return a.id < b.id;
} }
value_type max_value() { value_type max_value() {
return _Node::max_value(); return ExternalMemoryNode::max_value();
} }
value_type min_value() { value_type min_value() {
return _Node::min_value(); return ExternalMemoryNode::min_value();
} }
}; };
struct CmpEdgeByStartID : public std::binary_function<InternalExtractorEdge, InternalExtractorEdge, bool> {
typedef InternalExtractorEdge value_type;
bool operator () (const InternalExtractorEdge & a, const InternalExtractorEdge & b) const {
return a.start < b.start;
}
value_type max_value() {
return InternalExtractorEdge::max_value();
}
value_type min_value() {
return InternalExtractorEdge::min_value();
}
};
struct CmpEdgeByTargetID : public std::binary_function<InternalExtractorEdge, InternalExtractorEdge, bool> {
typedef InternalExtractorEdge value_type;
bool operator () (const InternalExtractorEdge & a, const InternalExtractorEdge & b) const {
return a.target < b.target;
}
value_type max_value() {
return InternalExtractorEdge::max_value();
}
value_type min_value() {
return InternalExtractorEdge::min_value();
}
};
inline std::string GetRandomString() {
char s[128];
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 127; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[127] = 0;
return std::string(s);
}
#endif /* EXTRACTORSTRUCTS_H_ */ #endif /* EXTRACTORSTRUCTS_H_ */
+173
View File
@@ -0,0 +1,173 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef INTERNAL_EXTRACTOR_EDGE_H
#define INTERNAL_EXTRACTOR_EDGE_H
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
struct InternalExtractorEdge {
InternalExtractorEdge()
:
start(0),
target(0),
type(0),
direction(0),
speed(0),
nameID(0),
isRoundabout(false),
ignoreInGrid(false),
isDurationSet(false),
isAccessRestricted(false),
isContraFlow(false),
is_split(false)
{ }
explicit InternalExtractorEdge(
NodeID start,
NodeID target,
short type,
short direction,
double speed,
unsigned nameID,
bool isRoundabout,
bool ignoreInGrid,
bool isDurationSet,
bool isAccressRestricted,
bool isContraFlow,
bool is_split
) :
start(start),
target(target),
type(type),
direction(direction),
speed(speed),
nameID(nameID),
isRoundabout(isRoundabout),
ignoreInGrid(ignoreInGrid),
isDurationSet(isDurationSet),
isAccessRestricted(isAccressRestricted),
isContraFlow(isContraFlow),
is_split(is_split)
{
BOOST_ASSERT(0 <= type);
}
// necessary static util functions for stxxl's sorting
static InternalExtractorEdge min_value() {
return InternalExtractorEdge(
0,
0,
0,
0,
0,
0,
false,
false,
false,
false,
false,
false
);
}
static InternalExtractorEdge max_value() {
return InternalExtractorEdge(
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max(),
0,
0,
0,
0,
false,
false,
false,
false,
false,
false
);
}
NodeID start;
NodeID target;
short type;
short direction;
double speed;
unsigned nameID;
bool isRoundabout;
bool ignoreInGrid;
bool isDurationSet;
bool isAccessRestricted;
bool isContraFlow;
bool is_split;
FixedPointCoordinate startCoord;
FixedPointCoordinate targetCoord;
};
struct CmpEdgeByStartID {
typedef InternalExtractorEdge value_type;
bool operator ()(
const InternalExtractorEdge & a,
const InternalExtractorEdge & b
) const {
return a.start < b.start;
}
value_type max_value() {
return InternalExtractorEdge::max_value();
}
value_type min_value() {
return InternalExtractorEdge::min_value();
}
};
struct CmpEdgeByTargetID {
typedef InternalExtractorEdge value_type;
bool operator ()(
const InternalExtractorEdge & a,
const InternalExtractorEdge & b
) const {
return a.target < b.target;
}
value_type max_value() {
return InternalExtractorEdge::max_value();
}
value_type min_value() {
return InternalExtractorEdge::min_value();
}
};
#endif //INTERNAL_EXTRACTOR_EDGE_H
+69 -38
View File
@@ -27,21 +27,46 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "PBFParser.h" #include "PBFParser.h"
PBFParser::PBFParser(const char * fileName, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser( ec, se ) { #include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/Restriction.h"
#include "../Util/MachineInfo.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <boost/ref.hpp>
#include <zlib.h>
PBFParser::PBFParser(
const char * fileName,
ExtractorCallbacks * extractor_callbacks,
ScriptingEnvironment& scripting_environment
) : BaseParser( extractor_callbacks, scripting_environment ) {
GOOGLE_PROTOBUF_VERIFY_VERSION; GOOGLE_PROTOBUF_VERIFY_VERSION;
//TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk? //TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
//NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free. //NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
threadDataQueue = boost::make_shared<ConcurrentQueue<_ThreadData*> >( 2500 ); /* Max 2500 items in queue, hardcoded. */
// Max 2500 items in queue, hardcoded.
threadDataQueue = boost::make_shared<ConcurrentQueue<_ThreadData*> >( 2500 );
input.open(fileName, std::ios::in | std::ios::binary); input.open(fileName, std::ios::in | std::ios::binary);
if (!input) { if (!input) {
throw OSRMException("pbf file not found."); throw OSRMException("pbf file not found.");
} }
#ifndef NDEBUG
blockCount = 0; blockCount = 0;
groupCount = 0; groupCount = 0;
#endif
} }
PBFParser::~PBFParser() { PBFParser::~PBFParser() {
@@ -50,18 +75,17 @@ PBFParser::~PBFParser() {
} }
// Clean up any leftover ThreadData objects in the queue // Clean up any leftover ThreadData objects in the queue
_ThreadData* td; _ThreadData* thread_data;
while (threadDataQueue->try_pop(td)) { while (threadDataQueue->try_pop(thread_data))
delete td; {
delete thread_data;
} }
google::protobuf::ShutdownProtobufLibrary(); google::protobuf::ShutdownProtobufLibrary();
#ifndef NDEBUG
SimpleLogger().Write(logDEBUG) << SimpleLogger().Write(logDEBUG) <<
"parsed " << blockCount << "parsed " << blockCount <<
" blocks from pbf with " << groupCount << " blocks from pbf with " << groupCount <<
" groups"; " groups";
#endif
} }
inline bool PBFParser::ReadHeader() { inline bool PBFParser::ReadHeader() {
@@ -191,22 +215,26 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
denseTagIndex += 2; denseTagIndex += 2;
} }
} }
#pragma omp parallel
{
const int thread_num = omp_get_thread_num();
#pragma omp parallel for schedule ( guided ) #pragma omp parallel for schedule ( guided )
for(int i = 0; i < number_of_nodes; ++i) { for(int i = 0; i < number_of_nodes; ++i)
ImportNode &n = extracted_nodes_vector[i]; {
ParseNodeInLua( n, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) ); ImportNode & import_node = extracted_nodes_vector[i];
} ParseNodeInLua(import_node, scripting_environment.getLuaStateForThreadID(thread_num));
BOOST_FOREACH(const ImportNode &n, extracted_nodes_vector) {
extractor_callbacks->nodeFunction(n);
} }
} }
inline void PBFParser::parseNode(_ThreadData * ) { BOOST_FOREACH(const ImportNode &import_node, extracted_nodes_vector)
throw OSRMException( {
"Parsing of simple nodes not supported. PBF should use dense nodes" extractor_callbacks->nodeFunction(import_node);
); }
}
inline void PBFParser::parseNode(_ThreadData * )
{
throw OSRMException("Parsing of simple nodes not supported. PBF should use dense nodes");
} }
inline void PBFParser::parseRelation(_ThreadData * threadData) { inline void PBFParser::parseRelation(_ThreadData * threadData) {
@@ -232,12 +260,12 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
break; break;
} }
} }
if ("restriction" == key) { if ( ("restriction" == key) && (val.find("only_") == 0) )
if(val.find("only_") == 0) { {
isOnlyRestriction = true; isOnlyRestriction = true;
}
} }
if ("except" == key) { if ("except" == key)
{
except_tag_string = val; except_tag_string = val;
} }
} }
@@ -248,7 +276,7 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
if(isRestriction) { if(isRestriction) {
int64_t lastRef = 0; int64_t lastRef = 0;
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction); InputRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
for( for(
int rolesIndex = 0, last_role = inputRelation.roles_sid_size(); int rolesIndex = 0, last_role = inputRelation.roles_sid_size();
rolesIndex < last_role; rolesIndex < last_role;
@@ -325,19 +353,24 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
} }
#pragma omp parallel for schedule ( guided ) #pragma omp parallel for schedule ( guided )
for(int i = 0; i < number_of_ways; ++i) { for(int i = 0; i < number_of_ways; ++i)
ExtractionWay & w = parsed_way_vector[i]; {
if(2 > w.path.size()) { ExtractionWay & extraction_way = parsed_way_vector[i];
continue; if (2 <= extraction_way.path.size())
{
ParseWayInLua(
extraction_way,
scripting_environment.getLuaStateForThreadID(omp_get_thread_num())
);
} }
ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID( omp_get_thread_num()) );
} }
BOOST_FOREACH(ExtractionWay & w, parsed_way_vector) { BOOST_FOREACH(ExtractionWay & extraction_way, parsed_way_vector)
if(2 > w.path.size()) { {
continue; if (2 <= extraction_way.path.size())
{
extractor_callbacks->wayFunction(extraction_way);
} }
extractor_callbacks->wayFunction(w);
} }
} }
@@ -365,9 +398,7 @@ inline void PBFParser::loadGroup(_ThreadData * threadData) {
} }
inline void PBFParser::loadBlock(_ThreadData * threadData) { inline void PBFParser::loadBlock(_ThreadData * threadData) {
#ifndef NDEBUG
++blockCount; ++blockCount;
#endif
threadData->currentGroupID = 0; threadData->currentGroupID = 0;
threadData->currentEntityID = 0; threadData->currentEntityID = 0;
} }
+12 -21
View File
@@ -29,24 +29,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define PBFPARSER_H_ #define PBFPARSER_H_
#include "BaseParser.h" #include "BaseParser.h"
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ConcurrentQueue.h" #include "../DataStructures/ConcurrentQueue.h"
#include "../Util/MachineInfo.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/ref.hpp>
#include <osmpbf/fileformat.pb.h> #include <osmpbf/fileformat.pb.h>
#include <osmpbf/osmformat.pb.h> #include <osmpbf/osmformat.pb.h>
#include <zlib.h> #include <fstream>
class PBFParser : public BaseParser { class PBFParser : public BaseParser {
@@ -73,7 +63,11 @@ class PBFParser : public BaseParser {
}; };
public: public:
PBFParser(const char * fileName, ExtractorCallbacks* ec, ScriptingEnvironment& se); PBFParser(
const char * fileName,
ExtractorCallbacks* ec,
ScriptingEnvironment& se
);
virtual ~PBFParser(); virtual ~PBFParser();
inline bool ReadHeader(); inline bool ReadHeader();
@@ -82,13 +76,13 @@ public:
private: private:
inline void ReadData(); inline void ReadData();
inline void ParseData(); inline void ParseData();
inline void parseDenseNode (_ThreadData * threadData); inline void parseDenseNode (_ThreadData * threadData);
inline void parseNode (_ThreadData * threadData); inline void parseNode (_ThreadData * threadData);
inline void parseRelation (_ThreadData * threadData); inline void parseRelation (_ThreadData * threadData);
inline void parseWay (_ThreadData * threadData); inline void parseWay (_ThreadData * threadData);
inline void loadGroup (_ThreadData * threadData); inline void loadGroup (_ThreadData * threadData);
inline void loadBlock (_ThreadData * threadData); inline void loadBlock (_ThreadData * threadData);
inline bool readPBFBlobHeader(std::fstream & stream, _ThreadData * threadData); inline bool readPBFBlobHeader(std::fstream & stream, _ThreadData * threadData);
inline bool unpackZLIB (std::fstream & stream, _ThreadData * threadData); inline bool unpackZLIB (std::fstream & stream, _ThreadData * threadData);
inline bool unpackLZMA (std::fstream & stream, _ThreadData * threadData); inline bool unpackLZMA (std::fstream & stream, _ThreadData * threadData);
@@ -99,11 +93,8 @@ private:
static const int MAX_BLOB_HEADER_SIZE = 64 * 1024; static const int MAX_BLOB_HEADER_SIZE = 64 * 1024;
static const int MAX_BLOB_SIZE = 32 * 1024 * 1024; static const int MAX_BLOB_SIZE = 32 * 1024 * 1024;
#ifndef NDEBUG
/* counting the number of read blocks and groups */
unsigned groupCount; unsigned groupCount;
unsigned blockCount; unsigned blockCount;
#endif
std::fstream input; // the input stream to parse std::fstream input; // the input stream to parse
boost::shared_ptr<ConcurrentQueue < _ThreadData* > > threadDataQueue; boost::shared_ptr<ConcurrentQueue < _ThreadData* > > threadDataQueue;
+13 -3
View File
@@ -27,6 +27,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ScriptingEnvironment.h" #include "ScriptingEnvironment.h"
#include "ExtractionHelperFunctions.h"
#include "ExtractionWay.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
ScriptingEnvironment::ScriptingEnvironment() {} ScriptingEnvironment::ScriptingEnvironment() {}
ScriptingEnvironment::ScriptingEnvironment(const char * fileName) { ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
SimpleLogger().Write() << "Using script " << fileName; SimpleLogger().Write() << "Using script " << fileName;
@@ -49,7 +58,6 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
// Add our function to the state's global scope // Add our function to the state's global scope
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::def("print", LUA_print<std::string>), luabind::def("print", LUA_print<std::string>),
luabind::def("parseMaxspeed", parseMaxspeed),
luabind::def("durationIsValid", durationIsValid), luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration) luabind::def("parseDuration", parseDuration)
]; ];
@@ -66,7 +74,7 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
.def(luabind::constructor<>()) .def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat) .def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon) .def_readwrite("lon", &ImportNode::lon)
.def_readwrite("id", &ImportNode::id) .def_readonly("id", &ImportNode::id)
.def_readwrite("bollard", &ImportNode::bollard) .def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight) .def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals) .def_readwrite("tags", &ImportNode::keyVals)
@@ -75,6 +83,7 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<ExtractionWay>("Way") luabind::class_<ExtractionWay>("Way")
.def(luabind::constructor<>()) .def(luabind::constructor<>())
.def_readonly("id", &ExtractionWay::id)
.def_readwrite("name", &ExtractionWay::name) .def_readwrite("name", &ExtractionWay::name)
.def_readwrite("speed", &ExtractionWay::speed) .def_readwrite("speed", &ExtractionWay::speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed) .def_readwrite("backward_speed", &ExtractionWay::backward_speed)
@@ -94,9 +103,10 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
] ]
]; ];
// fails on c++11/OS X 10.9
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<std::vector<std::string> >("vector") luabind::class_<std::vector<std::string> >("vector")
.def("Add", &std::vector<std::string>::push_back) .def("Add", static_cast<void (std::vector<std::string>::*)(const std::string&)>(&std::vector<std::string>::push_back))
]; ];
if(0 != luaL_dofile(myLuaState, fileName) ) { if(0 != luaL_dofile(myLuaState, fileName) ) {
+3 -10
View File
@@ -28,21 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SCRIPTINGENVIRONMENT_H_ #ifndef SCRIPTINGENVIRONMENT_H_
#define SCRIPTINGENVIRONMENT_H_ #define SCRIPTINGENVIRONMENT_H_
#include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <vector> #include <vector>
struct lua_State;
class ScriptingEnvironment { class ScriptingEnvironment {
public: public:
ScriptingEnvironment(); ScriptingEnvironment();
ScriptingEnvironment(const char * fileName); explicit ScriptingEnvironment(const char * fileName);
virtual ~ScriptingEnvironment(); virtual ~ScriptingEnvironment();
lua_State * getLuaStateForThreadID(const int); lua_State * getLuaStateForThreadID(const int);
+287 -223
View File
@@ -27,258 +27,322 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "XMLParser.h" #include "XMLParser.h"
#include "ExtractorStructs.h" #include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/InputReaderFactory.h" #include "../DataStructures/InputReaderFactory.h"
#include "../DataStructures/Restriction.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/ref.hpp> #include <boost/ref.hpp>
XMLParser::XMLParser(const char * filename, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser(ec, se) { XMLParser::XMLParser(const char *filename, ExtractorCallbacks *ec, ScriptingEnvironment &se)
SimpleLogger().Write(logWARNING) << : BaseParser(ec, se)
"Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf"; {
inputReader = inputReaderFactory(filename);
inputReader = inputReaderFactory(filename);
} }
bool XMLParser::ReadHeader() { bool XMLParser::ReadHeader() { return (xmlTextReaderRead(inputReader) == 1); }
return (xmlTextReaderRead( inputReader ) == 1); bool XMLParser::Parse()
} {
bool XMLParser::Parse() { while (xmlTextReaderRead(inputReader) == 1)
while ( xmlTextReaderRead( inputReader ) == 1 ) { {
const int type = xmlTextReaderNodeType( inputReader ); const int type = xmlTextReaderNodeType(inputReader);
//1 is Element // 1 is Element
if ( type != 1 ) { if (type != 1)
continue; {
} continue;
}
xmlChar* currentName = xmlTextReaderName( inputReader ); xmlChar *currentName = xmlTextReaderName(inputReader);
if ( currentName == NULL ) { if (currentName == NULL)
continue; {
} continue;
}
if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) { if (xmlStrEqual(currentName, (const xmlChar *)"node") == 1)
ImportNode n = _ReadXMLNode(); {
ParseNodeInLua( n, luaState ); ImportNode n = ReadXMLNode();
extractor_callbacks->nodeFunction(n); ParseNodeInLua(n, lua_state);
// if(!extractor_callbacks->nodeFunction(n)) extractor_callbacks->nodeFunction(n);
// std::cerr << "[XMLParser] dense node not parsed" << std::endl; }
}
if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) { if (xmlStrEqual(currentName, (const xmlChar *)"way") == 1)
ExtractionWay way = _ReadXMLWay( ); {
ParseWayInLua( way, luaState ); ExtractionWay way = ReadXMLWay();
extractor_callbacks->wayFunction(way); ParseWayInLua(way, lua_state);
// if(!extractor_callbacks->wayFunction(way)) extractor_callbacks->wayFunction(way);
// std::cerr << "[PBFParser] way not parsed" << std::endl; }
} if (use_turn_restrictions && xmlStrEqual(currentName, (const xmlChar *)"relation") == 1)
if( use_turn_restrictions ) { {
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) { InputRestrictionContainer r = ReadXMLRestriction();
_RawRestrictionContainer r = _ReadXMLRestriction(); if ((UINT_MAX != r.fromWay) && !extractor_callbacks->restrictionFunction(r))
if(r.fromWay != UINT_MAX) { {
if(!extractor_callbacks->restrictionFunction(r)) { std::cerr << "[XMLParser] restriction not parsed" << std::endl;
std::cerr << "[XMLParser] restriction not parsed" << std::endl; }
} }
} xmlFree(currentName);
} }
} return true;
xmlFree( currentName );
}
return true;
} }
_RawRestrictionContainer XMLParser::_ReadXMLRestriction() { InputRestrictionContainer XMLParser::ReadXMLRestriction()
_RawRestrictionContainer restriction; {
InputRestrictionContainer restriction;
std::string except_tag_string; std::string except_tag_string;
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { if (xmlTextReaderIsEmptyElement(inputReader) != 1)
const int depth = xmlTextReaderDepth( inputReader );while ( xmlTextReaderRead( inputReader ) == 1 ) { {
const int childType = xmlTextReaderNodeType( inputReader ); const int depth = xmlTextReaderDepth(inputReader);
if ( childType != 1 && childType != 15 ) { while (xmlTextReaderRead(inputReader) == 1)
continue; {
} const int childType = xmlTextReaderNodeType(inputReader);
const int childDepth = xmlTextReaderDepth( inputReader ); if (childType != 1 && childType != 15)
xmlChar* childName = xmlTextReaderName( inputReader ); {
if ( childName == NULL ) { continue;
continue; }
} const int childDepth = xmlTextReaderDepth(inputReader);
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "relation" ) == 1 ) { xmlChar *childName = xmlTextReaderName(inputReader);
xmlFree( childName ); if (childName == NULL)
break; {
} continue;
if ( childType != 1 ) { }
xmlFree( childName ); if (depth == childDepth && childType == 15 &&
continue; xmlStrEqual(childName, (const xmlChar *)"relation") == 1)
} {
xmlFree(childName);
break;
}
if (childType != 1)
{
xmlFree(childName);
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); {
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
if ( k != NULL && value != NULL ) { xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if(xmlStrEqual(k, ( const xmlChar* ) "restriction" )){ if (k != NULL && value != NULL)
if(0 == std::string((const char *) value).find("only_")) { {
restriction.restriction.flags.isOnly = true; if (xmlStrEqual(k, (const xmlChar *)"restriction") &&
} (0 == std::string((const char *)value).find("only_")))
} {
if ( xmlStrEqual(k, (const xmlChar *) "except") ) { restriction.restriction.flags.isOnly = true;
except_tag_string = (const char*) value; }
} if (xmlStrEqual(k, (const xmlChar *)"except"))
} {
except_tag_string = (const char *)value;
}
}
if ( k != NULL ) { if (k != NULL)
xmlFree( k ); {
} xmlFree(k);
if ( value != NULL ) { }
xmlFree( value ); if (value != NULL)
} {
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "member" ) == 1 ) { xmlFree(value);
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" ); }
if ( ref != NULL ) { }
xmlChar * role = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "role" ); else if (xmlStrEqual(childName, (const xmlChar *)"member") == 1)
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" ); {
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != NULL)
{
xmlChar *role = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"role");
xmlChar *type = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"type");
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) { if (xmlStrEqual(role, (const xmlChar *)"to") &&
restriction.toWay = stringToUint((const char*) ref); xmlStrEqual(type, (const xmlChar *)"way"))
} {
if(xmlStrEqual(role, (const xmlChar *) "from") && xmlStrEqual(type, (const xmlChar *) "way")) { restriction.toWay = stringToUint((const char *)ref);
restriction.fromWay = stringToUint((const char*) ref); }
} if (xmlStrEqual(role, (const xmlChar *)"from") &&
if(xmlStrEqual(role, (const xmlChar *) "via") && xmlStrEqual(type, (const xmlChar *) "node")) { xmlStrEqual(type, (const xmlChar *)"way"))
restriction.restriction.viaNode = stringToUint((const char*) ref); {
} restriction.fromWay = stringToUint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"via") &&
xmlStrEqual(type, (const xmlChar *)"node"))
{
restriction.restriction.viaNode = stringToUint((const char *)ref);
}
if(NULL != type) { if (NULL != type)
xmlFree( type ); {
} xmlFree(type);
if(NULL != role) { }
xmlFree( role ); if (NULL != role)
} {
if(NULL != ref) { xmlFree(role);
xmlFree( ref ); }
} if (NULL != ref)
} {
} xmlFree(ref);
xmlFree( childName ); }
} }
} }
xmlFree(childName);
}
}
if( ShouldIgnoreRestriction(except_tag_string) ) { if (ShouldIgnoreRestriction(except_tag_string))
restriction.fromWay = UINT_MAX; //workaround to ignore the restriction {
} restriction.fromWay = UINT_MAX; // workaround to ignore the restriction
return restriction; }
return restriction;
} }
ExtractionWay XMLParser::_ReadXMLWay() { ExtractionWay XMLParser::ReadXMLWay()
ExtractionWay way; {
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { ExtractionWay way;
const int depth = xmlTextReaderDepth( inputReader ); if (xmlTextReaderIsEmptyElement(inputReader) != 1)
while ( xmlTextReaderRead( inputReader ) == 1 ) { {
const int childType = xmlTextReaderNodeType( inputReader ); const int depth = xmlTextReaderDepth(inputReader);
if ( childType != 1 && childType != 15 ) { while (xmlTextReaderRead(inputReader) == 1)
continue; {
} const int childType = xmlTextReaderNodeType(inputReader);
const int childDepth = xmlTextReaderDepth( inputReader ); if (childType != 1 && childType != 15)
xmlChar* childName = xmlTextReaderName( inputReader ); {
if ( childName == NULL ) { continue;
continue; }
} const int childDepth = xmlTextReaderDepth(inputReader);
xmlChar *childName = xmlTextReaderName(inputReader);
if (childName == NULL)
{
continue;
}
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) { if (depth == childDepth && childType == 15 &&
xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); xmlStrEqual(childName, (const xmlChar *)"way") == 1)
way.id = stringToUint((char*)id); {
xmlFree(id); xmlChar *id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
xmlFree( childName ); way.id = stringToUint((char *)id);
break; xmlFree(id);
} xmlFree(childName);
if ( childType != 1 ) { break;
xmlFree( childName ); }
continue; if (childType != 1)
} {
xmlFree(childName);
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); {
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
// cout << "->k=" << k << ", v=" << value << endl; xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if ( k != NULL && value != NULL ) {
way.keyVals.Add(std::string( (char *) k ), std::string( (char *) value)); if (k != NULL && value != NULL)
} {
if ( k != NULL ) { way.keyVals.Add(std::string((char *)k), std::string((char *)value));
xmlFree( k ); }
} if (k != NULL)
if ( value != NULL ) { {
xmlFree( value ); xmlFree(k);
} }
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) { if (value != NULL)
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" ); {
if ( ref != NULL ) { xmlFree(value);
way.path.push_back( stringToUint(( const char* ) ref ) ); }
xmlFree( ref ); }
} else if (xmlStrEqual(childName, (const xmlChar *)"nd") == 1)
} {
xmlFree( childName ); xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
} if (ref != NULL)
} {
return way; way.path.push_back(stringToUint((const char *)ref));
xmlFree(ref);
}
}
xmlFree(childName);
}
}
return way;
} }
ImportNode XMLParser::_ReadXMLNode() { ImportNode XMLParser::ReadXMLNode()
ImportNode node; {
ImportNode node;
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" ); xmlChar *attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lat");
if ( attribute != NULL ) { if (attribute != NULL)
node.lat = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute ) ); {
xmlFree( attribute ); node.lat = COORDINATE_PRECISION * StringToDouble((const char *)attribute);
} xmlFree(attribute);
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" ); }
if ( attribute != NULL ) { attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lon");
node.lon = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute )); if (attribute != NULL)
xmlFree( attribute ); {
} node.lon = COORDINATE_PRECISION * StringToDouble((const char *)attribute);
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); xmlFree(attribute);
if ( attribute != NULL ) { }
node.id = stringToUint(( const char* ) attribute ); attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
xmlFree( attribute ); if (attribute != NULL)
} {
node.id = stringToUint((const char *)attribute);
xmlFree(attribute);
}
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { if (xmlTextReaderIsEmptyElement(inputReader) != 1)
const int depth = xmlTextReaderDepth( inputReader ); {
while ( xmlTextReaderRead( inputReader ) == 1 ) { const int depth = xmlTextReaderDepth(inputReader);
const int childType = xmlTextReaderNodeType( inputReader ); while (xmlTextReaderRead(inputReader) == 1)
// 1 = Element, 15 = EndElement {
if ( childType != 1 && childType != 15 ) { const int childType = xmlTextReaderNodeType(inputReader);
continue; // 1 = Element, 15 = EndElement
} if (childType != 1 && childType != 15)
const int childDepth = xmlTextReaderDepth( inputReader ); {
xmlChar* childName = xmlTextReaderName( inputReader ); continue;
if ( childName == NULL ) { }
continue; const int childDepth = xmlTextReaderDepth(inputReader);
} xmlChar *childName = xmlTextReaderName(inputReader);
if (childName == NULL)
{
continue;
}
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) { if (depth == childDepth && childType == 15 &&
xmlFree( childName ); xmlStrEqual(childName, (const xmlChar *)"node") == 1)
break; {
} xmlFree(childName);
if ( childType != 1 ) { break;
xmlFree( childName ); }
continue; if (childType != 1)
} {
xmlFree(childName);
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); {
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
if ( k != NULL && value != NULL ) { xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
node.keyVals.Add(std::string( reinterpret_cast<char*>(k) ), std::string( reinterpret_cast<char*>(value))); if (k != NULL && value != NULL)
} {
if ( k != NULL ) { node.keyVals.emplace(std::string((char *)(k)),
xmlFree( k ); std::string((char *)(value)));
} }
if ( value != NULL ) { if (k != NULL)
xmlFree( value ); {
} xmlFree(k);
} }
if (value != NULL)
{
xmlFree(value);
}
}
xmlFree( childName ); xmlFree(childName);
} }
} }
return node; return node;
} }
+9 -12
View File
@@ -28,25 +28,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef XMLPARSER_H_ #ifndef XMLPARSER_H_
#define XMLPARSER_H_ #define XMLPARSER_H_
#include "ExtractorCallbacks.h"
#include "BaseParser.h" #include "BaseParser.h"
#include "../DataStructures/Coordinate.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <libxml/xmlreader.h> #include <libxml/xmlreader.h>
class XMLParser : public BaseParser
class XMLParser : public BaseParser { {
public: public:
XMLParser(const char* filename, ExtractorCallbacks* ec, ScriptingEnvironment& se); XMLParser(const char *filename, ExtractorCallbacks *ec, ScriptingEnvironment &se);
bool ReadHeader(); bool ReadHeader();
bool Parse(); bool Parse();
private: private:
_RawRestrictionContainer _ReadXMLRestriction(); InputRestrictionContainer ReadXMLRestriction();
ExtractionWay _ReadXMLWay(); ExtractionWay ReadXMLWay();
ImportNode _ReadXMLNode(); ImportNode ReadXMLNode();
xmlTextReaderPtr inputReader; xmlTextReaderPtr inputReader;
}; };
+86
View File
@@ -0,0 +1,86 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_POINT_COORDINATE_H_
#define FIXED_POINT_COORDINATE_H_
#include <iosfwd> //for std::ostream
static const double COORDINATE_PRECISION = 1000000.;
struct FixedPointCoordinate {
int lat;
int lon;
FixedPointCoordinate();
explicit FixedPointCoordinate( int lat, int lon);
void Reset();
bool isSet() const;
bool isValid() const;
bool operator==(const FixedPointCoordinate & other) const;
static double ApproximateDistance(
const int lat1,
const int lon1,
const int lat2,
const int lon2
);
static double ApproximateDistance(
const FixedPointCoordinate & c1,
const FixedPointCoordinate & c2
);
static double ApproximateEuclideanDistance(
const FixedPointCoordinate & c1,
const FixedPointCoordinate & c2
);
static void convertInternalLatLonToString(
const int value,
std::string & output
);
static void convertInternalCoordinateToString(
const FixedPointCoordinate & coord,
std::string & output
);
static void convertInternalReversedCoordinateToString(
const FixedPointCoordinate & coord,
std::string & output
);
void Output(std::ostream & out) const;
};
inline std::ostream& operator<<(std::ostream& o, FixedPointCoordinate const & c){
c.Output(o);
return o;
}
#endif /* FIXED_POINT_COORDINATE_H_ */
@@ -25,33 +25,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef BRESENHAM_H_ #ifndef HTTP_HEADER_H
#define BRESENHAM_H_ #define HTTP_HEADER_H
#include <cmath> #include <string>
#include <vector>
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) { struct Header {
int dx = std::abs(x1-x0); std::string name;
int dy = std::abs(y1-y0); std::string value;
int sx = (x0 < x1 ? 1 : -1); void Clear() {
int sy = (y0 < y1 ? 1 : -1); name.clear();
int err = dx - dy; value.clear();
while(true) {
resultList.push_back(std::make_pair(x0,y0));
if(x0 == x1 && y0 == y1) break;
int e2 = 2* err;
if ( e2 > -dy) {
err -= dy;
x0 += sx;
} }
if(e2 < dx) { };
err+= dx;
y0 += sy;
}
}
} }
#endif /* BRESENHAM_H_ */ #endif //HTTP_HEADER_H
@@ -25,40 +25,49 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef QUERYOBJECTSSTORAGE_H_ #ifndef REPLY_H
#define QUERYOBJECTSSTORAGE_H_ #define REPLY_H
#include "../../Util/GraphLoader.h" #include "Header.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/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <vector> #include <vector>
#include <string>
namespace http {
const char okHTML[] = "";
const char badRequestHTML[] = "{\"status\": 400,\"status_message\":\"Bad Request\"}";
const char internalServerErrorHTML[] = "{\"status\": 500,\"status_message\":\"Internal Server Error\"}";
const char seperators[] = { ':', ' ' };
const char crlf[] = { '\r', '\n' };
const std::string okString = "HTTP/1.0 200 OK\r\n";
const std::string badRequestString = "HTTP/1.0 400 Bad Request\r\n";
const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Error\r\n";
class Reply {
public:
enum status_type {
ok = 200,
badRequest = 400,
internalServerError = 500
} status;
struct QueryObjectsStorage { std::vector<Header> headers;
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph; std::vector<boost::asio::const_buffer> toBuffers();
typedef QueryGraph::InputEdge InputEdge; std::vector<boost::asio::const_buffer> HeaderstoBuffers();
std::vector<std::string> content;
static Reply StockReply(status_type status);
void setSize(const unsigned size);
void SetUncompressedSize();
NodeInformationHelpDesk * nodeHelpDesk; Reply();
std::vector<char> m_names_char_list; private:
std::vector<unsigned> m_name_begin_indices; std::string ToString(Reply::status_type status);
QueryGraph * graph; boost::asio::const_buffer ToBuffer(Reply::status_type status);
std::string timestamp;
unsigned check_sum;
void GetName( const unsigned name_id, std::string & result ) const;
QueryObjectsStorage( const ServerPaths & paths );
~QueryObjectsStorage();
}; };
#endif /* QUERYOBJECTSSTORAGE_H_ */ }
#endif //REPLY_H
@@ -28,8 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ROUTE_PARAMETERS_H #ifndef ROUTE_PARAMETERS_H
#define ROUTE_PARAMETERS_H #define ROUTE_PARAMETERS_H
#include "../../DataStructures/Coordinate.h" #include <osrm/Coordinate.h>
#include "../../DataStructures/HashTable.h"
#include <boost/fusion/container/vector.hpp> #include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp> #include <boost/fusion/sequence/intrinsic.hpp>
@@ -46,7 +45,9 @@ struct RouteParameters {
geometry(true), geometry(true),
compression(true), compression(true),
deprecatedAPI(false), deprecatedAPI(false),
checkSum(-1) {} checkSum(-1)
{ }
short zoomLevel; short zoomLevel;
bool printInstructions; bool printInstructions;
bool alternateRoute; bool alternateRoute;
@@ -60,10 +61,9 @@ struct RouteParameters {
std::string language; std::string language;
std::vector<std::string> hints; std::vector<std::string> hints;
std::vector<FixedPointCoordinate> coordinates; std::vector<FixedPointCoordinate> coordinates;
typedef HashTable<std::string, std::string>::const_iterator OptionsIterator;
void setZoomLevel(const short i) { void setZoomLevel(const short i) {
if (18 > i && 0 < i) { if (18 >= i && 0 <= i) {
zoomLevel = i; zoomLevel = i;
} }
} }
@@ -97,8 +97,10 @@ struct RouteParameters {
} }
void addHint(const std::string & s) { void addHint(const std::string & s) {
hints.resize(coordinates.size()); hints.resize( coordinates.size() );
hints.back() = s; if( !hints.empty() ) {
hints.back() = s;
}
} }
void setLanguage(const std::string & s) { void setLanguage(const std::string & s) {
+38
View File
@@ -0,0 +1,38 @@
/*
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 SERVER_PATH_H
#define SERVER_PATH_H
#include <boost/unordered_map.hpp>
#include <boost/filesystem.hpp>
#include <string>
typedef boost::unordered_map<const std::string, boost::filesystem::path> ServerPaths;
#endif //SERVER_PATH_H
-64
View File
@@ -1,64 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "OSRM.h"
#include <boost/foreach.hpp>
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));
}
OSRM::~OSRM() {
BOOST_FOREACH(PluginMap::value_type & plugin_pointer, pluginMap) {
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;
}
pluginMap.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) {
reply.status = http::Reply::ok;
iter->second->HandleRequest(route_parameters, reply );
} else {
reply = http::Reply::stockReply(http::Reply::badRequest);
}
}
+12 -28
View File
@@ -28,38 +28,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OSRM_H #ifndef OSRM_H
#define OSRM_H #define OSRM_H
#include "OSRM.h" #include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <osrm/ServerPaths.h>
#include "../Plugins/BasePlugin.h" class OSRM_impl;
#include "../Plugins/HelloWorldPlugin.h"
#include "../Plugins/LocatePlugin.h"
#include "../Plugins/NearestPlugin.h"
#include "../Plugins/TimestampPlugin.h"
#include "../Plugins/ViaRoutePlugin.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> class OSRM {
#include <boost/filesystem.hpp> private:
#include <boost/noncopyable.hpp> OSRM_impl * OSRM_pimpl_;
#include <boost/thread.hpp>
#include <vector>
class OSRM : boost::noncopyable {
typedef boost::unordered_map<std::string, BasePlugin *> PluginMap;
QueryObjectsStorage * objects;
public: public:
OSRM(boost::unordered_map<const std::string,boost::filesystem::path>& paths); explicit OSRM(
const ServerPaths & paths,
const bool use_shared_memory = false
);
~OSRM(); ~OSRM();
void RunQuery(RouteParameters & route_parameters, http::Reply & reply); void RunQuery(RouteParameters & route_parameters, http::Reply & reply);
private:
void RegisterPlugin(BasePlugin * plugin);
PluginMap pluginMap;
}; };
#endif //OSRM_H #endif // OSRM_H
+167
View File
@@ -0,0 +1,167 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "OSRM_impl.h"
#include "OSRM.h"
#include "../Plugins/HelloWorldPlugin.h"
#include "../Plugins/LocatePlugin.h"
#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 <boost/assert.hpp>
OSRM_impl::OSRM_impl( const ServerPaths & server_paths, const bool use_shared_memory )
:
use_shared_memory(use_shared_memory)
{
if (use_shared_memory)
{
barrier = new SharedBarriers();
query_data_facade = new SharedDataFacade<QueryEdge::EdgeData>( );
}
else
{
query_data_facade = new InternalDataFacade<QueryEdge::EdgeData>(
server_paths
);
}
//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_impl::~OSRM_impl() {
BOOST_FOREACH(PluginMap::value_type & plugin_pointer, plugin_map) {
delete plugin_pointer.second;
}
if( use_shared_memory ) {
delete barrier;
}
}
void OSRM_impl::RegisterPlugin(BasePlugin * plugin) {
SimpleLogger().Write() << "loaded plugin: " << plugin->GetDescriptor();
if( plugin_map.find(plugin->GetDescriptor()) != plugin_map.end() ) {
delete plugin_map.find(plugin->GetDescriptor())->second;
}
plugin_map.emplace(plugin->GetDescriptor(), plugin);
}
void OSRM_impl::RunQuery(RouteParameters & route_parameters, http::Reply & reply) {
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);
}
}
// proxy code for compilation firewall
OSRM::OSRM(
const ServerPaths & paths,
const bool use_shared_memory
) : OSRM_pimpl_(new OSRM_impl(paths, use_shared_memory)) { }
OSRM::~OSRM() {
delete OSRM_pimpl_;
}
void OSRM::RunQuery(RouteParameters & route_parameters, http::Reply & reply) {
OSRM_pimpl_->RunQuery(route_parameters, reply);
}
+65
View File
@@ -0,0 +1,65 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OSRM_IMPL_H
#define OSRM_IMPL_H
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <osrm/ServerPaths.h>
#include "../DataStructures/QueryEdge.h"
#include "../Plugins/BasePlugin.h"
#include "../Util/ProgramOptions.h"
#include <boost/noncopyable.hpp>
struct SharedBarriers;
template<class EdgeDataT>
class BaseDataFacade;
class OSRM_impl : boost::noncopyable {
private:
typedef boost::unordered_map<std::string, BasePlugin *> PluginMap;
public:
OSRM_impl(
const ServerPaths & paths,
const bool use_shared_memory
);
virtual ~OSRM_impl();
void RunQuery(RouteParameters & route_parameters, http::Reply & reply);
private:
void RegisterPlugin(BasePlugin * plugin);
PluginMap plugin_map;
bool use_shared_memory;
SharedBarriers * barrier;
//base class pointer to the objects
BaseDataFacade<QueryEdge::EdgeData> * query_data_facade;
};
#endif //OSRM_IMPL_H
+7 -3
View File
@@ -28,9 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef BASEPLUGIN_H_ #ifndef BASEPLUGIN_H_
#define BASEPLUGIN_H_ #define BASEPLUGIN_H_
#include "../DataStructures/Coordinate.h" #include "../Util/StringUtil.h"
#include "../Server/BasicDatastructures.h"
#include "../Server/DataStructures/RouteParameters.h" #include <osrm/Coordinate.h>
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <boost/foreach.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
+50 -19
View File
@@ -29,10 +29,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define HELLOWORLDPLUGIN_H_ #define HELLOWORLDPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "../Util/StringUtil.h"
#include <sstream> #include <string>
class HelloWorldPlugin : public BasePlugin { class HelloWorldPlugin : public BasePlugin {
private:
std::string temp_string;
public: public:
HelloWorldPlugin() : descriptor_string("hello"){} HelloWorldPlugin() : descriptor_string("hello"){}
virtual ~HelloWorldPlugin() { } virtual ~HelloWorldPlugin() { }
@@ -40,28 +43,56 @@ public:
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
reply.content.append("<html><head><title>Hello World Demonstration Document</title></head><body><h1>Hello, World!</h1>"); reply.content.push_back("<html><head><title>Hello World Demonstration Document</title></head><body><h1>Hello, World!</h1>");
std::stringstream content; reply.content.push_back("<pre>");
content << "<pre>"; reply.content.push_back("zoom level: ");
content << "zoom level: " << routeParameters.zoomLevel << "\n"; intToString(routeParameters.zoomLevel, temp_string);
content << "checksum: " << routeParameters.checkSum << "\n"; reply.content.push_back(temp_string);
content << "instructions: " << (routeParameters.printInstructions ? "yes" : "no") << "\n"; reply.content.push_back("\nchecksum: ");
content << "geometry: " << (routeParameters.geometry ? "yes" : "no") << "\n"; intToString(routeParameters.checkSum, temp_string);
content << "compression: " << (routeParameters.compression ? "yes" : "no") << "\n"; reply.content.push_back(temp_string);
content << "output format: " << routeParameters.outputFormat << "\n"; reply.content.push_back("\ninstructions: ");
content << "json parameter: " << routeParameters.jsonpParameter << "\n"; reply.content.push_back((routeParameters.printInstructions ? "yes" : "no"));
content << "language: " << routeParameters.language << "<br>"; reply.content.push_back(temp_string);
content << "Number of locations: " << routeParameters.coordinates.size() << "\n"; 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) { 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) { 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.push_back( "</pre></body></html>");
reply.content.append(content.str());
reply.content.append("</body></html>");
} }
private: private:
std::string descriptor_string; std::string descriptor_string;
+45 -35
View File
@@ -29,27 +29,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define LOCATEPLUGIN_H_ #define LOCATEPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
/* //locates the nearest node in the road network for a given coordinate.
* This Plugin locates the nearest node in the road network for a given coordinate.
*/ template<class DataFacadeT>
class LocatePlugin : public BasePlugin { class LocatePlugin : public BasePlugin {
public: public:
LocatePlugin(QueryObjectsStorage * objects) : descriptor_string("locate") { explicit LocatePlugin(DataFacadeT * facade)
nodeHelpDesk = objects->nodeHelpDesk; :
} descriptor_string("locate"),
facade(facade)
{ }
const std::string & GetDescriptor() const { return descriptor_string; } 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 //check number of parameters
if(!routeParameters.coordinates.size()) { if(!routeParameters.coordinates.size()) {
reply = http::Reply::stockReply(http::Reply::badRequest); reply = http::Reply::StockReply(http::Reply::badRequest);
return; return;
} }
if(false == checkCoord(routeParameters.coordinates[0])) { if(false == checkCoord(routeParameters.coordinates[0])) {
reply = http::Reply::stockReply(http::Reply::badRequest); reply = http::Reply::StockReply(http::Reply::badRequest);
return; return;
} }
@@ -58,35 +62,37 @@ public:
std::string tmp; std::string tmp;
//json //json
// JSONParameter = routeParameters.options.Find("jsonp"); if(!routeParameters.jsonpParameter.empty()) {
if("" != routeParameters.jsonpParameter) { reply.content.push_back(routeParameters.jsonpParameter);
reply.content += routeParameters.jsonpParameter; reply.content.push_back("(");
reply.content += "(";
} }
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
reply.content += ("{"); reply.content.push_back ("{");
reply.content += ("\"version\":0.3,"); if(
if(!nodeHelpDesk->LocateClosestEndPointForCoordinate(routeParameters.coordinates[0], result)) { !facade->LocateClosestEndPointForCoordinate(
reply.content += ("\"status\":207,"); routeParameters.coordinates[0],
reply.content += ("\"mapped_coordinate\":[]"); result
)
) {
reply.content.push_back ("\"status\":207,");
reply.content.push_back ("\"mapped_coordinate\":[]");
} else { } else {
//Write coordinate to stream //Write coordinate to stream
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
reply.content += ("\"status\":0,"); reply.content.push_back ("\"status\":0,");
reply.content += ("\"mapped_coordinate\":"); reply.content.push_back ("\"mapped_coordinate\":");
convertInternalLatLonToString(result.lat, tmp); FixedPointCoordinate::convertInternalLatLonToString(result.lat, tmp);
reply.content += "["; reply.content.push_back("[");
reply.content += tmp; reply.content.push_back(tmp);
convertInternalLatLonToString(result.lon, tmp); FixedPointCoordinate::convertInternalLatLonToString(result.lon, tmp);
reply.content += ","; reply.content.push_back(",");
reply.content += tmp; reply.content.push_back(tmp);
reply.content += "]"; reply.content.push_back("]");
} }
reply.content += ",\"transactionId\": \"OSRM Routing Engine JSON Locate (v0.3)\""; reply.content.push_back("}");
reply.content += ("}");
reply.headers.resize(3); reply.headers.resize(3);
if("" != routeParameters.jsonpParameter) { if(!routeParameters.jsonpParameter.empty()) {
reply.content += ")"; reply.content.push_back( ")");
reply.headers[1].name = "Content-Type"; reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript"; reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition"; reply.headers[2].name = "Content-Disposition";
@@ -98,14 +104,18 @@ public:
reply.headers[2].value = "attachment; filename=\"location.json\""; reply.headers[2].value = "attachment; filename=\"location.json\"";
} }
reply.headers[0].name = "Content-Length"; 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; reply.headers[0].value = tmp;
return; return;
} }
private: private:
NodeInformationHelpDesk * nodeHelpDesk;
std::string descriptor_string; std::string descriptor_string;
DataFacadeT * facade;
}; };
#endif /* LOCATEPLUGIN_H_ */ #endif /* LOCATEPLUGIN_H_ */
+48 -46
View File
@@ -25,43 +25,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef NearestPlugin_H_ #ifndef NEAREST_PLUGIN_H
#define NearestPlugin_H_ #define NEAREST_PLUGIN_H
#include "BasePlugin.h" #include "BasePlugin.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <boost/unordered_map.hpp>
/* /*
* This Plugin locates the nearest point on a street in the road network for a given coordinate. * This Plugin locates the nearest point on a street in the road network for a given coordinate.
*/ */
template<class DataFacadeT>
class NearestPlugin : public BasePlugin { class NearestPlugin : public BasePlugin {
public: public:
NearestPlugin(QueryObjectsStorage * objects ) explicit NearestPlugin(DataFacadeT * facade )
: :
m_query_objects(objects), facade(facade),
descriptor_string("nearest") descriptor_string("nearest")
{ {
descriptorTable.insert(std::make_pair("" , 0)); //default descriptor descriptorTable.emplace("", 0); //default descriptor
descriptorTable.insert(std::make_pair("json", 1)); descriptorTable.emplace("json", 1);
} }
const std::string & GetDescriptor() const { return descriptor_string; } 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 //check number of parameters
if(!routeParameters.coordinates.size()) { if(!routeParameters.coordinates.size()) {
reply = http::Reply::stockReply(http::Reply::badRequest); reply = http::Reply::StockReply(http::Reply::badRequest);
return; return;
} }
if(false == checkCoord(routeParameters.coordinates[0])) { if( !checkCoord(routeParameters.coordinates[0]) ) {
reply = http::Reply::stockReply(http::Reply::badRequest); reply = http::Reply::StockReply(http::Reply::badRequest);
return; return;
} }
NodeInformationHelpDesk * nodeHelpDesk = m_query_objects->nodeHelpDesk;
//query to helpdesk
PhantomNode result; PhantomNode result;
nodeHelpDesk->FindPhantomNodeForCoordinate( facade->FindPhantomNodeForCoordinate(
routeParameters.coordinates[0], routeParameters.coordinates[0],
result, result,
routeParameters.zoomLevel routeParameters.zoomLevel
@@ -71,40 +75,34 @@ public:
//json //json
if("" != routeParameters.jsonpParameter) { if("" != routeParameters.jsonpParameter) {
reply.content += routeParameters.jsonpParameter; reply.content.push_back(routeParameters.jsonpParameter);
reply.content += "("; reply.content.push_back("(");
} }
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
reply.content += ("{"); reply.content.push_back("{\"status\":");
reply.content += ("\"version\":0.3,"); if(UINT_MAX != result.forward_node_id) {
reply.content += ("\"status\":"); reply.content.push_back("0,");
if(UINT_MAX != result.edgeBasedNode) {
reply.content += "0,";
} else { } else {
reply.content += "207,"; reply.content.push_back("207,");
} }
reply.content += ("\"mapped_coordinate\":"); reply.content.push_back("\"mapped_coordinate\":[");
reply.content += "["; if(UINT_MAX != result.forward_node_id) {
if(UINT_MAX != result.edgeBasedNode) { FixedPointCoordinate::convertInternalLatLonToString(result.location.lat, temp_string);
convertInternalLatLonToString(result.location.lat, temp_string); reply.content.push_back(temp_string);
reply.content += temp_string; FixedPointCoordinate::convertInternalLatLonToString(result.location.lon, temp_string);
convertInternalLatLonToString(result.location.lon, temp_string); reply.content.push_back(",");
reply.content += ","; reply.content.push_back(temp_string);
reply.content += temp_string;
} }
reply.content += "],"; reply.content.push_back("],\"name\":\"");
reply.content += "\"name\":\""; if(UINT_MAX != result.forward_node_id) {
if(UINT_MAX != result.edgeBasedNode) { facade->GetName(result.name_id, temp_string);
m_query_objects->GetName(result.nodeBasedEdgeNameID, temp_string); reply.content.push_back(temp_string);
reply.content += temp_string;
} }
reply.content += "\""; reply.content.push_back("\"}");
reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON Nearest (v0.3)\"";
reply.content += ("}");
reply.headers.resize(3); reply.headers.resize(3);
if("" != routeParameters.jsonpParameter) { if( !routeParameters.jsonpParameter.empty() ) {
reply.content += ")"; reply.content.push_back(")");
reply.headers[1].name = "Content-Type"; reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript"; reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition"; reply.headers[2].name = "Content-Disposition";
@@ -116,14 +114,18 @@ public:
reply.headers[2].value = "attachment; filename=\"location.json\""; reply.headers[2].value = "attachment; filename=\"location.json\"";
} }
reply.headers[0].name = "Content-Length"; 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; reply.headers[0].value = temp_string;
} }
private: private:
QueryObjectsStorage * m_query_objects; DataFacadeT * facade;
HashTable<std::string, unsigned> descriptorTable; boost::unordered_map<std::string, unsigned> descriptorTable;
std::string descriptor_string; std::string descriptor_string;
}; };
#endif /* NearestPlugin_H_ */ #endif /* NEAREST_PLUGIN_H */
+19 -17
View File
@@ -30,10 +30,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BasePlugin.h" #include "BasePlugin.h"
template<class DataFacadeT>
class TimestampPlugin : public BasePlugin { class TimestampPlugin : public BasePlugin {
public: public:
TimestampPlugin(QueryObjectsStorage * o) explicit TimestampPlugin(const DataFacadeT * facade)
: objects(o), descriptor_string("timestamp") : facade(facade), descriptor_string("timestamp")
{ } { }
const std::string & GetDescriptor() const { return descriptor_string; } const std::string & GetDescriptor() const { return descriptor_string; }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
@@ -41,23 +42,21 @@ public:
//json //json
if("" != routeParameters.jsonpParameter) { if("" != routeParameters.jsonpParameter) {
reply.content += routeParameters.jsonpParameter; reply.content.push_back(routeParameters.jsonpParameter);
reply.content += "("; reply.content.push_back("(");
} }
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
reply.content += ("{"); reply.content.push_back("{");
reply.content += ("\"version\":0.3,"); reply.content.push_back("\"status\":");
reply.content += ("\"status\":"); reply.content.push_back("0,");
reply.content += "0,"; reply.content.push_back("\"timestamp\":\"");
reply.content += ("\"timestamp\":\""); reply.content.push_back(facade->GetTimestamp());
reply.content += objects->timestamp; reply.content.push_back("\"");
reply.content += "\""; reply.content.push_back("}");
reply.content += ",\"transactionId\":\"OSRM Routing Engine JSON timestamp (v0.3)\"";
reply.content += ("}");
reply.headers.resize(3); reply.headers.resize(3);
if("" != routeParameters.jsonpParameter) { if("" != routeParameters.jsonpParameter) {
reply.content += ")"; reply.content.push_back(")");
reply.headers[1].name = "Content-Type"; reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript"; reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition"; reply.headers[2].name = "Content-Disposition";
@@ -68,12 +67,15 @@ public:
reply.headers[2].name = "Content-Disposition"; reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"timestamp.json\""; reply.headers[2].value = "attachment; filename=\"timestamp.json\"";
} }
reply.headers[0].name = "Content-Length"; unsigned content_length = 0;
intToString(reply.content.size(), tmp); BOOST_FOREACH(const std::string & snippet, reply.content) {
content_length += snippet.length();
}
intToString(content_length, tmp);
reply.headers[0].value = tmp; reply.headers[0].value = tmp;
} }
private: private:
QueryObjectsStorage * objects; const DataFacadeT * facade;
std::string descriptor_string; std::string descriptor_string;
}; };
+81 -82
View File
@@ -32,15 +32,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Algorithms/ObjectToBase64.h" #include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/QueryEdge.h" #include "../DataStructures/QueryEdge.h"
#include "../DataStructures/StaticGraph.h"
#include "../DataStructures/SearchEngine.h" #include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h" #include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h" #include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h" #include "../Descriptors/JSONDescriptor.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <cstdlib> #include <cstdlib>
@@ -48,140 +48,140 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string> #include <string>
#include <vector> #include <vector>
template<class DataFacadeT>
class ViaRoutePlugin : public BasePlugin { class ViaRoutePlugin : public BasePlugin {
private: private:
NodeInformationHelpDesk * nodeHelpDesk; boost::unordered_map<std::string, unsigned> descriptorTable;
StaticGraph<QueryEdge::EdgeData> * graph; boost::shared_ptr<SearchEngine<DataFacadeT> > search_engine_ptr;
HashTable<std::string, unsigned> descriptorTable;
SearchEngine * searchEnginePtr;
public: public:
ViaRoutePlugin(QueryObjectsStorage * objects) explicit ViaRoutePlugin(DataFacadeT * facade)
: :
// objects(objects), descriptor_string("viaroute"),
descriptor_string("viaroute") facade(facade)
{ {
nodeHelpDesk = objects->nodeHelpDesk; search_engine_ptr = boost::make_shared<SearchEngine<DataFacadeT> >(facade);
graph = objects->graph;
searchEnginePtr = new SearchEngine(objects);
// descriptorTable.emplace("" , 0);
descriptorTable.emplace("json", 0); descriptorTable.emplace("json", 0);
descriptorTable.emplace("gpx" , 1); descriptorTable.emplace("gpx" , 1);
} }
virtual ~ViaRoutePlugin() { virtual ~ViaRoutePlugin() { }
delete searchEnginePtr;
}
const std::string & GetDescriptor() const { return descriptor_string; } 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 //check number of parameters
if( 2 > routeParameters.coordinates.size() ) { if( 2 > routeParameters.coordinates.size() ) {
reply = http::Reply::stockReply(http::Reply::badRequest); reply = http::Reply::StockReply(http::Reply::badRequest);
return; return;
} }
RawRouteData rawRoute; RawRouteData raw_route;
rawRoute.checkSum = nodeHelpDesk->GetCheckSum(); raw_route.checkSum = facade->GetCheckSum();
bool checksumOK = (routeParameters.checkSum == rawRoute.checkSum); const bool checksumOK = (routeParameters.checkSum == raw_route.checkSum);
std::vector<std::string> textCoord; std::vector<std::string> textCoord;
for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) { for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) {
if(false == checkCoord(routeParameters.coordinates[i])) { if( !checkCoord(routeParameters.coordinates[i]) ) {
reply = http::Reply::stockReply(http::Reply::badRequest); reply = http::Reply::StockReply(http::Reply::badRequest);
return; return;
} }
rawRoute.rawViaNodeCoordinates.push_back(routeParameters.coordinates[i]); raw_route.rawViaNodeCoordinates.push_back(routeParameters.coordinates[i]);
} }
std::vector<PhantomNode> phantomNodeVector(rawRoute.rawViaNodeCoordinates.size()); std::vector<PhantomNode> phantomNodeVector(raw_route.rawViaNodeCoordinates.size());
for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) { for(unsigned i = 0; i < raw_route.rawViaNodeCoordinates.size(); ++i) {
if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) { 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]); 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; continue;
} }
} }
// SimpleLogger().Write() << "Brute force lookup of coordinate " << i; facade->FindPhantomNodeForCoordinate(
searchEnginePtr->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i], routeParameters.zoomLevel); raw_route.rawViaNodeCoordinates[i],
phantomNodeVector[i],
routeParameters.zoomLevel
);
} }
for(unsigned i = 0; i < phantomNodeVector.size()-1; ++i) { PhantomNodes current_phantom_node_pair;
PhantomNodes segmentPhantomNodes; for (unsigned i = 0; i < phantomNodeVector.size()-1; ++i)
segmentPhantomNodes.startPhantom = phantomNodeVector[i]; {
segmentPhantomNodes.targetPhantom = phantomNodeVector[i+1]; current_phantom_node_pair.source_phantom = phantomNodeVector[i];
rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes); current_phantom_node_pair.target_phantom = phantomNodeVector[i+1];
} raw_route.segmentEndCoordinates.push_back(current_phantom_node_pair);
if( ( routeParameters.alternateRoute ) && (1 == rawRoute.segmentEndCoordinates.size()) ) {
// SimpleLogger().Write() << "Checking for alternative paths";
searchEnginePtr->alternativePaths(rawRoute.segmentEndCoordinates[0], rawRoute);
} else {
searchEnginePtr->shortestPath(rawRoute.segmentEndCoordinates, rawRoute);
} }
if ((routeParameters.alternateRoute) && (1 == raw_route.segmentEndCoordinates.size()))
{
search_engine_ptr->alternative_path(raw_route.segmentEndCoordinates[0], raw_route);
}
else
{
search_engine_ptr->shortest_path(raw_route.segmentEndCoordinates, raw_route);
}
if(INT_MAX == rawRoute.lengthOfShortestPath ) { if (INT_MAX == raw_route.lengthOfShortestPath)
{
SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found"; SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
} }
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
//TODO: Move to member as smart pointer if (!routeParameters.jsonpParameter.empty())
BaseDescriptor * desc; {
if("" != routeParameters.jsonpParameter) { reply.content.push_back(routeParameters.jsonpParameter);
reply.content += routeParameters.jsonpParameter; reply.content.push_back("(");
reply.content += "(";
} }
_DescriptorConfig descriptorConfig; DescriptorConfig descriptor_config;
unsigned descriptorType = 0; unsigned descriptor_type = 0;
if(descriptorTable.find(routeParameters.outputFormat) != descriptorTable.end() ) { if(descriptorTable.find(routeParameters.outputFormat) != descriptorTable.end() ) {
descriptorType = descriptorTable.find(routeParameters.outputFormat)->second; descriptor_type = descriptorTable.find(routeParameters.outputFormat)->second;
} }
descriptorConfig.z = routeParameters.zoomLevel; descriptor_config.zoom_level = routeParameters.zoomLevel;
descriptorConfig.instructions = routeParameters.printInstructions; descriptor_config.instructions = routeParameters.printInstructions;
descriptorConfig.geometry = routeParameters.geometry; descriptor_config.geometry = routeParameters.geometry;
descriptorConfig.encodeGeometry = routeParameters.compression; descriptor_config.encode_geometry = routeParameters.compression;
switch(descriptorType){ boost::shared_ptr<BaseDescriptor<DataFacadeT> > descriptor;
switch(descriptor_type){
case 0: case 0:
desc = new JSONDescriptor(); descriptor = boost::make_shared<JSONDescriptor<DataFacadeT> >();
break; break;
case 1: case 1:
desc = new GPXDescriptor(); descriptor = boost::make_shared<GPXDescriptor<DataFacadeT> >();
break; break;
default: default:
desc = new JSONDescriptor(); descriptor = boost::make_shared<JSONDescriptor<DataFacadeT> >();
break; break;
} }
PhantomNodes phantomNodes; PhantomNodes phantom_nodes;
phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom; phantom_nodes.source_phantom = raw_route.segmentEndCoordinates[0].source_phantom;
// SimpleLogger().Write() << "Start location: " << phantomNodes.startPhantom.location; phantom_nodes.target_phantom = raw_route.segmentEndCoordinates[raw_route.segmentEndCoordinates.size()-1].target_phantom;
phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom; descriptor->SetConfig(descriptor_config);
// SimpleLogger().Write() << "TargetLocation: " << phantomNodes.targetPhantom.location;
// SimpleLogger().Write() << "Number of segments: " << rawRoute.segmentEndCoordinates.size();
desc->SetConfig(descriptorConfig);
desc->Run(reply, rawRoute, phantomNodes, *searchEnginePtr); descriptor->Run(raw_route, phantom_nodes, facade, reply);
if("" != routeParameters.jsonpParameter) {
reply.content += ")\n"; if (!routeParameters.jsonpParameter.empty())
{
reply.content.push_back(")\n");
} }
reply.headers.resize(3); reply.headers.resize(3);
reply.headers[0].name = "Content-Length"; reply.headers[0].name = "Content-Length";
std::string tmp; unsigned content_length = 0;
intToString(reply.content.size(), tmp); BOOST_FOREACH(const std::string & snippet, reply.content) {
reply.headers[0].value = tmp; content_length += snippet.length();
switch(descriptorType){ }
std::string tmp_string;
intToString(content_length, tmp_string);
reply.headers[0].value = tmp_string;
switch(descriptor_type){
case 0: case 0:
if("" != routeParameters.jsonpParameter){ if( !routeParameters.jsonpParameter.empty() ){
reply.headers[1].name = "Content-Type"; reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript"; reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition"; reply.headers[2].name = "Content-Disposition";
@@ -202,7 +202,7 @@ public:
break; break;
default: default:
if("" != routeParameters.jsonpParameter){ if( !routeParameters.jsonpParameter.empty() ){
reply.headers[1].name = "Content-Type"; reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript"; reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition"; reply.headers[2].name = "Content-Disposition";
@@ -215,12 +215,11 @@ public:
} }
break; break;
} }
delete desc;
return; return;
} }
private: private:
std::string descriptor_string; std::string descriptor_string;
DataFacadeT * facade;
}; };
+1 -1
View File
@@ -6,7 +6,7 @@ require 'sys/proctable'
BUILD_FOLDER = 'build' BUILD_FOLDER = 'build'
DATA_FOLDER = 'sandbox' DATA_FOLDER = 'sandbox'
PROFILE = 'bicycle' PROFILE = 'examples/postgis'
OSRM_PORT = 5000 OSRM_PORT = 5000
PROFILES_FOLDER = '../profiles' PROFILES_FOLDER = '../profiles'
File diff suppressed because it is too large Load Diff
+285 -125
View File
@@ -29,210 +29,370 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define BASICROUTINGINTERFACE_H_ #define BASICROUTINGINTERFACE_H_
#include "../DataStructures/RawRouteData.h" #include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngineData.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/ContainerUtils.h" #include "../Util/ContainerUtils.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <cassert>
#include <climits>
#include <stack> #include <stack>
template<class QueryDataT> SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap;
class BasicRoutingInterface : boost::noncopyable{ 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: protected:
QueryDataT & _queryData; DataFacadeT * facade;
public: public:
BasicRoutingInterface(QueryDataT & qd) : _queryData(qd) { } explicit BasicRoutingInterface( DataFacadeT * facade ) : facade(facade) { }
virtual ~BasicRoutingInterface(){ }; virtual ~BasicRoutingInterface(){ };
inline void RoutingStep(typename QueryDataT::QueryHeap & _forwardHeap, typename QueryDataT::QueryHeap & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection) const { inline void RoutingStep(
const NodeID node = _forwardHeap.DeleteMin(); SearchEngineData::QueryHeap & forward_heap,
const int distance = _forwardHeap.GetKey(node); SearchEngineData::QueryHeap & reverse_heap,
//SimpleLogger().Write() << "Settled (" << _forwardHeap.GetData( node ).parent << "," << node << ")=" << distance; NodeID * middle_node_id,
if(_backwardHeap.WasInserted(node) ){ int * upper_bound,
const int newDistance = _backwardHeap.GetKey(node) + distance; const bool forward_direction
if(newDistance < *_upperbound ){ ) const
if(newDistance>=0 ) { {
*middle = node; const NodeID node = forward_heap.DeleteMin();
*_upperbound = newDistance; const int distance = forward_heap.GetKey(node);
} else { 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){ if (distance > *upper_bound)
_forwardHeap.DeleteAll(); {
forward_heap.DeleteAll();
return; return;
} }
//Stalling //Stalling
for ( typename QueryDataT::Graph::EdgeIterator edge = _queryData.graph->BeginEdges( node ); edge < _queryData.graph->EndEdges(node); ++edge ) { for (EdgeID edge = facade->BeginEdges( node ); edge < facade->EndEdges(node); ++edge)
const typename QueryDataT::Graph::EdgeData & data = _queryData.graph->GetEdgeData(edge); {
bool backwardDirectionFlag = (!forwardDirection) ? data.forward : data.backward; const EdgeData & data = facade->GetEdgeData(edge);
if(backwardDirectionFlag) { const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
const NodeID to = _queryData.graph->GetTarget(edge); if (reverse_flag)
const int edgeWeight = data.distance; {
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 (forward_heap.WasInserted(to))
if(_forwardHeap.GetKey( to ) + edgeWeight < distance) { {
if(forward_heap.GetKey( to ) + edge_weight < distance)
{
return; return;
} }
} }
} }
} }
for ( typename QueryDataT::Graph::EdgeIterator edge = _queryData.graph->BeginEdges( node ); edge < _queryData.graph->EndEdges(node); ++edge ) { for (EdgeID edge = facade->BeginEdges(node), end_edge = facade->EndEdges(node); edge < end_edge; ++edge)
const typename QueryDataT::Graph::EdgeData & data = _queryData.graph->GetEdgeData(edge); {
bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward ); const EdgeData & data = facade->GetEdgeData(edge);
if(forwardDirectionFlag) { bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
if (forward_directionFlag)
{
const NodeID to = _queryData.graph->GetTarget(edge); const NodeID to = facade->GetTarget(edge);
const int edgeWeight = data.distance; const int edge_weight = data.distance;
assert( edgeWeight > 0 ); BOOST_ASSERT_MSG( edge_weight > 0, "edge_weight invalid" );
const int toDistance = distance + edgeWeight; const int to_distance = distance + edge_weight;
//New Node discovered -> Add to Heap + Node Info Storage //New Node discovered -> Add to Heap + Node Info Storage
if ( !_forwardHeap.WasInserted( to ) ) { if ( !forward_heap.WasInserted( to ) ) {
_forwardHeap.Insert( to, toDistance, node ); forward_heap.Insert( to, to_distance, node );
} }
//Found a shorter Path -> Update distance //Found a shorter Path -> Update distance
else if ( toDistance < _forwardHeap.GetKey( to ) ) { else if ( to_distance < forward_heap.GetKey( to ) ) {
_forwardHeap.GetData( to ).parent = node;
_forwardHeap.DecreaseKey( to, toDistance );
//new parent //new parent
forward_heap.GetData( to ).parent = node;
forward_heap.DecreaseKey( to, to_distance );
} }
} }
} }
} }
inline void UnpackPath(const std::vector<NodeID> & packedPath, std::vector<_PathData> & unpackedPath) const { inline void UnpackPath(const std::vector<NodeID> & packed_path, const PhantomNodes & phantom_node_pair, std::vector<PathData> & unpacked_path) const
const unsigned sizeOfPackedPath = packedPath.size(); {
std::stack<std::pair<NodeID, NodeID> > recursionStack; const bool start_traversed_in_reverse = (packed_path.front() != phantom_node_pair.source_phantom.forward_node_id);
const bool target_traversed_in_reverse = (packed_path.back() != phantom_node_pair.target_phantom.forward_node_id);
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. //We have to push the path in reverse order onto the stack because it's LIFO.
for(unsigned i = sizeOfPackedPath-1; i > 0; --i){ for(unsigned i = packed_path_size-1; i > 0; --i){
recursionStack.push(std::make_pair(packedPath[i-1], packedPath[i])); recursion_stack.push(
std::make_pair(packed_path[i-1], packed_path[i])
);
} }
std::pair<NodeID, NodeID> edge; std::pair<NodeID, NodeID> edge;
while(!recursionStack.empty()) { while (!recursion_stack.empty())
edge = recursionStack.top(); {
recursionStack.pop(); edge = recursion_stack.top();
recursion_stack.pop();
typename QueryDataT::Graph::EdgeIterator smallestEdge = SPECIAL_EDGEID; // facade->FindEdge does not suffice here in case of shortcuts.
int smallestWeight = INT_MAX; // The above explanation unclear? Think!
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.first);eit < _queryData.graph->EndEdges(edge.first);++eit){ EdgeID smaller_edge_id = SPECIAL_EDGEID;
const int weight = _queryData.graph->GetEdgeData(eit).distance; int edge_weight = INT_MAX;
if(_queryData.graph->GetTarget(eit) == edge.second && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).forward){ for (EdgeID edge_id = facade->BeginEdges(edge.first); edge_id < facade->EndEdges(edge.first); ++edge_id)
smallestEdge = eit; {
smallestWeight = weight; 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 (SPECIAL_EDGEID == smaller_edge_id)
if(smallestEdge == SPECIAL_EDGEID){ {
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.second);eit < _queryData.graph->EndEdges(edge.second);++eit){ for (EdgeID edge_id = facade->BeginEdges(edge.second); edge_id < facade->EndEdges(edge.second); ++edge_id)
const int weight = _queryData.graph->GetEdgeData(eit).distance; {
if(_queryData.graph->GetTarget(eit) == edge.first && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).backward){ const int weight = facade->GetEdgeData(edge_id).distance;
smallestEdge = eit; if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) && facade->GetEdgeData(edge_id).backward)
smallestWeight = weight; {
smaller_edge_id = edge_id;
edge_weight = weight;
} }
} }
} }
assert(smallestWeight != INT_MAX); BOOST_ASSERT_MSG(edge_weight != INVALID_EDGE_WEIGHT, "edge id invalid");
const typename QueryDataT::Graph::EdgeData& ed = _queryData.graph->GetEdgeData(smallestEdge); const EdgeData & ed = facade->GetEdgeData(smaller_edge_id);
if(ed.shortcut) {//unpack if (ed.shortcut)
const NodeID middle = ed.id; {//unpack
const NodeID middle_node_id = ed.id;
//again, we need to this in reversed order //again, we need to this in reversed order
recursionStack.push(std::make_pair(middle, edge.second)); recursion_stack.push(std::make_pair(middle_node_id, edge.second));
recursionStack.push(std::make_pair(edge.first, middle)); recursion_stack.push(std::make_pair(edge.first, middle_node_id));
} else { }
assert(!ed.shortcut); else
unpackedPath.push_back( {
_PathData( BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
ed.id, unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
_queryData.nodeHelpDesk->GetNameIndexFromEdgeID(ed.id), const TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
_queryData.nodeHelpDesk->GetTurnInstructionForEdgeID(ed.id),
ed.distance if (!facade->EdgeIsCompressed(ed.id))
{
BOOST_ASSERT( !facade->EdgeIsCompressed(ed.id) );
unpacked_path.push_back(
PathData(
facade->GetGeometryIndexForEdgeID(ed.id),
name_index,
turn_instruction,
ed.distance
)
);
}
else
{
std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(facade->GetGeometryIndexForEdgeID(ed.id), id_vector);
const int start_index = ( unpacked_path.empty() ? ( ( start_traversed_in_reverse ) ? id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position - 1 : phantom_node_pair.source_phantom.fwd_segment_position ) : 0 );
const int end_index = id_vector.size();
BOOST_ASSERT(start_index >= 0);
BOOST_ASSERT(start_index <= end_index);
for (int i = start_index; i < end_index; ++i)
{
unpacked_path.push_back(
PathData(
id_vector[i],
name_index,
TurnInstructionsClass::NoTurn,
0
)
);
}
unpacked_path.back().turnInstruction = turn_instruction;
unpacked_path.back().durationOfSegment = ed.distance;
}
}
}
if (SPECIAL_EDGEID != phantom_node_pair.target_phantom.packed_geometry_id)
{
std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(phantom_node_pair.target_phantom.packed_geometry_id, id_vector);
if (target_traversed_in_reverse)
{
std::reverse(id_vector.begin(), id_vector.end() );
}
const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id == phantom_node_pair.target_phantom.packed_geometry_id) && unpacked_path.empty();
int start_index = 0;
int end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
end_index = id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
}
if (is_local_path)
{
start_index = phantom_node_pair.source_phantom.fwd_segment_position;
end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
start_index = id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
end_index = id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
}
}
BOOST_ASSERT(start_index >= 0);
for (int i = start_index; i != end_index; (start_index < end_index ? ++i :--i))
{
BOOST_ASSERT( i >= -1 );
unpacked_path.push_back(
PathData(
id_vector[i],
phantom_node_pair.target_phantom.name_id,
TurnInstructionsClass::NoTurn,
0
) )
); );
} }
} }
// there is no equivalent to a node-based node in an edge-expanded graph.
// two equivalent routes may start (or end) at different node-based edges
// as they are added with the offset how much "distance" on the edge
// has already been traversed. Depending on offset one needs to remove
// the last node.
if (unpacked_path.size() > 1)
{
const unsigned last_index = unpacked_path.size()-1;
const unsigned second_to_last_index = last_index -1;
//looks like a trivially true check but tests for underflow
BOOST_ASSERT(last_index > second_to_last_index);
if (unpacked_path[last_index].node == unpacked_path[second_to_last_index].node)
{
unpacked_path.pop_back();
}
BOOST_ASSERT(!unpacked_path.empty());
}
} }
inline void UnpackEdge(const NodeID s, const NodeID t, std::vector<NodeID> & unpackedPath) const { inline void UnpackEdge(const NodeID s, const NodeID t, std::vector<NodeID> & unpacked_path) const
std::stack<std::pair<NodeID, NodeID> > recursionStack; {
recursionStack.push(std::make_pair(s,t)); std::stack<std::pair<NodeID, NodeID> > recursion_stack;
recursion_stack.push(std::make_pair(s,t));
std::pair<NodeID, NodeID> edge; std::pair<NodeID, NodeID> edge;
while(!recursionStack.empty()) { while (!recursion_stack.empty())
edge = recursionStack.top(); {
recursionStack.pop(); edge = recursion_stack.top();
recursion_stack.pop();
typename QueryDataT::Graph::EdgeIterator smallestEdge = SPECIAL_EDGEID; EdgeID smaller_edge_id = SPECIAL_EDGEID;
int smallestWeight = INT_MAX; int edge_weight = INT_MAX;
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.first);eit < _queryData.graph->EndEdges(edge.first);++eit){ for (EdgeID edge_id = facade->BeginEdges(edge.first); edge_id < facade->EndEdges(edge.first); ++edge_id)
const int weight = _queryData.graph->GetEdgeData(eit).distance; {
if(_queryData.graph->GetTarget(eit) == edge.second && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).forward){ const int weight = facade->GetEdgeData(edge_id).distance;
smallestEdge = eit; if(
smallestWeight = weight; (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){ if (SPECIAL_EDGEID == smaller_edge_id)
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; for (EdgeID edge_id = facade->BeginEdges(edge.second); edge_id < facade->EndEdges(edge.second); ++edge_id)
if(_queryData.graph->GetTarget(eit) == edge.first && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).backward){ {
smallestEdge = eit; const int weight = facade->GetEdgeData(edge_id).distance;
smallestWeight = weight; 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 if (ed.shortcut)
const NodeID middle = ed.id; {//unpack
const NodeID middle_node_id = ed.id;
//again, we need to this in reversed order //again, we need to this in reversed order
recursionStack.push(std::make_pair(middle, edge.second)); recursion_stack.push(std::make_pair(middle_node_id, edge.second));
recursionStack.push(std::make_pair(edge.first, middle)); recursion_stack.push(std::make_pair(edge.first, middle_node_id));
} else { }
assert(!ed.shortcut); else
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 { inline void RetrievePackedPathFromHeap(
NodeID pathNode = middle; const SearchEngineData::QueryHeap & forward_heap,
while(pathNode != _fHeap.GetData(pathNode).parent) { const SearchEngineData::QueryHeap & reverse_heap,
pathNode = _fHeap.GetData(pathNode).parent; const NodeID middle_node_id,
packedPath.push_back(pathNode); 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(packed_path.begin(), packed_path.end());
std::reverse(packedPath.begin(), packedPath.end()); packed_path.push_back(middle_node_id);
packedPath.push_back(middle); current_node_id = middle_node_id;
pathNode = middle; while (current_node_id != reverse_heap.GetData(current_node_id).parent)
while (pathNode != _bHeap.GetData(pathNode).parent){ {
pathNode = _bHeap.GetData(pathNode).parent; current_node_id = reverse_heap.GetData(current_node_id).parent;
packedPath.push_back(pathNode); packed_path.push_back(current_node_id);
} }
} }
inline void RetrievePackedPathFromSingleHeap(typename QueryDataT::QueryHeap & search_heap, const NodeID middle, std::vector<NodeID>& packed_path) const { inline void RetrievePackedPathFromSingleHeap(
NodeID pathNode = middle; const SearchEngineData::QueryHeap & search_heap,
while(pathNode != search_heap.GetData(pathNode).parent) { const NodeID middle_node_id,
pathNode = search_heap.GetData(pathNode).parent; std::vector<NodeID>& packed_path
packed_path.push_back(pathNode); ) 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);
} }
} }
}; };
#endif /* BASICROUTINGINTERFACE_H_ */ #endif /* BASICROUTINGINTERFACE_H_ */
+304 -104
View File
@@ -28,176 +28,376 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SHORTESTPATHROUTING_H_ #ifndef SHORTESTPATHROUTING_H_
#define SHORTESTPATHROUTING_H_ #define SHORTESTPATHROUTING_H_
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include "BasicRoutingInterface.h" #include "BasicRoutingInterface.h"
#include "../DataStructures/SearchEngineData.h"
#include "../typedefs.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: public:
ShortestPathRouting( QueryDataT & qd) : super(qd) {} ShortestPathRouting(
DataFacadeT * facade,
SearchEngineData & engine_working_data
) :
super(facade),
engine_working_data(engine_working_data)
{ }
~ShortestPathRouting() {} ~ShortestPathRouting() { }
void operator()(std::vector<PhantomNodes> & phantomNodesVector, RawRouteData & rawRouteData) const { void operator()(
BOOST_FOREACH(const PhantomNodes & phantomNodePair, phantomNodesVector) { const std::vector<PhantomNodes> & phantom_nodes_vector,
if(!phantomNodePair.AtLeastOnePhantomNodeIsUINTMAX()) { RawRouteData & raw_route_data
rawRouteData.lengthOfShortestPath = rawRouteData.lengthOfAlternativePath = INT_MAX; ) const
{
BOOST_FOREACH(
const PhantomNodes & phantom_node_pair,
phantom_nodes_vector
){
if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) {
// raw_route_data.lengthOfShortestPath = INT_MAX;
// raw_route_data.lengthOfAlternativePath = INT_MAX;
return; return;
} }
} }
int distance1 = 0; int distance1 = 0;
int distance2 = 0; int distance2 = 0;
bool search_from_1st_node = true;
bool searchFrom1stStartNode = true; bool search_from_2nd_node = true;
bool searchFrom2ndStartNode = true;
NodeID middle1 = UINT_MAX; NodeID middle1 = UINT_MAX;
NodeID middle2 = UINT_MAX; NodeID middle2 = UINT_MAX;
std::vector<NodeID> packedPath1; std::vector<std::vector<NodeID> > packed_legs1(phantom_nodes_vector.size());
std::vector<NodeID> packedPath2; std::vector<std::vector<NodeID> > packed_legs2(phantom_nodes_vector.size());
super::_queryData.InitializeOrClearFirstThreadLocalStorage(); engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::_queryData.InitializeOrClearSecondThreadLocalStorage(); super::facade->GetNumberOfNodes()
super::_queryData.InitializeOrClearThirdThreadLocalStorage(); );
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
engine_working_data.InitializeOrClearThirdThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
QueryHeap & forward_heap1 = *(super::_queryData.forwardHeap); QueryHeap & forward_heap1 = *(engine_working_data.forwardHeap);
QueryHeap & reverse_heap1 = *(super::_queryData.backwardHeap); QueryHeap & reverse_heap1 = *(engine_working_data.backwardHeap);
QueryHeap & forward_heap2 = *(super::_queryData.forwardHeap2); QueryHeap & forward_heap2 = *(engine_working_data.forwardHeap2);
QueryHeap & reverse_heap2 = *(super::_queryData.backwardHeap2); QueryHeap & reverse_heap2 = *(engine_working_data.backwardHeap2);
int current_leg = 0;
//Get distance to next pair of target nodes. //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(); forward_heap1.Clear(); forward_heap2.Clear();
reverse_heap1.Clear(); reverse_heap2.Clear(); reverse_heap1.Clear(); reverse_heap2.Clear();
int _localUpperbound1 = INT_MAX; int local_upper_bound1 = INT_MAX;
int _localUpperbound2 = INT_MAX; int local_upper_bound2 = INT_MAX;
middle1 = UINT_MAX; middle1 = UINT_MAX;
middle2 = UINT_MAX; middle2 = UINT_MAX;
//insert new starting nodes into forward heap, adjusted by previous distances. //insert new starting nodes into forward heap, adjusted by previous distances.
if(searchFrom1stStartNode) { if(
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode, distance1-phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode); search_from_1st_node &&
// INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1); phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID
forward_heap2.Insert(phantomNodePair.startPhantom.edgeBasedNode, distance1-phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode); ) {
// INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1); // SimpleLogger().Write(logDEBUG) << "fwd1 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
} forward_heap1.Insert(
if(phantomNodePair.startPhantom.isBidirected() && searchFrom2ndStartNode) { phantom_node_pair.source_phantom.forward_node_id,
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, distance2-phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1); distance1-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
// INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2); phantom_node_pair.source_phantom.forward_node_id
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); forward_heap2.Insert(
phantom_node_pair.source_phantom.forward_node_id,
distance1-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id
);
}
if(
search_from_2nd_node &&
phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID
) {
// SimpleLogger().Write(logDEBUG) << "fwd1 insert: " << phantom_node_pair.source_phantom.reverse_node_id << ", w: " << -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
forward_heap1.Insert(
phantom_node_pair.source_phantom.reverse_node_id,
distance2-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id
);
forward_heap2.Insert(
phantom_node_pair.source_phantom.reverse_node_id,
distance2-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id
);
} }
//insert new backward nodes into backward heap, unadjusted. //insert new backward nodes into backward heap, unadjusted.
reverse_heap1.Insert(phantomNodePair.targetPhantom.edgeBasedNode, phantomNodePair.targetPhantom.weight1, phantomNodePair.targetPhantom.edgeBasedNode); if( phantom_node_pair.target_phantom.forward_node_id != SPECIAL_NODEID ) {
// INFO("rv1: " << phantomNodePair.targetPhantom.edgeBasedNode << ", w;" << phantomNodePair.targetPhantom.weight1 ); // SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.target_phantom.forward_node_id << ", w: " << phantom_node_pair.target_phantom.GetForwardWeightPlusOffset();
if(phantomNodePair.targetPhantom.isBidirected() ) { reverse_heap1.Insert(
reverse_heap2.Insert(phantomNodePair.targetPhantom.edgeBasedNode+1, phantomNodePair.targetPhantom.weight2, phantomNodePair.targetPhantom.edgeBasedNode+1); phantom_node_pair.target_phantom.forward_node_id,
// INFO("rv2: " << phantomNodePair.targetPhantom.edgeBasedNode+1 << ", w;" << phantomNodePair.targetPhantom.weight2 ); phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
} phantom_node_pair.target_phantom.forward_node_id
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); }
if( phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID ) {
// SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.target_phantom.reverse_node_id << ", w: " << phantom_node_pair.target_phantom.GetReverseWeightPlusOffset();
reverse_heap2.Insert(
phantom_node_pair.target_phantom.reverse_node_id,
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.target_phantom.reverse_node_id
);
}
// const int forward_offset = phantom_node_pair.ComputeForwardQueueOffset();
// const int forward_offset = super::ComputeForwardOffset(
// phantom_node_pair.source_phantom
// );
// const int reverse_offset = -phantom_node_pair.ComputeReverseQueueOffset();
// const int reverse_offset = super::ComputeReverseOffset(
// phantom_node_pair.target_phantom
// );
//run two-Target Dijkstra routing step. //run two-Target Dijkstra routing step.
while(0 < (forward_heap1.Size() + reverse_heap1.Size() )){ while(0 < (forward_heap1.Size() + reverse_heap1.Size() )){
if(0 < forward_heap1.Size()){ if( 0 < forward_heap1.Size() ){
super::RoutingStep(forward_heap1, reverse_heap1, &middle1, &_localUpperbound1, forward_offset, true); super::RoutingStep(
forward_heap1,
reverse_heap1,
&middle1,
&local_upper_bound1,
true
);
} }
if(0 < reverse_heap1.Size() ){ if( 0 < reverse_heap1.Size() ){
super::RoutingStep(reverse_heap1, forward_heap1, &middle1, &_localUpperbound1, reverse_offset, false); super::RoutingStep(
reverse_heap1,
forward_heap1,
&middle1,
&local_upper_bound1,
false
);
} }
} }
if(0 < reverse_heap2.Size()) {
if( !reverse_heap2.Empty() ) {
while(0 < (forward_heap2.Size() + reverse_heap2.Size() )){ while(0 < (forward_heap2.Size() + reverse_heap2.Size() )){
if(0 < forward_heap2.Size()){ if( 0 < forward_heap2.Size() ){
super::RoutingStep(forward_heap2, reverse_heap2, &middle2, &_localUpperbound2, forward_offset, true); super::RoutingStep(
forward_heap2,
reverse_heap2,
&middle2,
&local_upper_bound2,
true
);
} }
if(0 < reverse_heap2.Size()){ if( 0 < reverse_heap2.Size() ){
super::RoutingStep(reverse_heap2, forward_heap2, &middle2, &_localUpperbound2, reverse_offset, false); super::RoutingStep(
reverse_heap2,
forward_heap2,
&middle2,
&local_upper_bound2,
false
);
} }
} }
} }
//No path found for both target nodes? //No path found for both target nodes?
if((INT_MAX == _localUpperbound1) && (INT_MAX == _localUpperbound2)) { if(
rawRouteData.lengthOfShortestPath = rawRouteData.lengthOfAlternativePath = INT_MAX; (INVALID_EDGE_WEIGHT == local_upper_bound1) &&
(INVALID_EDGE_WEIGHT == local_upper_bound2)
) {
raw_route_data.lengthOfShortestPath = INVALID_EDGE_WEIGHT;
raw_route_data.lengthOfAlternativePath = INVALID_EDGE_WEIGHT;
return; return;
} }
if(UINT_MAX == middle1) { if( SPECIAL_NODEID == middle1 ) {
searchFrom1stStartNode = false; search_from_1st_node = false;
} }
if(UINT_MAX == middle2) { if( SPECIAL_NODEID == middle2 ) {
searchFrom2ndStartNode = false; search_from_2nd_node = false;
} }
//Was at most one of the two paths not found? //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 //Unpack paths if they exist
std::vector<NodeID> temporaryPackedPath1; std::vector<NodeID> temporary_packed_leg1;
std::vector<NodeID> temporaryPackedPath2; std::vector<NodeID> temporary_packed_leg2;
if(INT_MAX != _localUpperbound1) {
super::RetrievePackedPathFromHeap(forward_heap1, reverse_heap1, middle1, temporaryPackedPath1); BOOST_ASSERT( (unsigned)current_leg < packed_legs1.size() );
BOOST_ASSERT( (unsigned)current_leg < packed_legs2.size() );
if( INVALID_EDGE_WEIGHT != local_upper_bound1 ) {
super::RetrievePackedPathFromHeap(
forward_heap1,
reverse_heap1,
middle1,
temporary_packed_leg1
);
} }
if(INT_MAX != _localUpperbound2) { if( INVALID_EDGE_WEIGHT != local_upper_bound2 ) {
super::RetrievePackedPathFromHeap(forward_heap2, reverse_heap2, middle2, temporaryPackedPath2); super::RetrievePackedPathFromHeap(
forward_heap2,
reverse_heap2,
middle2,
temporary_packed_leg2
);
} }
//if one of the paths was not found, replace it with the other one. //if one of the paths was not found, replace it with the other one.
if(0 == temporaryPackedPath1.size()) { if( temporary_packed_leg1.empty() ) {
temporaryPackedPath1.insert(temporaryPackedPath1.end(), temporaryPackedPath2.begin(), temporaryPackedPath2.end()); temporary_packed_leg1.insert(
_localUpperbound1 = _localUpperbound2; temporary_packed_leg1.end(),
temporary_packed_leg2.begin(),
temporary_packed_leg2.end()
);
local_upper_bound1 = local_upper_bound2;
} }
if(0 == temporaryPackedPath2.size()) { if( temporary_packed_leg2.empty() ) {
temporaryPackedPath2.insert(temporaryPackedPath2.end(), temporaryPackedPath1.begin(), temporaryPackedPath1.end()); temporary_packed_leg2.insert(
_localUpperbound2 = _localUpperbound1; temporary_packed_leg2.end(),
temporary_packed_leg1.begin(),
temporary_packed_leg1.end()
);
local_upper_bound2 = local_upper_bound1;
} }
assert(0 < temporaryPackedPath1.size() && 0 < temporaryPackedPath2.size()); BOOST_ASSERT_MSG(
!temporary_packed_leg1.empty() ||
!temporary_packed_leg2.empty(),
"tempory packed paths empty"
);
//Plug paths together, s.t. end of packed path is begin of temporary packed path BOOST_ASSERT(
if(0 < packedPath1.size() && 0 < packedPath2.size() ) { (0 == current_leg) || !packed_legs1[current_leg-1].empty()
if( *(temporaryPackedPath1.begin()) == *(temporaryPackedPath2.begin())) { );
//both new route segments start with the same node, thus one of the packedPath must go. BOOST_ASSERT(
assert( (packedPath1.size() == packedPath2.size() ) || (*(packedPath1.end()-1) != *(packedPath2.end()-1)) ); (0 == current_leg) || !packed_legs2[current_leg-1].empty()
if( *(packedPath1.end()-1) == *(temporaryPackedPath1.begin())) { );
packedPath2.clear();
packedPath2.insert(packedPath2.end(), packedPath1.begin(), packedPath1.end()); if( 0 < current_leg ) {
} else { const NodeID end_id_of_segment1 = packed_legs1[current_leg-1].back();
packedPath1.clear(); const NodeID end_id_of_segment2 = packed_legs2[current_leg-1].back();
packedPath1.insert(packedPath1.end(), packedPath2.begin(), packedPath2.end()); BOOST_ASSERT( !temporary_packed_leg1.empty() );
} const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
} else { const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
//packed paths 1 and 2 may need to switch. if( ( end_id_of_segment1 != start_id_of_leg1 ) &&
if(*(packedPath1.end()-1) != *(temporaryPackedPath1.begin())) { ( end_id_of_segment2 != start_id_of_leg2 )
packedPath1.swap(packedPath2); ) {
std::swap(distance1, distance2); std::swap(temporary_packed_leg1, temporary_packed_leg2);
std::swap(local_upper_bound1, local_upper_bound2);
}
}
// remove one path if both legs end at the same segment
if( 0 < current_leg ) {
const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
if(
start_id_of_leg1 == start_id_of_leg2
) {
const NodeID last_id_of_packed_legs1 = packed_legs1[current_leg-1].back();
const NodeID last_id_of_packed_legs2 = packed_legs2[current_leg-1].back();
if( start_id_of_leg1 != last_id_of_packed_legs1 ) {
packed_legs1 = packed_legs2;
BOOST_ASSERT(
start_id_of_leg1 == temporary_packed_leg1.front()
);
} else
if( start_id_of_leg2 != last_id_of_packed_legs2 ) {
packed_legs2 = packed_legs1;
BOOST_ASSERT(
start_id_of_leg2 == temporary_packed_leg2.front()
);
} }
} }
} }
packedPath1.insert(packedPath1.end(), temporaryPackedPath1.begin(), temporaryPackedPath1.end()); BOOST_ASSERT(
packedPath2.insert(packedPath2.end(), temporaryPackedPath2.begin(), temporaryPackedPath2.end()); packed_legs1.size() == packed_legs2.size()
);
if( (packedPath1.back() == packedPath2.back()) && phantomNodePair.targetPhantom.isBidirected() ) { packed_legs1[current_leg].insert(
packed_legs1[current_leg].end(),
temporary_packed_leg1.begin(),
temporary_packed_leg1.end()
);
BOOST_ASSERT(packed_legs1[current_leg].size() == temporary_packed_leg1.size() );
packed_legs2[current_leg].insert(
packed_legs2[current_leg].end(),
temporary_packed_leg2.begin(),
temporary_packed_leg2.end()
);
BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size() );
NodeID lastNodeID = packedPath2.back(); if(
searchFrom1stStartNode &= !(lastNodeID == phantomNodePair.targetPhantom.edgeBasedNode+1); (packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
searchFrom2ndStartNode &= !(lastNodeID == phantomNodePair.targetPhantom.edgeBasedNode); phantom_node_pair.target_phantom.isBidirected()
) {
const NodeID last_node_id = packed_legs2[current_leg].back();
search_from_1st_node &= !(last_node_id == phantom_node_pair.target_phantom.reverse_node_id);
search_from_2nd_node &= !(last_node_id == phantom_node_pair.target_phantom.forward_node_id);
BOOST_ASSERT( search_from_1st_node != search_from_2nd_node );
} }
distance1 = _localUpperbound1; distance1 = local_upper_bound1;
distance2 = _localUpperbound2; distance2 = local_upper_bound2;
++current_leg;
} }
if(distance1 > distance2){ if (distance1 > distance2)
std::swap(packedPath1, packedPath2); {
std::swap( packed_legs1, packed_legs2 );
} }
remove_consecutive_duplicates_from_vector(packedPath1); raw_route_data.unpacked_path_segments.resize( packed_legs1.size() );
super::UnpackPath(packedPath1, rawRouteData.computedShortestPath); // const int start_offset = ( packed_legs1[0].front() == phantom_nodes_vector.front().source_phantom.forward_node_id ? 1 : -1 )*phantom_nodes_vector.front().source_phantom.fwd_segment_position;
rawRouteData.lengthOfShortestPath = std::min(distance1, distance2);
return; raw_route_data.source_traversed_in_reverse = (packed_legs1.front().front() != phantom_nodes_vector.front().source_phantom.forward_node_id);
raw_route_data.target_traversed_in_reverse = (packed_legs1.back().back() != phantom_nodes_vector.back().target_phantom.forward_node_id);
for (unsigned i = 0; i < packed_legs1.size(); ++i)
{
BOOST_ASSERT(!phantom_nodes_vector.empty());
// const bool at_beginning = (packed_legs1[i] == packed_legs1.front());
// const bool at_end = (packed_legs1[i] == packed_legs1.back());
BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size());
PhantomNodes unpack_phantom_node_pair = phantom_nodes_vector[i];
// if (!at_beginning)
// {
// unpack_phantom_node_pair.source_phantom.packed_geometry_id = SPECIAL_EDGEID;
// unpack_phantom_node_pair.source_phantom.fwd_segment_position = 0;
// }
// if (!at_end)
// {
// unpack_phantom_node_pair.target_phantom.packed_geometry_id = SPECIAL_EDGEID;
// unpack_phantom_node_pair.target_phantom.fwd_segment_position = 0;
// }
super::UnpackPath(
// -- packed input
packed_legs1[i],
// -- start and end of (sub-)route
unpack_phantom_node_pair,
// -- unpacked output
raw_route_data.unpacked_path_segments[i]
);
}
raw_route_data.lengthOfShortestPath = std::min(distance1, distance2);
} }
}; };
+7 -6
View File
@@ -36,13 +36,13 @@ namespace qi = boost::spirit::qi;
template <typename Iterator, class HandlerT> template <typename Iterator, class HandlerT>
struct APIGrammar : qi::grammar<Iterator> { struct APIGrammar : qi::grammar<Iterator> {
APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h) { explicit APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h) {
api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query); api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query);
query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | cmp | language | instruction | geometry | alt_route | old_API) ) ; query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | cmp | language | instruction | geometry | alt_route | old_API) ) ;
zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)]; zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)];
output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)]; output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)];
jsonp = (-qi::lit('&')) >> qi::lit("jsonp") >> '=' >> stringwithDot[boost::bind(&HandlerT::setJSONpParameter, handler, ::_1)]; jsonp = (-qi::lit('&')) >> qi::lit("jsonp") >> '=' >> stringwithPercent[boost::bind(&HandlerT::setJSONpParameter, handler, ::_1)];
checksum = (-qi::lit('&')) >> qi::lit("checksum") >> '=' >> qi::int_[boost::bind(&HandlerT::setChecksum, handler, ::_1)]; checksum = (-qi::lit('&')) >> qi::lit("checksum") >> '=' >> qi::int_[boost::bind(&HandlerT::setChecksum, handler, ::_1)];
instruction = (-qi::lit('&')) >> qi::lit("instructions") >> '=' >> qi::bool_[boost::bind(&HandlerT::setInstructionFlag, handler, ::_1)]; instruction = (-qi::lit('&')) >> qi::lit("instructions") >> '=' >> qi::bool_[boost::bind(&HandlerT::setInstructionFlag, handler, ::_1)];
geometry = (-qi::lit('&')) >> qi::lit("geometry") >> '=' >> qi::bool_[boost::bind(&HandlerT::setGeometryFlag, handler, ::_1)]; geometry = (-qi::lit('&')) >> qi::lit("geometry") >> '=' >> qi::bool_[boost::bind(&HandlerT::setGeometryFlag, handler, ::_1)];
@@ -53,16 +53,17 @@ struct APIGrammar : qi::grammar<Iterator> {
alt_route = (-qi::lit('&')) >> qi::lit("alt") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAlternateRouteFlag, handler, ::_1)]; alt_route = (-qi::lit('&')) >> qi::lit("alt") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAlternateRouteFlag, handler, ::_1)];
old_API = (-qi::lit('&')) >> qi::lit("geomformat") >> '=' >> string[boost::bind(&HandlerT::setDeprecatedAPIFlag, handler, ::_1)]; old_API = (-qi::lit('&')) >> qi::lit("geomformat") >> '=' >> string[boost::bind(&HandlerT::setDeprecatedAPIFlag, handler, ::_1)];
string = +(qi::char_("a-zA-Z")); string = +(qi::char_("a-zA-Z"));
stringwithDot = +(qi::char_("a-zA-Z0-9_.-")); stringwithDot = +(qi::char_("a-zA-Z0-9_.-"));
stringwithPercent = +(qi::char_("a-zA-Z0-9_.-") | qi::char_('[') | qi::char_(']') | (qi::char_('%') >> qi::char_("0-9A-Z") >> qi::char_("0-9A-Z") ));
} }
qi::rule<Iterator> api_call, query; qi::rule<Iterator> api_call, query;
qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, hint, qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, hint,
stringwithDot, language, instruction, geometry, stringwithDot, stringwithPercent, language, instruction, geometry,
cmp, alt_route, old_API; cmp, alt_route, old_API;
HandlerT * handler; HandlerT * handler;
}; };
#endif /* APIGRAMMAR_H_ */ #endif /* APIGRAMMAR_H_ */
-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
+240
View File
@@ -0,0 +1,240 @@
/*
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 "Connection.h"
#include "RequestHandler.h"
#include "RequestParser.h"
#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 <string>
#include <vector>
namespace http {
Connection::Connection(
boost::asio::io_service& io_service,
RequestHandler& handler
) :
strand(io_service),
TCP_socket(io_service),
request_handler(handler),
request_parser(new RequestParser())
{ }
Connection::~Connection() {
delete request_parser;
}
boost::asio::ip::tcp::socket& Connection::socket() {
return TCP_socket;
}
/// Start the first asynchronous operation for the connection.
void Connection::start() {
TCP_socket.async_read_some(
boost::asio::buffer(incoming_data_buffer),
strand.wrap( boost::bind(
&Connection::handle_read,
this->shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
)
);
}
void Connection::handle_read(
const boost::system::error_code& e,
std::size_t bytes_transferred
) {
if( !e ) {
CompressionType compression_type(noCompression);
boost::tribool result;
boost::tie(result, boost::tuples::ignore) = request_parser->Parse(
request,
incoming_data_buffer.data(),
incoming_data_buffer.data() + bytes_transferred,
&compression_type
);
if( result ) {
request.endpoint = TCP_socket.remote_endpoint().address();
request_handler.handle_request(request, reply);
Header compression_header;
std::vector<char> compressed_output;
std::vector<boost::asio::const_buffer> output_buffer;
switch(compression_type) {
case deflateRFC1951:
compression_header.name = "Content-Encoding";
compression_header.value = "deflate";
reply.headers.insert(
reply.headers.begin(),
compression_header
);
compressBufferCollection(
reply.content,
compression_type,
compressed_output
);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
output_buffer.push_back(
boost::asio::buffer(compressed_output)
);
boost::asio::async_write(
TCP_socket,
output_buffer,
strand.wrap(
boost::bind(
&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error
)
)
);
break;
case gzipRFC1952:
compression_header.name = "Content-Encoding";
compression_header.value = "gzip";
reply.headers.insert(
reply.headers.begin(),
compression_header
);
compressBufferCollection(
reply.content,
compression_type,
compressed_output
);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
output_buffer.push_back(
boost::asio::buffer(compressed_output)
);
boost::asio::async_write(
TCP_socket,
output_buffer,
strand.wrap(
boost::bind(
&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error
)
)
);
break;
case noCompression:
reply.SetUncompressedSize();
output_buffer = reply.toBuffers();
boost::asio::async_write(
TCP_socket,
output_buffer,
strand.wrap(
boost::bind(
&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error
)
)
);
break;
}
} else if (!result) {
reply = Reply::StockReply(Reply::badRequest);
boost::asio::async_write(
TCP_socket,
reply.toBuffers(),
strand.wrap(
boost::bind(
&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error
)
)
);
} else {
TCP_socket.async_read_some(
boost::asio::buffer(incoming_data_buffer),
strand.wrap(
boost::bind(
&Connection::handle_read,
this->shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
)
);
}
}
}
/// Handle completion of a write operation.
void Connection::handle_write(const boost::system::error_code& e) {
if (!e) {
// Initiate graceful connection closure.
boost::system::error_code ignoredEC;
TCP_socket.shutdown(
boost::asio::ip::tcp::socket::shutdown_both,
ignoredEC
);
}
}
void Connection::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();
}
}
+22 -220
View File
@@ -28,24 +28,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONNECTION_H #ifndef CONNECTION_H
#define CONNECTION_H #define CONNECTION_H
#include "BasicDatastructures.h" #include "Http/CompressionType.h"
#include "RequestHandler.h" #include "Http/Request.h"
#include "RequestParser.h"
#include <osrm/Reply.h>
#include <boost/array.hpp> #include <boost/array.hpp>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/assert.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp> #include <boost/enable_shared_from_this.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <zlib.h>
#include <string>
#include <vector> #include <vector>
class RequestHandler;
namespace http { namespace http {
class RequestParser;
/// Represents a single connection from a client. /// Represents a single connection from a client.
class Connection : public boost::enable_shared_from_this<Connection>, class Connection : public boost::enable_shared_from_this<Connection>,
private boost::noncopyable { private boost::noncopyable {
@@ -53,235 +54,36 @@ public:
explicit Connection( explicit Connection(
boost::asio::io_service& io_service, boost::asio::io_service& io_service,
RequestHandler& handler RequestHandler& handler
) : strand(io_service), TCP_socket(io_service), request_handler(handler) { } );
boost::asio::ip::tcp::socket& socket() { ~Connection();
return TCP_socket;
} boost::asio::ip::tcp::socket& socket();
/// Start the first asynchronous operation for the connection. /// Start the first asynchronous operation for the connection.
void start() { void start();
TCP_socket.async_read_some(
boost::asio::buffer(incoming_data_buffer),
strand.wrap( boost::bind(
&Connection::handle_read,
this->shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
)
);
}
private: private:
void handle_read( void handle_read(
const boost::system::error_code& e, const boost::system::error_code& e,
std::size_t bytes_transferred std::size_t bytes_transferred
) { );
if( !e ) {
CompressionType compression_type(noCompression);
boost::tribool result;
boost::tie(result, boost::tuples::ignore) = request_parser.Parse(
request,
incoming_data_buffer.data(),
incoming_data_buffer.data() + bytes_transferred,
&compression_type
);
if( result ) {
request.endpoint = TCP_socket.remote_endpoint().address();
request_handler.handle_request(request, reply);
Header compression_header;
std::vector<unsigned char> compressed_output;
std::vector<boost::asio::const_buffer> output_buffer;
switch(compression_type) {
case deflateRFC1951:
compression_header.name = "Content-Encoding";
compression_header.value = "deflate";
reply.headers.insert(
reply.headers.begin(),
compression_header
);
compressCharArray(
reply.content.c_str(),
reply.content.length(),
compressed_output,
compression_type
);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
output_buffer.push_back(
boost::asio::buffer(compressed_output)
);
boost::asio::async_write(
TCP_socket,
output_buffer,
strand.wrap(
boost::bind(
&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error
)
)
);
break;
case gzipRFC1952:
compression_header.name = "Content-Encoding";
compression_header.value = "gzip";
reply.headers.insert(
reply.headers.begin(),
compression_header
);
compressCharArray(
reply.content.c_str(),
reply.content.length(),
compressed_output,
compression_type
);
reply.setSize(compressed_output.size());
output_buffer = reply.HeaderstoBuffers();
output_buffer.push_back(
boost::asio::buffer(compressed_output)
);
boost::asio::async_write(
TCP_socket,
output_buffer,
strand.wrap(
boost::bind(
&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error
)
)
);
break;
case noCompression:
boost::asio::async_write(
TCP_socket,
reply.toBuffers(),
strand.wrap(
boost::bind(
&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error
)
)
);
break;
}
} else if (!result) {
reply = Reply::stockReply(Reply::badRequest);
boost::asio::async_write(
TCP_socket,
reply.toBuffers(),
strand.wrap(
boost::bind(
&Connection::handle_write,
this->shared_from_this(),
boost::asio::placeholders::error
)
)
);
} else {
TCP_socket.async_read_some(
boost::asio::buffer(incoming_data_buffer),
strand.wrap(
boost::bind(
&Connection::handle_read,
this->shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
)
);
}
}
}
/// Handle completion of a write operation. /// Handle completion of a write operation.
void handle_write(const boost::system::error_code& e) { void handle_write(const boost::system::error_code& e);
if (!e) {
// Initiate graceful connection closure.
boost::system::error_code ignoredEC;
TCP_socket.shutdown(
boost::asio::ip::tcp::socket::shutdown_both,
ignoredEC
);
}
}
// Big thanks to deusty who explains how to use gzip compression by void compressBufferCollection(
// the right call to deflateInit2(): std::vector<std::string> uncompressed_data,
// http://deusty.blogspot.com/2007/07/gzip-compressiondecompression.html CompressionType compression_type,
void compressCharArray( std::vector<char> & compressed_data
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;
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);
} while (deflate_res == Z_OK);
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);
}
boost::asio::io_service::strand strand; boost::asio::io_service::strand strand;
boost::asio::ip::tcp::socket TCP_socket; boost::asio::ip::tcp::socket TCP_socket;
RequestHandler& request_handler; RequestHandler& request_handler;
boost::array<char, 8192> incoming_data_buffer; boost::array<char, 8192> incoming_data_buffer;
Request request; Request request;
RequestParser request_parser; RequestParser * request_parser;
Reply reply; Reply reply;
}; };
+132
View File
@@ -0,0 +1,132 @@
/*
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/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 <osrm/Coordinate.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 bool EdgeIsCompressed( const unsigned id ) const = 0;
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const = 0;
virtual void GetUncompressedGeometry(
const unsigned id,
std::vector<unsigned> & result_nodes
) 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 EscapeJSONString(temporary_string);
}
virtual std::string GetTimestamp() const = 0;
};
#endif // QUERY_DATA_FACADE_H
+485
View File
@@ -0,0 +1,485 @@
/*
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/OriginalEdgeData.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/ProgramOptions.h"
#include "../../Util/SimpleLogger.h"
#include <osrm/Coordinate.h>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
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;
boost::shared_ptr<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;
ShM<bool, false>::vector m_egde_is_compressed;
ShM<unsigned, false>::vector m_geometry_indices;
ShM<unsigned, false>::vector m_geometry_list;
boost::shared_ptr<
StaticRTree<
RTreeLeaf,
ShM<FixedPointCoordinate, false>::vector,
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
);
NodeInfo current_node;
unsigned number_of_coordinates = 0;
nodes_input_stream.read(
(char *)&number_of_coordinates,
sizeof(unsigned)
);
m_coordinate_list = boost::make_shared<std::vector<FixedPointCoordinate> >(number_of_coordinates);
for(unsigned i = 0; i < number_of_coordinates; ++i) {
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
m_coordinate_list->at(i) = FixedPointCoordinate(
current_node.lat,
current_node.lon
);
BOOST_ASSERT( ( std::abs(m_coordinate_list->at(i).lat) >> 30) == 0 );
BOOST_ASSERT( ( std::abs(m_coordinate_list->at(i).lon) >> 30) == 0 );
}
nodes_input_stream.close();
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);
m_egde_is_compressed.resize (number_of_edges);
unsigned compressed = 0;
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.via_node;
m_name_ID_list[i] = current_edge_data.name_id;
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
m_egde_is_compressed[i] = current_edge_data.compressed_geometry;
if(m_egde_is_compressed[i]) {
++compressed;
}
}
edges_input_stream.close();
}
void LoadGeometries(const boost::filesystem::path & geometry_file)
{
std::ifstream geometry_stream(
geometry_file.c_str(),
std::ios::binary
);
unsigned number_of_indices = 0;
unsigned number_of_compressed_geometries = 0;
geometry_stream.read(
(char *)&number_of_indices,
sizeof(unsigned)
);
m_geometry_indices.resize(number_of_indices);
geometry_stream.read(
(char *)&(m_geometry_indices[0]),
number_of_indices*sizeof(unsigned)
);
geometry_stream.read(
(char *)&number_of_compressed_geometries,
sizeof(unsigned)
);
BOOST_ASSERT( m_geometry_indices.back() == number_of_compressed_geometries );
m_geometry_list.resize( number_of_compressed_geometries );
geometry_stream.read(
(char *)&(m_geometry_list[0]),
number_of_compressed_geometries*sizeof(unsigned)
);
geometry_stream.close();
}
void LoadRTree(
const boost::filesystem::path & ram_index_path,
const boost::filesystem::path & file_index_path
) {
BOOST_ASSERT_MSG(
!m_coordinate_list->empty(),
"coordinates must be loaded before r-tree"
);
m_static_rtree = boost::make_shared<StaticRTree<RTreeLeaf> >(
ram_index_path,
file_index_path,
m_coordinate_list
);
}
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;
m_static_rtree.reset();
}
explicit 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("geometries") == server_paths.end() ) {
throw OSRMException("no geometries 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;
paths_iterator = server_paths.find("geometries");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & geometries_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 geometries";
LoadGeometries( geometries_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 {
return m_coordinate_list->at(id);
};
bool EdgeIsCompressed( const unsigned id ) const {
return m_egde_is_compressed.at(id);
}
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 {
const bool found = m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
);
return found;
}
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"
);
const unsigned begin_index = m_name_begin_indices[name_id];
const 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()
);
}
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const {
return m_via_node_list.at(id);
}
virtual void GetUncompressedGeometry(
const unsigned id, std::vector<unsigned> & result_nodes
) const {
const unsigned begin = m_geometry_indices.at(id);
const unsigned end = m_geometry_indices.at(id+1);
result_nodes.clear();
result_nodes.insert(result_nodes.begin(),
m_geometry_list.begin() + begin,
m_geometry_list.begin() + end);
}
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;
}
+72
View File
@@ -0,0 +1,72 @@
/*
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_BARRIER_H
#define SHARED_BARRIER_H
#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;
};
#endif //SHARED_BARRIER_H

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