Compare commits

...

1371 Commits

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

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

  * Luabind which is depending on Lua5.2

  * LuaJIT which has a Lua5.1 API

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

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

In compliance with the recommendations of section 4.2 of RFC2616, the header
is added before the existing entity headers.
2013-02-22 16:01:30 +01:00
DennisOSRM f7657280b6 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-02-22 15:50:07 +01:00
Emil Tin f88a4baf79 update bike tests 2013-02-22 15:49:44 +01:00
Emil Tin b051f715e6 add 'no' to barrier whitelist in bike profile 2013-02-22 15:49:44 +01:00
Emil Tin 81a05c89e4 update bike speeds 2013-02-22 15:49:44 +01:00
Emil Tin cc55b016e9 don't push against oneway flow on roundabout. fixes #591 2013-02-22 15:49:44 +01:00
DennisOSRM ae8e51074e Removing superflous inline statements 2013-02-22 15:49:44 +01:00
Emil Tin 313b93169d turn off turn restrictions for bicycle and foot, update tests 2013-02-22 15:49:44 +01:00
Emil Tin db148741e9 code cleanup 2013-02-22 15:49:43 +01:00
Emil Tin 1ecad20a0d support xml, move duplicated xml/pbf code to base 2013-02-22 15:49:43 +01:00
Emil Tin 22c5c539c2 default to using turn restrictions 2013-02-22 15:49:43 +01:00
Emil Tin d59e526e1e lua setting for using turn restrictions 2013-02-22 15:49:43 +01:00
Emil Tin 94fa0047db update bike tests 2013-02-19 08:54:23 +01:00
Emil Tin 26e2f9ddd1 add 'no' to barrier whitelist in bike profile 2013-02-19 08:38:10 +01:00
Emil Tin 23254b4f24 update bike speeds 2013-02-19 08:38:10 +01:00
Emil Tin 9a44f16846 don't push against oneway flow on roundabout. fixes #591 2013-02-15 17:02:49 +01:00
DennisOSRM cad0069be2 Minor refactoring/reordering 2013-02-14 17:12:52 +01:00
DennisOSRM f315a013b8 Refactoring InputEdge type and removing dead code 2013-02-14 17:12:12 +01:00
DennisOSRM f780aa6160 Saving 4 bytes on each original edge. Simplifying handling of original
edge data
2013-02-14 17:11:18 +01:00
DennisOSRM 0f03beb2b5 replacing c-style size_t with the one from std namespace 2013-02-12 15:46:40 +01:00
DennisOSRM 7e39c43896 allocate data in chunks of 8MB 2013-02-12 15:24:35 +01:00
DennisOSRM 906d28fa5d Correct wrong allocation, use std::vector for node array and pass PODs
by value not ref
2013-02-12 15:23:09 +01:00
DennisOSRM 4d017f5d49 Saving 4 bytes per edge 2013-02-12 11:35:59 +01:00
DennisOSRM 6410314b0b Add license attribution to GPX output 2013-02-12 10:57:33 +01:00
DennisOSRM 1c0202e790 Reordering initializations 2013-02-11 15:20:37 +01:00
DennisOSRM 918c978551 Fixes issue #585 2013-02-11 15:06:33 +01:00
DennisOSRM 3d1a85bbea Fixing compilation issues on various compilers, i.e. old GCC, clang,
ICPC
2013-02-10 18:18:39 +01:00
Dennis Luxen 1a442c36e9 Implementing #566 2013-02-10 15:05:31 +01:00
Emil Tin a4e322f085 don't allow bikes on highway=construction, fixes #582 2013-02-06 16:58:18 +01:00
DennisOSRM 0b1d268b09 Fixing issue that enters infinite loop under certain conditions 2013-02-06 15:23:57 +01:00
DennisOSRM c2be6bc019 Fixes issue #567 2013-02-05 16:06:10 +01:00
DennisOSRM 9e11e832da fixing symlink 2013-02-05 09:50:14 +01:00
DennisOSRM 348e656671 Merge branch 'feature/opposite_direction' into develop 2013-02-04 18:38:15 +01:00
DennisOSRM 54cdf6d6f2 maxspeed:forward and :backward get parsed and tests pass. Implements
#569 partially.
2013-02-04 15:58:35 +01:00
DennisOSRM 7c5ca8f199 ignore changes on profile symlink 2013-02-04 13:11:03 +01:00
DennisOSRM ee42d94e2d Fix test to reflect changed maxspeed behavior 2013-02-04 13:10:31 +01:00
DennisOSRM 91baa9dfd7 Merge completed 2013-02-04 13:05:05 +01:00
DennisOSRM 572b176401 Fixes issue #579 2013-02-04 12:13:30 +01:00
Emil Tin 97f1dc0749 update maxspeed tests, remove maxspeed from foot profile 2013-02-04 11:30:46 +01:00
Emil Tin d67ac1a708 fuzzy matching in routability tables, ported from opposite branch 2013-02-04 10:33:25 +01:00
DennisOSRM 2707001a3a Merge branch 'feature/opposite_direction' of https://DennisOSRM@github.com/DennisOSRM/Project-OSRM.git into feature/opposite_direction 2013-02-03 23:25:06 +01:00
Emil Tin bb1064ac42 remove a nearest test, for now 2013-02-03 21:01:10 +01:00
Emil Tin 436cc692da a few more test for nearest api 2013-02-03 20:37:22 +01:00
Emil Tin 76decf2e8b fix nearest test 2013-02-03 20:24:46 +01:00
Emil Tin ccdd0f599a test nearest API 2013-02-03 20:17:06 +01:00
Emil Tin c65fed1d38 simplify testbot maxspeed forw/back test 2013-02-03 18:23:23 +01:00
DennisOSRM c36ec7c95b Replacing profile.lua by a symlink 2013-02-03 18:17:22 +01:00
DennisOSRM 305ce04284 replacing by symlink 2013-02-03 18:16:36 +01:00
DennisOSRM 034ce137a9 removing file 2013-02-03 18:15:39 +01:00
Emil Tin 73c81a0a6c Removing debug output 2013-02-03 18:13:57 +01:00
DennisOSRM 7544727f7a Turn on all warnings during build by default 2013-02-03 17:08:15 +01:00
DennisOSRM 961a379f79 Fixing signed/unsigned comparison warnings 2013-02-03 17:07:31 +01:00
DennisOSRM 9ffcaa5550 Fixed offset, moved rvalues to the left in comparisons and const'ed a
few things.
2013-02-03 16:56:59 +01:00
DennisOSRM 2dbae6ce51 Refactoring routing algorithms, alternative computation hastened by
sweeping the search space only once. Should fix #572
2013-02-03 16:47:32 +01:00
Emil Tin f7505e8877 test car maxspeed forw/backw (@todo) 2013-02-03 15:43:12 +01:00
Emil Tin c453f8e7a9 test car maxspeed forw/backw (@todo) 2013-02-03 15:42:14 +01:00
Emil Tin 3a4695713d test bike maxspeed forw/backw (@todo) 2013-02-03 15:34:41 +01:00
DennisOSRM 7d9d0878de Adding templated utility functions for repeated operations on containers 2013-02-03 14:59:10 +01:00
DennisOSRM 26729ca482 Fixing useless comparison 2013-02-03 14:57:40 +01:00
DennisOSRM 405600783e introducing further typedefs to make code more readable 2013-02-03 14:55:49 +01:00
DennisOSRM 5b5e9296b3 Adding const to parameter and rehash to give map 1000 buckets 2013-02-03 14:54:22 +01:00
Emil Tin dd5d520b53 update profile and tests for pushing of bikes 2013-02-03 14:46:18 +01:00
Emil Tin b3d517943a fuzzy ranges on routability tables, value shortcuts 2013-02-03 14:03:37 +01:00
DennisOSRM 59ca59d431 Using unordered_set where it suffices 2013-02-03 13:19:23 +01:00
DennisOSRM 78c92be14b Fixes issue #577, syntax error in JSONP response 2013-02-01 13:21:12 +01:00
DennisOSRM adf0c726ef Further changes to duration handling 2013-01-30 14:03:21 +01:00
DennisOSRM 9ecfed4e56 linking to car profile 2013-01-30 13:47:24 +01:00
DennisOSRM 9db884f371 Fixing duration parsing 2013-01-30 13:46:20 +01:00
DennisOSRM e0c211085c Handle route=shuttle_train again 2013-01-29 17:36:28 +01:00
DennisOSRM 555bfaf37a Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-01-29 17:19:54 +01:00
DennisOSRM bcf4af4a2f Duration tag now handles 'hh:mm', 'mm' as well as 'hh:mm:ss' 2013-01-29 10:11:04 +01:00
DennisOSRM 6a71163912 Merging further changes 2013-01-28 11:11:11 +01:00
Emil Tin cb2fcf4f52 add @todo tag to partial way duration test 2013-01-28 09:39:18 +01:00
Emil Tin 061d78c681 test partial duration of ways 2013-01-28 08:30:34 +01:00
DennisOSRM 0ffa973ec6 Exit gracefully when data is empty 2013-01-27 23:08:45 +01:00
DennisOSRM 03de87c213 Parsing duration when present 2013-01-27 23:06:23 +01:00
DennisOSRM 59481dd762 Adding duration member to way 2013-01-27 23:05:27 +01:00
DennisOSRM 86f4aebead Fixes test to expect time in minutes not seconds 2013-01-27 23:03:04 +01:00
DennisOSRM a92950d234 Fixes how durations are parsed 2013-01-27 23:01:37 +01:00
DennisOSRM ccdc6f1a63 Removing dead code 2013-01-27 23:00:06 +01:00
DennisOSRM 62cc8f456c Rebasing branch on develop 2013-01-27 14:49:47 +01:00
DennisOSRM f7c6b9a0f7 Fixed direction flag on split edges 2013-01-27 14:36:57 +01:00
DennisOSRM 01a6e3c619 Fixed the computation of reverse edge weight 2013-01-27 14:36:57 +01:00
DennisOSRM 6948d56e5d Fixing edge array sentinel at position n+1 2013-01-27 14:36:57 +01:00
DennisOSRM 6373b3e49c Adding first implementation of back() reference function 2013-01-27 14:36:57 +01:00
DennisOSRM 91dc1b6639 Adding curly braces where appropriate 2013-01-27 14:36:57 +01:00
DennisOSRM 6317b08090 Fixing test cases to check for different speeds in opposite direction 2013-01-27 14:36:57 +01:00
Emil Tin aae0547cca better testbot maxspeed handling, fix test 2013-01-27 14:36:56 +01:00
Emil Tin 4f9c422e2f test maxspeed forward/backward 2013-01-27 14:36:56 +01:00
Emil Tin 3595ac08f7 fix tag on @opposite test 2013-01-27 14:36:56 +01:00
Emil Tin 5339f440bd test forward/backward maxspeed (car) 2013-01-27 14:36:56 +01:00
Emil Tin 86d7442a5f support comments in test tables 2013-01-27 14:36:56 +01:00
DennisOSRM e6e5626a2c Implementing logic when route is going against one-way flow (think
bikes!)
2013-01-27 14:36:56 +01:00
DennisOSRM 4a52dd1c5b Fixing constant 2013-01-27 14:36:56 +01:00
DennisOSRM dd1302e8b1 Added new TurnInstruction that indicates when to go against oneway
streets. It's important for cycling.
2013-01-27 14:36:56 +01:00
DennisOSRM 7b4b7232fc Fixing test for opposite directions 2013-01-27 14:36:56 +01:00
DennisOSRM b069725df0 Support for backward speed in extractor 2013-01-27 14:36:56 +01:00
Emil Tin aa9d8c773f fix name of duration test 2013-01-26 19:06:30 +01:00
Emil Tin c68a03d05c add test scenario matching wiki graph explanation 2013-01-26 18:59:31 +01:00
Emil Tin cbea651cf8 test duration on ways 2013-01-26 18:58:33 +01:00
DennisOSRM b4ee345966 removing left-over debug output 2013-01-23 11:52:18 +01:00
DennisOSRM 296e7ccb08 Removing dead code 2013-01-23 11:34:16 +01:00
Emil Tin 43bb53e789 better testbot maxspeed handling, fix test 2013-01-19 16:00:44 +01:00
Emil Tin 384be58230 test maxspeed forward/backward 2013-01-19 13:10:11 +01:00
Emil Tin 46d1a87b89 fix tag on @opposite test 2013-01-19 13:07:21 +01:00
Emil Tin 7c8bf18cc6 test forward/backward maxspeed (car) 2013-01-19 13:06:52 +01:00
Emil Tin 35255d052d support comments in test tables 2013-01-19 13:06:52 +01:00
DennisOSRM cf5c776990 Implementing logic when route is going against one-way flow (think
bikes!)
2013-01-18 21:28:13 +01:00
DennisOSRM 9961172d70 Fixing constant 2013-01-18 19:33:51 +01:00
DennisOSRM c1c46544a6 Further optimizations 2013-01-18 19:08:22 +01:00
DennisOSRM fc24dbf9b7 Added new TurnInstruction that indicates when to go against oneway
streets. It's important for cycling.
2013-01-18 19:06:03 +01:00
DennisOSRM 7f311551dd Fixing test for opposite directions 2013-01-18 19:01:36 +01:00
DennisOSRM 1a6c01769e Support for backward speed in extractor 2013-01-18 19:01:36 +01:00
DennisOSRM 9da4e18099 Reordering padded struct 2013-01-18 18:59:38 +01:00
DennisOSRM b19e2fbafe Fixing test for opposite directions 2013-01-18 16:42:04 +01:00
DennisOSRM 7f69857376 Support for backward speed in extractor 2013-01-18 16:40:12 +01:00
DennisOSRM a64420d700 further const'ing 2013-01-11 22:22:57 +01:00
DennisOSRM 2ccd3da5b3 replacing unsafe strcpy operations 2013-01-11 22:13:02 +01:00
DennisOSRM 845c73af73 Removing unused table, Uninitialized scalar field (UNINIT_CTOR),
Coverity CID 751302
2013-01-11 20:44:35 +01:00
DennisOSRM f7d79209dc Fixing dereference after null check (Coverity: CID 967038) 2013-01-11 20:20:22 +01:00
DennisOSRM 0017aef89a Merge branch 'develop' of https://DennisOSRM@github.com/DennisOSRM/Project-OSRM.git into develop 2013-01-11 18:36:17 +01:00
DennisOSRM 7449f81ed4 Reordering members in struct to actually exploit four byte padding,
partially fixes #563
2013-01-11 18:36:00 +01:00
Emil Tin 724e96f0c1 test different forw/backw settings (@todo) 2013-01-11 18:16:17 +01:00
DennisOSRM 8158e7f1c5 Using explicit 64bit integer instead of compiler-dependent long long 2013-01-11 18:16:08 +01:00
Emil Tin 7d7baa70a9 test routes parsing (@todo) 2013-01-10 17:06:16 +01:00
Emil Tin 2e3947cc6d support list of ways in relations tests 2013-01-10 17:05:41 +01:00
Emil Tin 54774726b2 test separate weight/speed, still marked as @todo 2013-01-10 14:00:48 +01:00
DennisOSRM 2af9fcad68 Saving 3 bytes per original edge. 2013-01-06 19:38:03 +01:00
DennisOSRM fd79e81fe5 Removing explicit namespace usage 2013-01-06 19:06:17 +01:00
DennisOSRM 2b5e110719 Splitting utility header with ambigious name into two files with better
names
2013-01-06 19:03:04 +01:00
DennisOSRM 864c2d9f49 stray const keyword removed that prevented build 2013-01-06 17:58:02 +01:00
DennisOSRM 764fe533e8 Adding forgotten commit 2013-01-06 17:54:17 +01:00
DennisOSRM f1f59d770e Forgotten file. 2013-01-06 17:51:45 +01:00
DennisOSRM 950baaa9fc Merge branch 'develop' of https://DennisOSRM@github.com/DennisOSRM/Project-OSRM.git into develop 2013-01-06 17:48:30 +01:00
DennisOSRM 5b3aacb4b2 removing stringstream 2013-01-06 17:48:18 +01:00
Emil Tin d6adc56b3a add test for multiple except tag values in restrictions 2013-01-06 15:44:15 +01:00
DennisOSRM dbe1a4255c type change 2013-01-06 13:02:10 +01:00
DennisOSRM eed20b2271 several fixes to replace copied parameters with const refs. 2013-01-06 13:00:58 +01:00
DennisOSRM e70adbb1cb Using const-refs instead of copies when iterating vectors 2013-01-06 12:59:36 +01:00
DennisOSRM 06c22a478f fixing typo 2013-01-06 12:39:12 +01:00
Emil Tin 565b0e97d1 rename @weight test to @fastest 2013-01-06 11:51:45 +01:00
DennisOSRM 00168cb12f Removing dead code. 2013-01-05 22:47:12 +01:00
DennisOSRM ffdaa71086 Implementation of turn restriction exceptions 2013-01-05 19:20:25 +01:00
DennisOSRM 5de2aa1cbf fixing test and removing todo tag 2013-01-05 17:35:50 +01:00
DennisOSRM 64988ed831 Adding functionality for turn restriction exceptions to profile 2013-01-05 17:32:39 +01:00
DennisOSRM fa050ad616 Fixing registration of package path. 2013-01-05 17:27:10 +01:00
Project OSRM d2458f3169 Merge pull request #550 from ibikecph/lua_require
easy lua require()
2013-01-05 03:03:13 -08:00
Emil Tin 551af0e45a fix a few restrictions tests 2013-01-04 16:09:00 +01:00
DennisOSRM 4ac5440a4a Removing debug output 2013-01-04 12:49:31 +01:00
DennisOSRM 7c54d4e62f Fixes the Birminingham speed limit bug reported by Philip Barnes 2013-01-04 12:31:43 +01:00
DennisOSRM 8ab5915983 Add symlink to the profile in the respective folde 2013-01-04 12:23:25 +01:00
DennisOSRM 877865a4b1 removing profile 2013-01-04 12:22:09 +01:00
Dennis Luxen 7cf4d37595 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-01-02 00:41:08 +01:00
Dennis Luxen 80add9f820 Splitting monolithic extraction code into compile units 2013-01-02 00:33:39 +01:00
Dennis Luxen 12a35c1214 Splitting monolithic extraction code into compile units 2013-01-02 00:33:14 +01:00
Dennis Luxen 9379d2462e Splitting monolithic extraction code into compile units 2013-01-02 00:32:34 +01:00
Emil Tin c5e8bed1fb increase stxxl allocation used in tests, to avoid reallocation 2013-01-02 00:02:48 +01:00
Emil Tin 4aa7ade32c ordering includes alphabetically 2013-01-01 23:20:16 +01:00
Emil Tin c4ed218a7a Revert "remove unused struct MinimalEdgeData"
This reverts commit 0235cf5d8e.
2013-01-01 23:01:52 +01:00
Emil Tin ff417fac01 update ferry tests 2013-01-01 18:41:38 +01:00
Emil Tin 0f4207f85e show total running time when extracting 2013-01-01 17:25:40 +01:00
Emil Tin f4431ed837 simple rake tasks for extracting/preparing separately 2013-01-01 17:10:30 +01:00
Emil Tin 0235cf5d8e remove unused struct MinimalEdgeData 2012-12-31 11:22:56 +01:00
DennisOSRM 8fc8a4e303 Removing last remaining 'using namespace std' statement 2012-12-29 21:02:26 +01:00
DennisOSRM 943c15927a Fixing data type issue that prevented large files on windows. See issue
#55
2012-12-29 14:14:01 +01:00
Emil Tin 28f0782b17 code cleanup, merge Lua.h and LuaUtil.h 2012-12-28 22:40:00 +01:00
Emil Tin 09e331a76b fix gitignore to avoid ignoring subfolders. add missing lua file 2012-12-28 22:40:00 +01:00
Emil Tin ce43b09991 support lua require() 2012-12-28 22:40:00 +01:00
DennisOSRM f9ab8426ce Merging changes for 0.3.2 2012-12-26 18:37:57 +01:00
DennisOSRM b869184c10 Replaced submodule with a text referencing the subproject directly 2012-12-26 18:32:57 +01:00
DennisOSRM 68e39b8053 Removing Docs submodule 2012-12-26 18:29:16 +01:00
DennisOSRM 8e023418e4 Removing superflous file 2012-12-23 20:03:12 +01:00
315 changed files with 27553 additions and 14663 deletions
+54
View File
@@ -0,0 +1,54 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: true
AlwaysBreakTemplateDeclarations: false
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: false
ColumnLimit: 100
ConstructorInitializerAllOnOneLineOrOnePerLine: false
DerivePointerBinding: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: true
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000
PenaltyReturnTypeOnItsOwnLine: 60
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
Standard: Cpp11
IndentWidth: 4
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Allman
IndentFunctionDeclarationAfterType: false
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
...
+26 -17
View File
@@ -33,11 +33,11 @@ ehthumbs.db
Icon?
Thumbs.db
# SCons related files #
# build related files #
#######################
SconsBuilder*
.scon*
.build
/build/
/Util/UUID.cpp
/Util/GitDescription.cpp
# Eclipse related files #
#########################
@@ -54,30 +54,39 @@ stxxl.errlog
# compiled protobuffers #
#########################
DataStructures/pbf-proto/*.pb.h
DataStructures/pbf-proto/*.pb.cc
/DataStructures/pbf-proto/*.pb.h
/DataStructures/pbf-proto/*.pb.cc
# External Libs #
#################
lib/
win/lib
/lib/
/win/lib
# Visual Studio Temp + build Files #
####################################
win/*.user
win/*.ncb
win/*.suo
win/Debug/
win/Release/
win/bin/
win/bin-debug/
/win/*.user
/win/*.ncb
/win/*.suo
/win/Debug/
/win/Release/
/win/bin/
/win/bin-debug/
/osrm-extract
/osrm-io-benchmark
/osrm-components
/osrm-routed
/osrm-datastore
/osrm-prepare
/osrm-unlock-all
/osrm-cli
/nohup.out
# Sandbox folder #
###################
sandbox/
/sandbox/
test/profile.lua
/test/profile.lua
# Deprecated config file #
##########################
/server.ini
-3
View File
@@ -1,3 +0,0 @@
[submodule "Docs"]
path = Docs
url = https://github.com/DennisSchiefer/Project-OSRM-Web.git
+47
View File
@@ -0,0 +1,47 @@
language: cpp
compiler:
- gcc
# - clang
# Make sure CMake is installed
install:
- sudo apt-get update >/dev/null
- sudo apt-get -q install libprotoc-dev libprotobuf7 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:
- rvm use 1.9.3
- gem install bundler
- bundle install
- mkdir build
- cd build
- cmake .. $CMAKEOPTIONS
script:
- make -j 2
- cd ..
- cucumber -p verify
after_script:
# - cd ..
# - cucumber -p verify
branches:
only:
- master
- develop
cache:
- bundler
- apt
env:
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release" OSRM_PORT=5000 OSRM_TIMEOUT=60
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug" OSRM_PORT=5010 OSRM_TIMEOUT=60
notifications:
irc:
channels:
- irc.oftc.net#osrm
on_success: change
on_failure: always
use_notice: true
skip_join: false
recipients:
- dennis@mapbox.com
email:
on_success: change
on_failure: always
-11
View File
@@ -1,11 +0,0 @@
The following people contributed code to the Open Source Routing Machine:
Christian Vetter
Dennis Luxen
Ruslan Krenzler
Frederik Ramm
Bharath Vissapragada
Pascal Neis
Sasa Ivetic
Emil Tin
Henning Moll
-49
View File
@@ -1,49 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef BRESENHAM_H_
#define BRESENHAM_H_
#include <cmath>
#include <vector>
typedef std::pair<unsigned, unsigned> BresenhamPixel;
inline void Bresenham (int x0, int y0, int x1, int y1, std::vector<BresenhamPixel> &resultList) {
int dx = std::abs(x1-x0);
int dy = std::abs(y1-y0);
int sx = (x0 < x1 ? 1 : -1);
int sy = (y0 < y1 ? 1 : -1);
int err = dx - dy;
while(true) {
resultList.push_back(std::make_pair(x0,y0));
if(x0 == x1 && y0 == y1) break;
int e2 = 2* err;
if ( e2 > -dy) {
err -= dy;
x0 += sx;
}
if(e2 < dx) {
err+= dx;
y0 += sy;
}
}
}
#endif /* BRESENHAM_H_ */
-85
View File
@@ -1,85 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#include "CRC32.h"
CRC32::CRC32() : crc(0) {
crcFunction = detectBestCRC32C();
}
unsigned CRC32::SoftwareBasedCRC32(char *str, unsigned len, unsigned ) {
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_Processor;
CRC32_Processor.process_bytes( str, len);
return CRC32_Processor.checksum();
}
unsigned CRC32::SSEBasedCRC32( char *str, unsigned len, unsigned crc) {
unsigned q=len/sizeof(unsigned),
r=len%sizeof(unsigned),
*p=(unsigned*)str/*, crc*/;
//crc=0;
while (q--) {
__asm__ __volatile__(
".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
:"=S"(crc)
:"0"(crc), "c"(*p)
);
++p;
}
str=(char*)p;
while (r--) {
__asm__ __volatile__(
".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
:"=S"(crc)
:"0"(crc), "c"(*str)
);
++str;
}
return crc;
}
CRC32::CRC32CFunctionPtr CRC32::detectBestCRC32C() {
static const int SSE42_BIT = 20;
unsigned ecx = cpuid(1);
bool hasSSE42 = ecx & (1 << SSE42_BIT);
if (hasSSE42) {
std::cout << "using hardware base sse computation" << std::endl;
return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated;
} else {
std::cout << "using software base sse computation" << std::endl;
return &CRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
}
}
unsigned CRC32::cpuid(unsigned functionInput) {
unsigned eax;
unsigned ebx;
unsigned ecx;
unsigned edx;
asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (functionInput));
return ecx;
}
unsigned CRC32::operator()(char *str, unsigned len){
crc =((*this).*(crcFunction))(str, len, crc);
return crc;
}
-46
View File
@@ -1,46 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef CRC32_H_
#define CRC32_H_
#include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream>
class CRC32 {
private:
unsigned crc;
unsigned slowcrc_table[1<<8];
typedef boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> my_crc_32_type;
typedef unsigned (CRC32::*CRC32CFunctionPtr)(char *str, unsigned len, unsigned crc);
unsigned SoftwareBasedCRC32(char *str, unsigned len, unsigned crc);
unsigned SSEBasedCRC32( char *str, unsigned len, unsigned crc);
unsigned cpuid(unsigned functionInput);
CRC32CFunctionPtr detectBestCRC32C();
CRC32CFunctionPtr crcFunction;
public:
CRC32();
unsigned operator()(char *str, unsigned len);
virtual ~CRC32() {};
};
#endif /* CRC32_H_ */
+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)
);
}
}
}
}
+47 -104
View File
@@ -1,129 +1,72 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DOUGLASPEUCKER_H_
#define DOUGLASPEUCKER_H_
#include <cassert>
#include "../Util/SimpleLogger.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <cmath>
#include <cfloat>
#include <limits>
#include <stack>
#include <vector>
#include "../DataStructures/Coordinate.h"
/*This class object computes the bitvector of indicating generalized input points
* according to the (Ramer-)Douglas-Peucker algorithm.
/* This class object computes the bitvector of indicating generalized input
* points according to the (Ramer-)Douglas-Peucker algorithm.
*
* Input is vector of pairs. Each pair consists of the point information and a bit
* indicating if the points is present in the generalization.
* Input is vector of pairs. Each pair consists of the point information and a
* bit indicating if the points is present in the generalization.
* Note: points may also be pre-selected*/
//These thresholds are more or less heuristically chosen.
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
static double DouglasPeuckerThresholds[19] = { 32000000., 16240000., 80240000., 40240000., 20000000., 10000000., 500000., 240000., 120000., 60000., 30000., 19000., 5000., 2000., 200, 16, 6, 3. , 3. };
struct SegmentInformation;
template<class PointT>
class DouglasPeucker {
private:
typedef std::pair<std::size_t, std::size_t> PairOfPoints;
//Stack to simulate the recursion
std::stack<PairOfPoints > recursionStack;
/**
* This distance computation does integer arithmetic only and is about twice as fast as
* the other distance function. It is an approximation only, but works more or less ok.
*/
template<class CoordT>
inline int fastDistance(const CoordT& point, const CoordT& segA, const CoordT& segB) const {
const int p2x = (segB.lon - segA.lat);
const int p2y = (segB.lon - segA.lat);
const int something = p2x*p2x + p2y*p2y;
int u = (something < FLT_EPSILON ? 0 : ((point.lon - segA.lon) * p2x + (point.lat - segA.lat) * p2y) / something);
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;
}
std::stack<PairOfPoints> recursion_stack;
double ComputeDistance(
const FixedPointCoordinate& point,
const FixedPointCoordinate& segA,
const FixedPointCoordinate& segB
) const;
public:
void Run(std::vector<PointT> & inputVector, const unsigned zoomLevel) {
{
assert(zoomLevel < 19);
assert(1 < inputVector.size());
std::size_t leftBorderOfRange = 0;
std::size_t rightBorderOfRange = 1;
//Sweep linerarily over array and identify those ranges that need to be checked
// recursionStack.hint(inputVector.size());
do {
assert(inputVector[leftBorderOfRange].necessary);
assert(inputVector.back().necessary);
void Run(
std::vector<SegmentInformation> & input_geometry,
const unsigned zoom_level
);
if(inputVector[rightBorderOfRange].necessary) {
recursionStack.push(std::make_pair(leftBorderOfRange, rightBorderOfRange));
leftBorderOfRange = rightBorderOfRange;
}
++rightBorderOfRange;
} while( rightBorderOfRange < inputVector.size());
}
while(!recursionStack.empty()) {
//pop next element
const PairOfPoints pair = recursionStack.top();
recursionStack.pop();
assert(inputVector[pair.first].necessary);
assert(inputVector[pair.second].necessary);
assert(pair.second < inputVector.size());
assert(pair.first < pair.second);
int maxDistance = INT_MIN;
std::size_t indexOfFarthestElement = pair.second;
//find index idx of element with maxDistance
for(std::size_t i = pair.first+1; i < pair.second; ++i){
const double distance = std::fabs(fastDistance(inputVector[i].location, inputVector[pair.first].location, inputVector[pair.second].location));
if(distance > DouglasPeuckerThresholds[zoomLevel] && distance > maxDistance) {
indexOfFarthestElement = i;
maxDistance = distance;
}
}
if (maxDistance > DouglasPeuckerThresholds[zoomLevel]) {
// mark idx as necessary
inputVector[indexOfFarthestElement].necessary = true;
if (1 < indexOfFarthestElement - pair.first) {
recursionStack.push(std::make_pair(pair.first, indexOfFarthestElement) );
}
if (1 < pair.second - indexOfFarthestElement)
recursionStack.push(std::make_pair(indexOfFarthestElement, pair.second) );
}
}
}
};
#endif /* DOUGLASPEUCKER_H_ */
+91 -53
View File
@@ -1,49 +1,79 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ITERATORBASEDCRC32_H_
#define ITERATORBASEDCRC32_H_
*/
#ifndef ITERATOR_BASED_CRC32_H
#define ITERATOR_BASED_CRC32_H
#include "../Util/SimpleLogger.h"
#include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream>
#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>
class IteratorbasedCRC32 {
private:
typedef typename ContainerT::iterator ContainerT_iterator;
typedef typename ContainerT::iterator IteratorType;
unsigned crc;
unsigned slowcrc_table[1<<8];
typedef boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> my_crc_32_type;
typedef unsigned (IteratorbasedCRC32::*CRC32CFunctionPtr)(char *str, unsigned len, unsigned crc);
bool use_SSE42_CRC_function;
unsigned SoftwareBasedCRC32(char *str, unsigned len, unsigned ){
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_Processor;
CRC32_Processor.process_bytes( str, len);
return CRC32_Processor.checksum();
#if !defined(__x86_64__)
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_processor;
#endif
unsigned SoftwareBasedCRC32( char *str, unsigned len )
{
#if !defined(__x86_64__)
CRC32_processor.process_bytes( str, len);
return CRC32_processor.checksum();
#else
return 0;
#endif
}
unsigned SSEBasedCRC32( char *str, unsigned len, unsigned crc){
unsigned q=len/sizeof(unsigned),
r=len%sizeof(unsigned),
*p=(unsigned*)str/*, crc*/;
// adapted from http://byteworm.com/2010/10/13/crc32/
unsigned SSE42BasedCRC32( char *str, unsigned len )
{
#if defined(__x86_64__)
unsigned q = len/sizeof(unsigned);
unsigned r = len%sizeof(unsigned);
unsigned *p = (unsigned*)str;
//crc=0;
while (q--) {
@@ -64,47 +94,55 @@ private:
);
++str;
}
#endif
return crc;
}
unsigned cpuid(unsigned functionInput){
unsigned eax;
unsigned ebx;
unsigned ecx;
unsigned edx;
asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (functionInput));
inline unsigned cpuid() const
{
unsigned eax = 0, ebx = 0, ecx = 0, edx = 0;
// on X64 this calls hardware cpuid(.) instr. otherwise a dummy impl.
__get_cpuid( 1, &eax, &ebx, &ecx, &edx );
return ecx;
}
CRC32CFunctionPtr detectBestCRC32C(){
static const int SSE42_BIT = 20;
unsigned ecx = cpuid(1);
bool hasSSE42 = ecx & (1 << SSE42_BIT);
if (hasSSE42) {
std::cout << "using hardware base sse computation" << std::endl;
return &IteratorbasedCRC32::SSEBasedCRC32; //crc32 hardware accelarated;
bool DetectNativeCRC32Support()
{
static const int SSE42_BIT = 0x00100000;
const unsigned ecx = cpuid();
const bool has_SSE42 = ecx & SSE42_BIT;
if (has_SSE42) {
SimpleLogger().Write() << "using hardware based CRC32 computation";
} else {
std::cout << "using software base sse computation" << std::endl;
return &IteratorbasedCRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
SimpleLogger().Write() << "using software based CRC32 computation";
}
return has_SSE42;
}
CRC32CFunctionPtr crcFunction;
public:
IteratorbasedCRC32(): crc(0) {
crcFunction = detectBestCRC32C();
IteratorbasedCRC32() : crc(0)
{
use_SSE42_CRC_function = DetectNativeCRC32Support();
}
virtual ~IteratorbasedCRC32() {};
unsigned operator()( ContainerT_iterator iter, const ContainerT_iterator end) {
unsigned operator()( IteratorType iter, const IteratorType end )
{
unsigned crc = 0;
while(iter != end) {
char * data = reinterpret_cast<char*>(&(*iter) );
crc =((*this).*(crcFunction))(data, sizeof(typename ContainerT::value_type*), crc);
if (use_SSE42_CRC_function)
{
crc = SSE42BasedCRC32( data, sizeof(typename ContainerT::value_type) );
}
else
{
crc = SoftwareBasedCRC32( data, sizeof(typename ContainerT::value_type) );
}
++iter;
}
return crc;
}
};
#endif /* ITERATORBASEDCRC32_H_ */
#endif /* ITERATOR_BASED_CRC32_H */
+66 -33
View File
@@ -1,26 +1,36 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OBJECTTOBASE64_H_
#define OBJECTTOBASE64_H_
#include "../Util/StringUtil.h"
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
@@ -28,40 +38,63 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <algorithm>
#include <string>
#include "../Util/StringUtil.h"
#include <vector>
typedef
boost::archive::iterators::base64_from_binary<
boost::archive::iterators::transform_width<string::const_iterator, 6, 8>
> base64_t;
boost::archive::iterators::transform_width<const char *, 6, 8>
> base64_t;
typedef
boost::archive::iterators::transform_width<
boost::archive::iterators::binary_from_base64<string::const_iterator>, 8, 6
boost::archive::iterators::binary_from_base64<
std::string::const_iterator>, 8, 6
> binary_t;
template<class ToEncodeT>
static void EncodeObjectToBase64(const ToEncodeT & object, std::string& encoded) {
encoded.clear();
char * pointerToOriginalObject = (char *)&object;
encoded = std::string(base64_t(pointerToOriginalObject), base64_t(pointerToOriginalObject+sizeof(ToEncodeT)));
//replace "+" with "-" and "/" with "_"
template<class ObjectT>
static void EncodeObjectToBase64(const ObjectT & object, std::string& encoded) {
const char * char_ptr_to_object = (const char *)&object;
std::vector<unsigned char> data(sizeof(object));
std::copy(
char_ptr_to_object,
char_ptr_to_object + sizeof(ObjectT),
data.begin()
);
unsigned char number_of_padded_chars = 0; // is in {0,1,2};
while(data.size() % 3 != 0) {
++number_of_padded_chars;
data.push_back(0x00);
}
BOOST_ASSERT_MSG(
0 == data.size() % 3,
"base64 input data size is not a multiple of 3!"
);
encoded.resize(sizeof(ObjectT));
encoded.assign(
base64_t( &data[0] ),
base64_t( &data[0] + (data.size() - number_of_padded_chars) )
);
replaceAll(encoded, "+", "-");
replaceAll(encoded, "/", "_");
}
template<class ToEncodeT>
static void DecodeObjectFromBase64(ToEncodeT & object, const std::string& _encoded) {
template<class ObjectT>
static void DecodeObjectFromBase64(const std::string& input, ObjectT & object) {
try {
string encoded(_encoded);
std::string encoded(input);
//replace "-" with "+" and "_" with "/"
replaceAll(encoded, "-", "+");
replaceAll(encoded, "_", "/");
char * pointerToDecodedObject = (char *)&object;
std::string dec(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length() - 1));
std::copy ( dec.begin(), dec.end(), pointerToDecodedObject );
} catch(...) {}
std::copy (
binary_t( encoded.begin() ),
binary_t( encoded.begin() + encoded.length() - 1),
(char *)&object
);
} catch(...) { }
}
#endif /* OBJECTTOBASE64_H_ */
+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 += "]";
}
+46 -111
View File
@@ -1,134 +1,69 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef POLYLINECOMPRESSOR_H_
#define POLYLINECOMPRESSOR_H_
#include <string>
//#include "../DataStructures/ExtractorStructs.h"
#include "../DataStructures/SegmentInformation.h"
#include "../Util/StringUtil.h"
#include <string>
#include <vector>
class PolylineCompressor {
private:
inline void encodeVectorSignedNumber(std::vector<int> & numbers, std::string & output) const {
for(unsigned i = 0; i < numbers.size(); ++i) {
numbers[i] <<= 1;
if (numbers[i] < 0) {
numbers[i] = ~(numbers[i]);
}
}
for(unsigned i = 0; i < numbers.size(); ++i) {
encodeNumber(numbers[i], output);
}
}
void encodeVectorSignedNumber(
std::vector<int> & numbers,
std::string & output
) const;
inline void encodeNumber(int numberToEncode, std::string & output) const {
while (numberToEncode >= 0x20) {
int nextValue = (0x20 | (numberToEncode & 0x1f)) + 63;
output += (static_cast<char> (nextValue));
if(92 == nextValue)
output += (static_cast<char> (nextValue));
numberToEncode >>= 5;
}
numberToEncode += 63;
output += (static_cast<char> (numberToEncode));
if(92 == numberToEncode)
output += (static_cast<char> (numberToEncode));
}
void encodeNumber(int number_to_encode, std::string & output) const;
public:
inline void printEncodedString(const std::vector<SegmentInformation>& polyline, std::string &output) const {
std::vector<int> deltaNumbers;
output += "\"";
if(!polyline.empty()) {
_Coordinate lastCoordinate = polyline[0].location;
deltaNumbers.push_back( lastCoordinate.lat );
deltaNumbers.push_back( lastCoordinate.lon );
for(unsigned i = 1; i < polyline.size(); ++i) {
if(!polyline[i].necessary)
continue;
deltaNumbers.push_back(polyline[i].location.lat - lastCoordinate.lat);
deltaNumbers.push_back(polyline[i].location.lon - lastCoordinate.lon);
lastCoordinate = polyline[i].location;
}
encodeVectorSignedNumber(deltaNumbers, output);
}
output += "\"";
void printEncodedString(
const std::vector<SegmentInformation> & polyline,
std::string & output
) const;
}
void printEncodedString(
const std::vector<FixedPointCoordinate>& polyline,
std::string &output
) const;
inline void printEncodedString(const std::vector<_Coordinate>& polyline, std::string &output) const {
std::vector<int> deltaNumbers(2*polyline.size());
output += "\"";
if(!polyline.empty()) {
deltaNumbers[0] = polyline[0].lat;
deltaNumbers[1] = polyline[0].lon;
for(unsigned i = 1; i < polyline.size(); ++i) {
deltaNumbers[(2*i)] = (polyline[i].lat - polyline[i-1].lat);
deltaNumbers[(2*i)+1] = (polyline[i].lon - polyline[i-1].lon);
}
encodeVectorSignedNumber(deltaNumbers, output);
}
output += "\"";
}
void printUnencodedString(
const std::vector<FixedPointCoordinate> & polyline,
std::string & output
) const;
inline void printUnencodedString(std::vector<_Coordinate> & polyline, std::string & output) const {
output += "[";
std::string tmp;
for(unsigned i = 0; i < polyline.size(); i++) {
convertInternalLatLonToString(polyline[i].lat, tmp);
output += "[";
output += tmp;
convertInternalLatLonToString(polyline[i].lon, tmp);
output += ", ";
output += tmp;
output += "]";
if( i < polyline.size()-1 ) {
output += ",";
}
}
output += "]";
}
void printUnencodedString(
const std::vector<SegmentInformation> & polyline,
std::string & output
) const;
inline void printUnencodedString(std::vector<SegmentInformation> & polyline, std::string & output) const {
output += "[";
std::string tmp;
for(unsigned i = 0; i < polyline.size(); i++) {
if(!polyline[i].necessary)
continue;
convertInternalLatLonToString(polyline[i].location.lat, tmp);
output += "[";
output += tmp;
convertInternalLatLonToString(polyline[i].location.lon, tmp);
output += ", ";
output += tmp;
output += "]";
if( i < polyline.size()-1 ) {
output += ",";
}
}
output += "]";
}
};
#endif /* POLYLINECOMPRESSOR_H_ */
+357 -237
View File
@@ -1,91 +1,111 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STRONGLYCONNECTEDCOMPONENTS_H_
#define STRONGLYCONNECTEDCOMPONENTS_H_
#include <cassert>
#include <stack>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp>
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/NodeCoords.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/TurnInstructions.h"
// Strongly connected components using Tarjan's Algorithm
#include "../Util/SimpleLogger.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/integer.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#ifdef __APPLE__
#include <gdal.h>
#include <ogrsf_frmts.h>
#else
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#endif
#include <stack>
#include <vector>
class TarjanSCC {
private:
struct _NodeBasedEdgeData {
struct TarjanNode {
TarjanNode() : index(UINT_MAX), lowlink(UINT_MAX), onStack(false) {}
unsigned index;
unsigned lowlink;
bool onStack;
};
struct TarjanEdgeData {
int distance;
unsigned edgeBasedNodeID;
unsigned nameID:31;
bool shortcut:1;
short type;
bool isAccessRestricted:1;
bool forward:1;
bool backward:1;
bool roundabout:1;
bool ignoreInGrid:1;
short type;
bool isAccessRestricted;
bool reversedEdge:1;
};
struct _EdgeBasedEdgeData {
int distance;
unsigned via;
unsigned nameID;
bool forward;
bool backward;
TurnInstruction turnInstruction;
struct TarjanStackFrame {
explicit TarjanStackFrame(
NodeID v,
NodeID parent
) : v(v), parent(parent) { }
NodeID v;
NodeID parent;
};
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
typedef DynamicGraph<TarjanEdgeData> TarjanDynamicGraph;
typedef TarjanDynamicGraph::InputEdge TarjanEdge;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> restriction_target;
typedef std::vector<restriction_target> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned> RestrictionMap;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
std::vector<NodeInfo> m_coordinate_list;
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
boost::shared_ptr<TarjanDynamicGraph> m_node_based_graph;
boost::unordered_set<NodeID> m_barrier_node_list;
boost::unordered_set<NodeID> m_traffic_light_list;
unsigned m_restriction_counter;
RestrictionMap m_restriction_map;
public:
struct EdgeBasedNode {
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
@@ -104,241 +124,308 @@ public:
bool ignoreInGrid:1;
};
private:
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
struct TarjanNode {
TarjanNode() : index(UINT_MAX), lowlink(UINT_MAX), onStack(false) {}
unsigned index;
unsigned lowlink;
bool onStack;
};
struct TarjanStackFrame {
explicit TarjanStackFrame(NodeID _v, NodeID p) : v(_v), parent(p) {}
NodeID v;
NodeID parent;
};
public:
TarjanSCC(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) {
BOOST_FOREACH(_Restriction & restriction, irs) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode);
TarjanSCC(
int number_of_nodes,
std::vector<NodeBasedEdge> & input_edges,
std::vector<NodeID> & bn,
std::vector<NodeID> & tl,
std::vector<TurnRestriction> & irs,
std::vector<NodeInfo> & nI
) :
m_coordinate_list(nI),
m_restriction_counter(irs.size())
{
BOOST_FOREACH(const TurnRestriction & restriction, irs) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(
restriction.fromNode, restriction.viaNode
);
unsigned index;
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource);
if(restrIter == _restrictionMap.end()) {
index = _restrictionBucketVector.size();
_restrictionBucketVector.resize(index+1);
_restrictionMap[restrictionSource] = index;
RestrictionMap::iterator restriction_iterator = m_restriction_map.find(restrictionSource);
if(restriction_iterator == m_restriction_map.end()) {
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index+1);
m_restriction_map.insert(std::make_pair(restrictionSource, index));
} else {
index = restrIter->second;
index = restriction_iterator->second;
//Map already contains an is_only_*-restriction
if(_restrictionBucketVector.at(index).begin()->second)
if(m_restriction_bucket_list.at(index).begin()->second) {
continue;
else if(restriction.flags.isOnly){
} else if(restriction.flags.isOnly) {
//We are going to insert an is_only_*-restriction. There can be only one.
_restrictionBucketVector.at(index).clear();
m_restriction_bucket_list.at(index).clear();
}
}
_restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly));
m_restriction_bucket_list.at(index).push_back(
std::make_pair(restriction.toNode, restriction.flags.isOnly)
);
}
BOOST_FOREACH(NodeID id, bn) {
_barrierNodes[id] = true;
}
BOOST_FOREACH(NodeID id, tl) {
_trafficLights[id] = true;
}
m_barrier_node_list.insert(bn.begin(), bn.end());
m_traffic_light_list.insert(tl.begin(), tl.end());
DeallocatingVector< _NodeBasedEdge > edges;
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {
_NodeBasedEdge edge;
if(!i->isForward()) {
edge.source = i->target();
edge.target = i->source();
edge.data.backward = i->isForward();
edge.data.forward = i->isBackward();
DeallocatingVector< TarjanEdge > edge_list;
BOOST_FOREACH(const NodeBasedEdge & input_edge, input_edges) {
TarjanEdge edge;
if(!input_edge.isForward()) {
edge.source = input_edge.target();
edge.target = input_edge.source();
edge.data.backward = input_edge.isForward();
edge.data.forward = input_edge.isBackward();
} else {
edge.source = i->source();
edge.target = i->target();
edge.data.forward = i->isForward();
edge.data.backward = i->isBackward();
edge.source = input_edge.source();
edge.target = input_edge.target();
edge.data.forward = input_edge.isForward();
edge.data.backward = input_edge.isBackward();
}
if(edge.source == edge.target)
if(edge.source == edge.target) {
continue;
}
edge.data.distance = (std::max)((int)i->weight(), 1 );
assert( edge.data.distance > 0 );
edge.data.distance = (std::max)((int)input_edge.weight(), 1 );
BOOST_ASSERT( edge.data.distance > 0 );
edge.data.shortcut = false;
edge.data.roundabout = i->isRoundabout();
edge.data.ignoreInGrid = i->ignoreInGrid();
edge.data.nameID = i->name();
edge.data.type = i->type();
edge.data.isAccessRestricted = i->isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size();
edges.push_back( edge );
edge.data.roundabout = input_edge.isRoundabout();
edge.data.ignoreInGrid = input_edge.ignoreInGrid();
edge.data.nameID = input_edge.name();
edge.data.type = input_edge.type();
edge.data.isAccessRestricted = input_edge.isAccessRestricted();
edge.data.reversedEdge = false;
edge_list.push_back( edge );
if( edge.data.backward ) {
std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward();
edge.data.backward = i->isForward();
edge.data.edgeBasedNodeID = edges.size();
edges.push_back( edge );
edge.data.forward = input_edge.isBackward();
edge.data.backward = input_edge.isForward();
edge.data.reversedEdge = true;
edge_list.push_back( edge );
}
}
std::vector<NodeBasedEdge>().swap(inputEdges);
std::sort( edges.begin(), edges.end() );
_nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges );
std::vector<NodeBasedEdge>().swap(input_edges);
BOOST_ASSERT_MSG(
0 == input_edges.size() && 0 == input_edges.capacity(),
"input edge vector not properly deallocated"
);
std::sort( edge_list.begin(), edge_list.end() );
m_node_based_graph = boost::make_shared<TarjanDynamicGraph>(
number_of_nodes,
edge_list
);
}
~TarjanSCC() {
m_node_based_graph.reset();
}
void Run() {
Percent p(_nodeBasedGraph->GetNumberOfNodes());
//remove files from previous run if exist
DeleteFileIfExists("component.dbf");
DeleteFileIfExists("component.shx");
DeleteFileIfExists("component.shp");
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver;
Percent p(m_node_based_graph->GetNumberOfNodes());
OGRRegisterAll();
poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(
pszDriverName );
if( poDriver == NULL )
{
printf( "%s driver not available.\n", pszDriverName );
exit( 1 );
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver * poDriver = OGRSFDriverRegistrar::GetRegistrar()->
GetDriverByName( pszDriverName );
if( NULL == poDriver ) {
throw OSRMException("ESRI Shapefile driver not available");
}
OGRDataSource *poDS;
OGRDataSource * poDS = poDriver->CreateDataSource(
"component.shp",
NULL
);
poDS = poDriver->CreateDataSource( "component.shp", NULL );
if( poDS == NULL ) {
printf( "Creation of output file failed.\n" );
exit( 1 );
if( NULL == poDS ) {
throw OSRMException("Creation of output file failed");
}
OGRLayer *poLayer;
OGRLayer * poLayer = poDS->CreateLayer(
"component",
NULL,
wkbLineString,
NULL
);
poLayer = poDS->CreateLayer( "component", NULL, wkbLineString, NULL );
if( poLayer == NULL ) {
printf( "Layer creation failed.\n" );
exit( 1 );
if( NULL == poLayer ) {
throw OSRMException("Layer creation failed.");
}
//The following is a hack to distinguish between stuff that happens before the recursive call and stuff that happens after
std::stack<std::pair<bool, TarjanStackFrame> > recursionStack; //true = stuff before, false = stuff after call
std::stack<NodeID> tarjanStack;
std::vector<unsigned> componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX);
std::vector<NodeID> vectorOfComponentSizes;
std::vector<TarjanNode> tarjanNodes(_nodeBasedGraph->GetNumberOfNodes());
unsigned currentComponent = 0, sizeOfCurrentComponent = 0;
//The following is a hack to distinguish between stuff that happens
//before the recursive call and stuff that happens after
std::stack<std::pair<bool, TarjanStackFrame> > recursion_stack;
//true = stuff before, false = stuff after call
std::stack<NodeID> tarjan_stack;
std::vector<unsigned> components_index(
m_node_based_graph->GetNumberOfNodes(),
UINT_MAX
);
std::vector<NodeID> component_size_vector;
std::vector<TarjanNode> tarjan_node_list(
m_node_based_graph->GetNumberOfNodes()
);
unsigned component_index = 0, size_of_current_component = 0;
int index = 0;
for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) {
if(UINT_MAX == componentsIndex[node]) {
recursionStack.push(std::make_pair(true, TarjanStackFrame(node,node)) );
for(
NodeID node = 0, last_node = m_node_based_graph->GetNumberOfNodes();
node < last_node;
++node
) {
if(UINT_MAX == components_index[node]) {
recursion_stack.push(
std::make_pair(true, TarjanStackFrame(node,node))
);
}
while(!recursionStack.empty()) {
bool beforeRecursion = recursionStack.top().first;
TarjanStackFrame currentFrame = recursionStack.top().second;
while(!recursion_stack.empty()) {
bool before_recursion = recursion_stack.top().first;
TarjanStackFrame currentFrame = recursion_stack.top().second;
NodeID v = currentFrame.v;
// INFO("popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion");
recursionStack.pop();
recursion_stack.pop();
if(beforeRecursion) {
if(before_recursion) {
//Mark frame to handle tail of recursion
recursionStack.push(std::make_pair(false, currentFrame));
recursion_stack.push(std::make_pair(false, currentFrame));
//Mark essential information for SCC
tarjanNodes[v].index = index;
tarjanNodes[v].lowlink = index;
tarjanStack.push(v);
tarjanNodes[v].onStack = true;
tarjan_node_list[v].index = index;
tarjan_node_list[v].lowlink = index;
tarjan_stack.push(v);
tarjan_node_list[v].onStack = true;
++index;
// INFO("pushing " << v << " onto tarjan stack, idx[" << v << "]=" << tarjanNodes[v].index << ", lowlink["<< v << "]=" << tarjanNodes[v].lowlink);
//Traverse outgoing edges
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
_NodeBasedDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2);
// INFO("traversing edge (" << v << "," << vprime << ")");
if(UINT_MAX == tarjanNodes[vprime].index) {
recursionStack.push(std::make_pair(true,TarjanStackFrame(vprime, v)));
for(
TarjanDynamicGraph::EdgeIterator e2 = m_node_based_graph->BeginEdges(v);
e2 < m_node_based_graph->EndEdges(v);
++e2
) {
const TarjanDynamicGraph::NodeIterator vprime =
m_node_based_graph->GetTarget(e2);
if(UINT_MAX == tarjan_node_list[vprime].index) {
recursion_stack.push(
std::make_pair(
true,
TarjanStackFrame(vprime, v)
)
);
} else {
// INFO("Node " << vprime << " is already explored");
if(tarjanNodes[vprime].onStack) {
unsigned newLowlink = std::min(tarjanNodes[v].lowlink, tarjanNodes[vprime].index);
// INFO("Setting lowlink[" << v << "] from " << tarjanNodes[v].lowlink << " to " << newLowlink);
tarjanNodes[v].lowlink = newLowlink;
// } else {
// INFO("But node " << vprime << " is not on stack");
if(
tarjan_node_list[vprime].onStack &&
tarjan_node_list[vprime].index < tarjan_node_list[v].lowlink
) {
tarjan_node_list[v].lowlink = tarjan_node_list[vprime].index;
}
}
}
} else {
// INFO("we are at the end of recursion and checking node " << v);
{ // setting lowlink in its own scope so it does not pollute namespace
// NodeID parent = (UINT_MAX == tarjanNodes[v].parent ? v : tarjanNodes[v].parent );
// INFO("parent=" << currentFrame.parent);
// INFO("tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << currentFrame.parent << "].lowlink=" << tarjanNodes[currentFrame.parent].lowlink);
//Note the index shift by 1 compared to the recursive version
tarjanNodes[currentFrame.parent].lowlink = std::min(tarjanNodes[currentFrame.parent].lowlink, tarjanNodes[v].lowlink);
// INFO("Setting tarjanNodes[" << currentFrame.parent <<"].lowlink=" << tarjanNodes[currentFrame.parent].lowlink);
}
// INFO("tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << v << "].index=" << tarjanNodes[v].index);
tarjan_node_list[currentFrame.parent].lowlink =
std::min(
tarjan_node_list[currentFrame.parent].lowlink,
tarjan_node_list[v].lowlink
);
//after recursion, lets do cycle checking
//Check if we found a cycle. This is the bottom part of the recursion
if(tarjanNodes[v].lowlink == tarjanNodes[v].index) {
if(tarjan_node_list[v].lowlink == tarjan_node_list[v].index) {
NodeID vprime;
do {
// INFO("identified component " << currentComponent << ": " << tarjanStack.top());
vprime = tarjanStack.top(); tarjanStack.pop();
tarjanNodes[vprime].onStack = false;
componentsIndex[vprime] = currentComponent;
++sizeOfCurrentComponent;
vprime = tarjan_stack.top(); tarjan_stack.pop();
tarjan_node_list[vprime].onStack = false;
components_index[vprime] = component_index;
++size_of_current_component;
} while( v != vprime);
vectorOfComponentSizes.push_back(sizeOfCurrentComponent);
if(sizeOfCurrentComponent > 1000)
INFO("large component [" << currentComponent << "]=" << sizeOfCurrentComponent);
++currentComponent;
sizeOfCurrentComponent = 0;
component_size_vector.push_back(size_of_current_component);
if(size_of_current_component > 1000) {
SimpleLogger().Write() <<
"large component [" << component_index << "]=" <<
size_of_current_component;
}
++component_index;
size_of_current_component = 0;
}
}
}
}
INFO("identified: " << vectorOfComponentSizes.size() << " many components, marking small components");
SimpleLogger().Write() <<
"identified: " << component_size_vector.size() <<
" many components, marking small components";
int singleCounter = 0;
for(unsigned i = 0; i < vectorOfComponentSizes.size(); ++i){
if(1 == vectorOfComponentSizes[i])
++singleCounter;
// TODO/C++11: prime candidate for lambda function
unsigned size_one_counter = 0;
for(unsigned i = 0, end = component_size_vector.size(); i < end; ++i){
if(1 == component_size_vector[i]) {
++size_one_counter;
}
}
INFO("identified " << singleCounter << " SCCs of size 1");
p.reinit(_nodeBasedGraph->GetNumberOfNodes());
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
SimpleLogger().Write() <<
"identified " << size_one_counter << " SCCs of size 1";
uint64_t total_network_distance = 0;
p.reinit(m_node_based_graph->GetNumberOfNodes());
for(
TarjanDynamicGraph::NodeIterator u = 0, last_u_node = m_node_based_graph->GetNumberOfNodes();
u < last_u_node;
++u
) {
p.printIncrement();
for(
TarjanDynamicGraph::EdgeIterator e1 = m_node_based_graph->BeginEdges(u), last_edge = m_node_based_graph->EndEdges(u);
e1 < last_edge;
++e1
) {
if(!m_node_based_graph->GetEdgeData(e1).reversedEdge) {
continue;
}
const TarjanDynamicGraph::NodeIterator v = m_node_based_graph->GetTarget(e1);
total_network_distance += 100*FixedPointCoordinate::ApproximateDistance(
m_coordinate_list[u].lat,
m_coordinate_list[u].lon,
m_coordinate_list[v].lat,
m_coordinate_list[v].lon
);
if( SHRT_MAX != m_node_based_graph->GetEdgeData(e1).type ) {
BOOST_ASSERT(e1 != UINT_MAX);
BOOST_ASSERT(u != UINT_MAX);
BOOST_ASSERT(v != UINT_MAX);
const unsigned size_of_containing_component =
std::min(
component_size_vector[components_index[u]],
component_size_vector[components_index[v]]
);
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) {
assert(e1 != UINT_MAX);
assert(u != UINT_MAX);
assert(v != UINT_MAX);
//edges that end on bollard nodes may actually be in two distinct components
if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) {
//INFO("(" << inputNodeInfoList[u].lat/100000. << ";" << inputNodeInfoList[u].lon/100000. << ") -> (" << inputNodeInfoList[v].lat/100000. << ";" << inputNodeInfoList[v].lon/100000. << ")");
if(size_of_containing_component < 10) {
OGRLineString lineString;
lineString.addPoint(inputNodeInfoList[u].lon/100000., inputNodeInfoList[u].lat/100000.);
lineString.addPoint(inputNodeInfoList[v].lon/100000., inputNodeInfoList[v].lat/100000.);
lineString.addPoint(
m_coordinate_list[u].lon/COORDINATE_PRECISION,
m_coordinate_list[u].lat/COORDINATE_PRECISION
);
lineString.addPoint(
m_coordinate_list[v].lon/COORDINATE_PRECISION,
m_coordinate_list[v].lat/COORDINATE_PRECISION
);
OGRFeature * poFeature = OGRFeature::CreateFeature(
poLayer->GetLayerDefn()
);
OGRFeature *poFeature;
poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
poFeature->SetGeometry( &lineString );
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
{
ERR( "Failed to create feature in shapefile.\n" );
if( OGRERR_NONE != poLayer->CreateFeature(poFeature) ) {
throw OSRMException(
"Failed to create feature in shapefile."
);
}
OGRFeature::DestroyFeature( poFeature );
}
@@ -346,37 +433,70 @@ public:
}
}
OGRDataSource::DestroyDataSource( poDS );
std::vector<NodeID>().swap(vectorOfComponentSizes);
std::vector<NodeID>().swap(componentsIndex);
std::vector<NodeID>().swap(component_size_vector);
BOOST_ASSERT_MSG(
0 == component_size_vector.size() &&
0 == component_size_vector.capacity(),
"component_size_vector not properly deallocated"
);
std::vector<NodeID>().swap(components_index);
BOOST_ASSERT_MSG(
0 == components_index.size() && 0 == components_index.capacity(),
"icomponents_index not properly deallocated"
);
SimpleLogger().Write()
<< "total network distance: " <<
(uint64_t)total_network_distance/100/1000. <<
" km";
}
private:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const {
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
if (restrIter != _restrictionMap.end()) {
unsigned index = restrIter->second;
BOOST_FOREACH(RestrictionSource restrictionTarget, _restrictionBucketVector.at(index)) {
if(restrictionTarget.second) {
return restrictionTarget.first;
std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end()) {
const unsigned index = restriction_iterator->second;
BOOST_FOREACH(
const RestrictionSource & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(restriction_target.second) {
return restriction_target.first;
}
}
}
return UINT_MAX;
}
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const {
bool CheckIfTurnIsRestricted(
const NodeID u,
const NodeID v,
const NodeID w
) const {
//only add an edge if turn is not a U-turn except it is the end of dead-end street.
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
if (restrIter != _restrictionMap.end()) {
unsigned index = restrIter->second;
BOOST_FOREACH(RestrictionTarget restrictionTarget, _restrictionBucketVector.at(index)) {
if(w == restrictionTarget.first)
std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end()) {
const unsigned index = restriction_iterator->second;
BOOST_FOREACH(
const restriction_target & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(w == restriction_target.first) {
return true;
}
}
}
return false;
}
void DeleteFileIfExists(const std::string & file_name) const {
if (boost::filesystem::exists(file_name) ) {
boost::filesystem::remove(file_name);
}
}
};
#endif /* STRONGLYCONNECTEDCOMPONENTS_H_ */
+269
View File
@@ -0,0 +1,269 @@
cmake_minimum_required(VERSION 2.6)
project(OSRM)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CheckCXXCompilerFlag)
include(FindPackageHandleStandardArgs)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
git_describe(GIT_DESCRIPTION)
set(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
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UUID-Config.cmake
DEPENDS
${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
COMMENT "Configuring UUID.cpp"
VERBATIM)
add_custom_target(UUIDConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/UUID.cpp)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread)
configure_file(
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp
)
file(GLOB ExtractorGlob Extractor/*.cpp)
set(ExtractorSources extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources})
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp)
set(PrepareSources prepare.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources})
file(GLOB ServerGlob Server/*.cpp)
file(GLOB DescriptorGlob Descriptors/*.cpp)
file(GLOB DatastructureGlob DataStructures/SearchEngineData.cpp)
file(GLOB CoordinateGlob DataStructures/Coordinate.cpp)
file(GLOB AlgorithmGlob Algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
set(
OSRMSources
${LibOSRMGlob}
${DescriptorGlob}
${DatastructureGlob}
${CoordinateGlob}
${AlgorithmGlob}
${HttpGlob}
)
add_library(COORDLIB STATIC ${CoordinateGlob})
add_library(OSRM ${OSRMSources} Util/GitDescription.cpp Util/UUID.cpp)
add_library(UUID STATIC Util/UUID.cpp)
add_library(GITDESCRIPTION STATIC Util/GitDescription.cpp)
add_dependencies(UUID UUIDConfigure)
add_dependencies(GITDESCRIPTION GIT_DESCRIPTION)
add_executable(osrm-routed routed.cpp ${ServerGlob})
set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED)
add_executable(osrm-datastore datastore.cpp)
# Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_BUILD_TYPE Release)
endif()
if(CMAKE_BUILD_TYPE MATCHES Debug)
message(STATUS "Configuring OSRM in debug mode")
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
message(STATUS "adding profiling flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
set(CMAKE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
endif()
endif()
if(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "Configuring OSRM in release mode")
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)
set(CMAKE_OSX_ARCHITECTURES "x86_64")
message(STATUS "Set Architecture to x64 on OS X")
exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION)
string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION})
if(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()
#Check Boost
set(BOOST_MIN_VERSION "1.46.0")
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
if(NOT Boost_FOUND)
message(FATAL_ERROR "Fatal error: Boost (version >= 1.46.0) required.\n")
endif()
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(OSRM ${Boost_LIBRARIES} COORDLIB)
target_link_libraries(osrm-extract ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
target_link_libraries(osrm-prepare ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
target_link_libraries(osrm-routed ${Boost_LIBRARIES} OSRM UUID GITDESCRIPTION)
target_link_libraries(osrm-datastore ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
find_package(Threads REQUIRED)
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
find_package(Lua52)
if(NOT LUA52_FOUND)
find_package(Lua51 REQUIRED)
if(NOT APPLE)
find_package(LuaJIT 5.1)
endif()
else()
if(NOT APPLE)
find_package(LuaJIT 5.2)
endif()
endif()
if( LUAJIT_FOUND )
target_link_libraries(osrm-extract ${LUAJIT_LIBRARIES})
target_link_libraries(osrm-prepare ${LUAJIT_LIBRARIES})
else()
target_link_libraries(osrm-extract ${LUA_LIBRARY})
target_link_libraries(osrm-prepare ${LUA_LIBRARY})
endif()
include_directories(${LUA_INCLUDE_DIR})
find_package(LibXml2 REQUIRED)
include_directories(${LIBXML2_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LIBXML2_LIBRARIES})
find_package( Luabind REQUIRED )
include_directories(${LUABIND_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
find_package( STXXL REQUIRED )
include_directories(${STXXL_INCLUDE_DIR})
target_link_libraries(OSRM ${STXXL_LIBRARY})
target_link_libraries(osrm-extract ${STXXL_LIBRARY})
target_link_libraries(osrm-prepare ${STXXL_LIBRARY})
find_package( OSMPBF REQUIRED )
include_directories(${OSMPBF_INCLUDE_DIR})
target_link_libraries(osrm-extract ${OSMPBF_LIBRARY})
target_link_libraries(osrm-prepare ${OSMPBF_LIBRARY})
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${PROTOBUF_LIBRARY})
target_link_libraries(osrm-prepare ${PROTOBUF_LIBRARY})
find_package(BZip2 REQUIRED)
include_directories(${BZIP_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${BZIP2_LIBRARIES})
find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${ZLIB_LIBRARY})
target_link_libraries(osrm-routed ${ZLIB_LIBRARY})
if(WITH_TOOLS)
message(STATUS "Activating OSRM internal tools")
find_package(GDAL)
if(GDAL_FOUND)
add_executable(osrm-components Tools/componentAnalysis.cpp)
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(
osrm-components
${GDAL_LIBRARIES} ${Boost_LIBRARIES} UUID GITDESCRIPTION COORDLIB)
endif()
add_executable(osrm-cli Tools/simpleclient.cpp)
target_link_libraries(osrm-cli ${Boost_LIBRARIES} OSRM UUID GITDESCRIPTION)
add_executable(osrm-io-benchmark Tools/io-benchmark.cpp)
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES} GITDESCRIPTION)
add_executable(osrm-unlock-all Tools/unlock_all_mutexes.cpp)
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} GITDESCRIPTION)
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-unlock-all rt)
endif()
endif()
file(GLOB InstallGlob Include/osrm/*.h Library/OSRM.h)
# Add RPATH info to executables so that when they are run after being installed
# (i.e., from /usr/local/bin/) the linker can find library dependencies. For
# more info see http://www.cmake.org/Wiki/CMake_RPATH_handling
set_property(TARGET osrm-extract PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-prepare PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-datastore PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
install(FILES ${InstallGlob} DESTINATION include/osrm)
install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-prepare DESTINATION bin)
install(TARGETS osrm-datastore DESTINATION bin)
install(TARGETS osrm-routed DESTINATION bin)
install(TARGETS OSRM DESTINATION lib)
list(GET Boost_LIBRARIES 1 BOOST_LIBRARY_FIRST)
get_filename_component(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_FIRST}" PATH)
set(BOOST_LIBRARY_LISTING "-L${BOOST_LIBRARY_LISTING}")
foreach (lib ${Boost_LIBRARIES})
get_filename_component(BOOST_LIBRARY_NAME "${lib}" NAME_WE)
string(REPLACE "lib" "" BOOST_LIBRARY_NAME ${BOOST_LIBRARY_NAME})
set(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_LISTING} -l${BOOST_LIBRARY_NAME}")
endforeach ()
configure_file(${CMAKE_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
-261
View File
@@ -1,261 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef CONTRACTIONCLEANUP_H_INCLUDED
#define CONTRACTIONCLEANUP_H_INCLUDED
#include <algorithm>
#ifndef _WIN32
#include <sys/time.h>
#endif
#include "Contractor.h"
class ContractionCleanup {
private:
struct _CleanupHeapData {
NodeID parent;
_CleanupHeapData( NodeID p ) {
parent = p;
}
};
typedef BinaryHeap< NodeID, NodeID, int, _CleanupHeapData > _Heap;
struct _ThreadData {
_Heap* _heapForward;
_Heap* _heapBackward;
_ThreadData( NodeID nodes ) {
_heapBackward = new _Heap(nodes);
_heapForward = new _Heap(nodes);
}
~_ThreadData() {
delete _heapBackward;
delete _heapForward;
}
};
public:
struct Edge {
NodeID source;
NodeID target;
struct EdgeData {
NodeID via;
unsigned nameID;
int distance;
TurnInstruction turnInstruction;
bool shortcut:1;
bool forward:1;
bool backward:1;
} data;
bool operator<( const Edge& right ) const {
if ( source != right.source )
return source < right.source;
return target < right.target;
}
//sorts by source and other attributes
static bool CompareBySource( const Edge& left, const Edge& right ) {
if ( left.source != right.source )
return left.source < right.source;
int l = ( left.data.forward ? -1 : 0 ) + ( left.data.backward ? -1 : 0 );
int r = ( right.data.forward ? -1 : 0 ) + ( right.data.backward ? -1 : 0 );
if ( l != r )
return l < r;
if ( left.target != right.target )
return left.target < right.target;
return left.data.distance < right.data.distance;
}
bool operator== ( const Edge& right ) const {
return ( source == right.source && target == right.target && data.distance == right.data.distance &&
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward
&& data.via == right.data.via && data.nameID == right.data.nameID
);
}
};
ContractionCleanup( int numNodes, const std::vector< Edge >& edges ) {
_graph = edges;
_numNodes = numNodes;
}
~ContractionCleanup() {
}
void Run() {
RemoveUselessShortcuts();
}
template< class EdgeT >
void GetData( std::vector< EdgeT >& edges ) {
for ( int edge = 0, endEdges = ( int ) _graph.size(); edge != endEdges; ++edge ) {
if(_graph[edge].data.forward || _graph[edge].data.backward) {
EdgeT newEdge;
newEdge.source = _graph[edge].source;
newEdge.target = _graph[edge].target;
newEdge.data = _graph[edge].data;
edges.push_back( newEdge );
}
}
sort( edges.begin(), edges.end() );
}
private:
double _Timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
}
void BuildOutgoingGraph() {
//sort edges by source
sort( _graph.begin(), _graph.end(), Edge::CompareBySource );
try {
_firstEdge.resize( _numNodes + 1 );
} catch(...) {
ERR("Not enough RAM on machine");
return;
}
_firstEdge[0] = 0;
for ( NodeID i = 0, node = 0; i < ( NodeID ) _graph.size(); i++ ) {
while ( _graph[i].source != node )
_firstEdge[++node] = i;
if ( i == ( NodeID ) _graph.size() - 1 )
while ( node < _numNodes )
_firstEdge[++node] = ( int ) _graph.size();
}
}
void RemoveUselessShortcuts() {
int maxThreads = omp_get_max_threads();
std::vector < _ThreadData* > threadData;
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
threadData.push_back( new _ThreadData( _numNodes ) );
}
INFO("Scanning for useless shortcuts");
BuildOutgoingGraph();
/*
#pragma omp parallel for
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
//only remove shortcuts
if ( !_graph[i].data.shortcut )
continue;
if ( _graph[i].data.forward ) {
int result = _ComputeDistance( _graph[i].source, _graph[i].target, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.forward = false;
}
}
if ( _graph[i].data.backward ) {
int result = _ComputeDistance( _graph[i].target, _graph[i].source, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.backward = false;
}
}
}
*/
INFO("Removing edges");
int useful = 0;
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
if ( !_graph[i].data.forward && !_graph[i].data.backward && _graph[i].data.shortcut ) {
continue;
}
_graph[useful] = _graph[i];
useful++;
}
INFO("Removed " << _graph.size() - useful << " useless shortcuts");
_graph.resize( useful );
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
delete threadData[threadNum];
}
}
void _ComputeStep( _Heap* heapForward, _Heap* heapBackward, bool forwardDirection, NodeID* middle, int* targetDistance ) {
const NodeID node = heapForward->DeleteMin();
const int distance = heapForward->GetKey( node );
if ( distance > *targetDistance ) {
heapForward->DeleteAll();
return;
}
if ( heapBackward->WasInserted( node ) ) {
const int newDistance = heapBackward->GetKey( node ) + distance;
if ( newDistance < *targetDistance ) {
*middle = node;
*targetDistance = newDistance;
}
}
for ( int edge = _firstEdge[node], endEdges = _firstEdge[node + 1]; edge != endEdges; ++edge ) {
const NodeID to = _graph[edge].target;
const int edgeWeight = _graph[edge].data.distance;
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
if ( (forwardDirection ? _graph[edge].data.forward : _graph[edge].data.backward ) ) {
//New Node discovered -> Add to Heap + Node Info Storage
if ( !heapForward->WasInserted( to ) )
heapForward->Insert( to, toDistance, node );
//Found a shorter Path -> Update distance
else if ( toDistance < heapForward->GetKey( to ) ) {
heapForward->DecreaseKey( to, toDistance );
//new parent
heapForward->GetData( to ) = node;
}
}
}
}
int _ComputeDistance( NodeID source, NodeID target, _ThreadData * data ) {
data->_heapForward->Clear();
data->_heapBackward->Clear();
//insert source into heap
data->_heapForward->Insert( source, 0, source );
data->_heapBackward->Insert( target, 0, target );
int targetDistance = std::numeric_limits< int >::max();
NodeID middle = std::numeric_limits<NodeID>::max();
while ( data->_heapForward->Size() + data->_heapBackward->Size() > 0 ) {
if ( data->_heapForward->Size() > 0 ) {
_ComputeStep( data->_heapForward, data->_heapBackward, true, &middle, &targetDistance );
}
if ( data->_heapBackward->Size() > 0 ) {
_ComputeStep( data->_heapBackward, data->_heapForward, false, &middle, &targetDistance );
}
}
return targetDistance;
}
NodeID _numNodes;
std::vector< Edge > _graph;
std::vector< unsigned > _firstEdge;
};
#endif // CONTRACTIONCLEANUP_H_INCLUDED
+153 -124
View File
@@ -1,36 +1,32 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONTRACTOR_H_INCLUDED
#define CONTRACTOR_H_INCLUDED
#include <algorithm>
#include <limits>
#include <vector>
#include <cfloat>
#include <ctime>
#include <boost/foreach.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include "TemporaryStorage.h"
#include "../DataStructures/BinaryHeap.h"
@@ -40,15 +36,26 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/XORFastHash.h"
#include "../DataStructures/XORFastHashStorage.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <algorithm>
#include <limits>
#include <vector>
class Contractor {
private:
struct _ContractorEdgeData {
_ContractorEdgeData() :
struct ContractorEdgeData {
ContractorEdgeData() :
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) {}
unsigned distance;
unsigned id;
@@ -66,7 +73,7 @@ private:
_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, XORFastHashStorage<NodeID, NodeID> > _Heap;
typedef _DynamicGraph::InputEdge _ContractorEdge;
@@ -109,6 +116,7 @@ public:
Contractor( int nodes, ContainerT& inputEdges) {
std::vector< _ContractorEdge > edges;
edges.reserve(inputEdges.size()*2);
temp_edge_counter = 0;
typename ContainerT::deallocation_iterator diter = inputEdges.dbegin();
typename ContainerT::deallocation_iterator dend = inputEdges.dend();
@@ -117,12 +125,12 @@ public:
while(diter!=dend) {
newEdge.source = diter->source();
newEdge.target = diter->target();
newEdge.data = _ContractorEdgeData( (std::max)((int)diter->weight(), 1 ), 1, diter->id(), false, diter->isForward(), diter->isBackward());
assert( newEdge.data.distance > 0 );
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" );
#ifndef NDEBUG
if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) {
WARN("Edge weight large -> " << newEdge.data.distance);
SimpleLogger().Write(logWARNING) <<
"Edge weight large -> " << newEdge.data.distance;
}
#endif
edges.push_back( newEdge );
@@ -157,11 +165,13 @@ public:
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max();
//remove parallel edges
while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) {
if ( edges[i].data.forward )
if ( edges[i].data.forward) {
forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance );
if ( edges[i].data.backward )
}
if ( edges[i].data.backward) {
backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance );
i++;
}
++i;
}
//merge edges (s,t) and (t,s) into bidirectional edge
if ( forwardEdge.data.distance == backwardEdge.data.distance ) {
@@ -183,6 +193,7 @@ public:
_graph = boost::make_shared<_DynamicGraph>( nodes, edges );
edges.clear();
std::vector<_ContractorEdge>().swap(edges);
BOOST_ASSERT( 0 == edges.capacity() );
// unsigned maxdegree = 0;
// NodeID highestNode = 0;
//
@@ -194,22 +205,22 @@ public:
// }
// }
//
// INFO("edges at node with id " << highestNode << " has degree " << maxdegree);
// SimpleLogger().Write() << "edges at node with id " << highestNode << " has degree " << maxdegree;
// for(unsigned i = _graph->BeginEdges(highestNode); i < _graph->EndEdges(highestNode); ++i) {
// INFO(" ->(" << highestNode << "," << _graph->GetTarget(i) << "); via: " << _graph->GetEdgeData(i).via);
// SimpleLogger().Write() << " ->(" << highestNode << "," << _graph->GetTarget(i) << "); via: " << _graph->GetEdgeData(i).via;
// }
//Create temporary file
// GetTemporaryFileName(temporaryEdgeStorageFilename);
temporaryStorageSlotID = TemporaryStorage::GetInstance().allocateSlot();
edge_storage_slot = TemporaryStorage::GetInstance().AllocateSlot();
std::cout << "contractor finished initalization" << std::endl;
}
~Contractor() {
//Delete temporary file
// remove(temporaryEdgeStorageFilename.c_str());
TemporaryStorage::GetInstance().deallocateSlot(temporaryStorageSlotID);
TemporaryStorage::GetInstance().DeallocateSlot(edge_storage_slot);
}
void Run() {
@@ -230,8 +241,9 @@ public:
//initialize the variables
#pragma omp parallel for schedule ( guided )
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
for ( int x = 0; x < ( int ) numberOfNodes; ++x ) {
remainingNodes[x].id = x;
}
std::cout << "initializing elimination PQ ..." << std::flush;
#pragma omp parallel
@@ -242,20 +254,20 @@ public:
nodePriority[x] = _Evaluate( data, &nodeData[x], x );
}
}
std::cout << "ok" << std::endl << "preprocessing ..." << std::flush;
std::cout << "ok" << std::endl << "preprocessing " << numberOfNodes << " nodes ..." << std::flush;
bool flushedContractor = false;
while ( numberOfContractedNodes < numberOfNodes ) {
while ( numberOfNodes > 2 && numberOfContractedNodes < numberOfNodes ) {
if(!flushedContractor && (numberOfContractedNodes > (numberOfNodes*0.65) ) ){
DeallocatingVector<_ContractorEdge> newSetOfEdges; //this one is not explicitely cleared since it goes out of scope anywa
std::cout << " [flush " << numberOfContractedNodes << " nodes] " << std::flush;
//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;
}
threadData.clear();
//Create new priority array
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
@@ -272,26 +284,19 @@ public:
remainingNodes[newNodeID].id = newNodeID;
}
TemporaryStorage & tempStorage = TemporaryStorage::GetInstance();
//Write dummy number of edges to temporary file
// std::ofstream temporaryEdgeStorage(temporaryEdgeStorageFilename.c_str(), std::ios::binary);
long initialFilePosition = tempStorage.tell(temporaryStorageSlotID);
unsigned numberOfTemporaryEdges = 0;
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&numberOfTemporaryEdges, sizeof(unsigned));
//walk over all nodes
for(unsigned i = 0; i < _graph->GetNumberOfNodes(); ++i) {
//INFO("Restructuring node " << i << "|" << _graph->GetNumberOfNodes());
const NodeID start = i;
for(_DynamicGraph::EdgeIterator currentEdge = _graph->BeginEdges(start); currentEdge < _graph->EndEdges(start); ++currentEdge) {
_DynamicGraph::EdgeData & data = _graph->GetEdgeData(currentEdge);
const NodeID target = _graph->GetTarget(currentEdge);
if(UINT_MAX == newNodeIDFromOldNodeIDMap[i] ){
//Save edges of this node w/o renumbering.
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&start, sizeof(NodeID));
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&target, sizeof(NodeID));
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&data, sizeof(_DynamicGraph::EdgeData));
++numberOfTemporaryEdges;
}else {
tempStorage.WriteToSlot(edge_storage_slot, (char*)&start, sizeof(NodeID));
tempStorage.WriteToSlot(edge_storage_slot, (char*)&target, sizeof(NodeID));
tempStorage.WriteToSlot(edge_storage_slot, (char*)&data, sizeof(_DynamicGraph::EdgeData));
++temp_edge_counter;
} else {
//node is not yet contracted.
//add (renumbered) outgoing edges to new DynamicGraph.
_ContractorEdge newEdge;
@@ -299,17 +304,18 @@ public:
newEdge.target = newNodeIDFromOldNodeIDMap[target];
newEdge.data = data;
newEdge.data.originalViaNodeID = true;
assert(UINT_MAX != newNodeIDFromOldNodeIDMap[start] );
assert(UINT_MAX != newNodeIDFromOldNodeIDMap[target]);
BOOST_ASSERT_MSG(
UINT_MAX != newNodeIDFromOldNodeIDMap[start],
"new start id not resolveable"
);
BOOST_ASSERT_MSG(
UINT_MAX != newNodeIDFromOldNodeIDMap[target],
"new target id not resolveable"
);
newSetOfEdges.push_back(newEdge);
}
}
}
//Note the number of temporarily stored edges
tempStorage.seek(temporaryStorageSlotID, initialFilePosition);
tempStorage.writeToSlot(temporaryStorageSlotID, (char*)&numberOfTemporaryEdges, sizeof(unsigned));
// INFO("Flushed " << numberOfTemporaryEdges << " edges to disk");
//Delete map from old NodeIDs to new ones.
std::vector<NodeID>().swap(newNodeIDFromOldNodeIDMap);
@@ -378,10 +384,14 @@ public:
_DynamicGraph::EdgeIterator currentEdgeID = _graph->FindEdge(edge.source, edge.target);
if(currentEdgeID < _graph->EndEdges(edge.source) ) {
_DynamicGraph::EdgeData & currentEdgeData = _graph->GetEdgeData(currentEdgeID);
if( currentEdgeData.shortcut
&& edge.data.forward == currentEdgeData.forward
&& edge.data.backward == currentEdgeData.backward ) {
currentEdgeData.distance = std::min(currentEdgeData.distance, edge.data.distance);
if( currentEdgeData.shortcut &&
edge.data.forward == currentEdgeData.forward &&
edge.data.backward == currentEdgeData.backward &&
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;
}
}
@@ -422,77 +432,88 @@ public:
// avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
// quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
//
// INFO("rest: " << remainingNodes.size() << ", max: " << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", quad: " << quaddegree);
// SimpleLogger().Write() << "rest: " << remainingNodes.size() << ", max: " << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", quad: " << quaddegree;
p.printStatus(numberOfContractedNodes);
}
BOOST_FOREACH(_ThreadData * data, threadData)
BOOST_FOREACH(_ThreadData * data, threadData) {
delete data;
}
threadData.clear();
}
template< class Edge >
inline void GetEdges( DeallocatingVector< Edge >& edges ) {
Percent p (_graph->GetNumberOfNodes());
INFO("Getting edges of minimized graph");
SimpleLogger().Write() << "Getting edges of minimized graph";
NodeID numberOfNodes = _graph->GetNumberOfNodes();
if(oldNodeIDFromNewNodeIDMap.size()) {
if(_graph->GetNumberOfNodes()) {
Edge newEdge;
for ( NodeID node = 0; node < numberOfNodes; ++node ) {
p.printStatus(node);
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; ++edge ) {
const NodeID target = _graph->GetTarget( edge );
const _DynamicGraph::EdgeData& data = _graph->GetEdgeData( edge );
Edge newEdge;
newEdge.source = oldNodeIDFromNewNodeIDMap[node];
newEdge.target = oldNodeIDFromNewNodeIDMap[target];
assert(UINT_MAX != newEdge.source);
assert(UINT_MAX != newEdge.target);
if( !oldNodeIDFromNewNodeIDMap.empty() ) {
newEdge.source = oldNodeIDFromNewNodeIDMap[node];
newEdge.target = oldNodeIDFromNewNodeIDMap[target];
} else {
newEdge.source = node;
newEdge.target = target;
}
BOOST_ASSERT_MSG(
UINT_MAX != newEdge.source,
"Source id invalid"
);
BOOST_ASSERT_MSG(
UINT_MAX != newEdge.target,
"Target id invalid"
);
newEdge.data.distance = data.distance;
newEdge.data.shortcut = data.shortcut;
if(!data.originalViaNodeID)
if(
!data.originalViaNodeID &&
!oldNodeIDFromNewNodeIDMap.empty()
) {
newEdge.data.id = oldNodeIDFromNewNodeIDMap[data.id];
else
} else {
newEdge.data.id = data.id;
assert(newEdge.data.id != UINT_MAX);
}
BOOST_ASSERT_MSG(
newEdge.data.id != INT_MAX, //2^31
"edge id invalid"
);
newEdge.data.forward = data.forward;
newEdge.data.backward = data.backward;
edges.push_back( newEdge );
}
}
}
INFO("Renumbered edges of minimized graph, freeing space");
_graph.reset();
std::vector<NodeID>().swap(oldNodeIDFromNewNodeIDMap);
INFO("Loading temporary edges");
BOOST_ASSERT( 0 == oldNodeIDFromNewNodeIDMap.capacity() );
// std::ifstream temporaryEdgeStorage(temporaryEdgeStorageFilename.c_str(), std::ios::binary);
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.
NodeID start;
NodeID target;
//edges.reserve(edges.size()+numberOfTemporaryEdges);
_DynamicGraph::EdgeData data;
for(unsigned i = 0; i < numberOfTemporaryEdges; ++i) {
tempStorage.readFromSlot(temporaryStorageSlotID, (char*)&start, sizeof(NodeID));
tempStorage.readFromSlot(temporaryStorageSlotID, (char*)&target, sizeof(NodeID));
tempStorage.readFromSlot(temporaryStorageSlotID, (char*)&data, sizeof(_DynamicGraph::EdgeData));
Edge newEdge;
newEdge.source = start;
newEdge.target = target;
newEdge.data.distance = data.distance;
newEdge.data.shortcut = data.shortcut;
newEdge.data.id = data.id;
newEdge.data.forward = data.forward;
newEdge.data.backward = data.backward;
edges.push_back( newEdge );
Edge restored_edge;
for(unsigned i = 0; i < temp_edge_counter; ++i) {
tempStorage.ReadFromSlot(edge_storage_slot, (char*)&start, sizeof(NodeID));
tempStorage.ReadFromSlot(edge_storage_slot, (char*)&target, sizeof(NodeID));
tempStorage.ReadFromSlot(edge_storage_slot, (char*)&data, sizeof(_DynamicGraph::EdgeData));
restored_edge.source = start;
restored_edge.target = target;
restored_edge.data.distance = data.distance;
restored_edge.data.shortcut = data.shortcut;
restored_edge.data.id = data.id;
restored_edge.data.forward = data.forward;
restored_edge.data.backward = data.backward;
edges.push_back( restored_edge );
}
tempStorage.deallocateSlot(temporaryStorageSlotID);
INFO("Hierarchy has " << edges.size() << " edges");
tempStorage.DeallocateSlot(edge_storage_slot);
}
private:
@@ -515,24 +536,27 @@ private:
if ( heap.GetData( node ).target ) {
++targetsFound;
if ( targetsFound >= numTargets )
if ( targetsFound >= numTargets ) {
return;
}
}
//iterate over all edges of node
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) {
const _ContractorEdgeData& data = _graph->GetEdgeData( edge );
if ( !data.forward )
const ContractorEdgeData& data = _graph->GetEdgeData( edge );
if ( !data.forward ){
continue;
}
const NodeID to = _graph->GetTarget( edge );
if(middleNode == to)
if(middleNode == to) {
continue;
}
const int toDistance = distance + data.distance;
//New Node discovered -> Add to Heap + Node Info Storage
if ( !heap.WasInserted( to ) )
if ( !heap.WasInserted( to ) ) {
heap.Insert( to, toDistance, _HeapData(currentHop, false) );
}
//Found a shorter Path -> Update distance
else if ( toDistance < heap.GetKey( to ) ) {
heap.DecreaseKey( to, toDistance );
@@ -565,7 +589,7 @@ private:
std::vector< _ContractorEdge >& insertedEdges = data->insertedEdges;
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 );
if ( Simulate ) {
assert( stats != NULL );
@@ -581,9 +605,10 @@ private:
unsigned numTargets = 0;
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
const _ContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward )
const ContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward ) {
continue;
}
const NodeID target = _graph->GetTarget( outEdge );
const int pathDistance = inData.distance + outData.distance;
maxDistance = std::max( maxDistance, pathDistance );
@@ -593,15 +618,16 @@ private:
}
}
if( Simulate )
if( Simulate ) {
_Dijkstra( maxDistance, numTargets, 1000, data, node );
else
} else {
_Dijkstra( maxDistance, numTargets, 2000, data, node );
}
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
const _ContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward )
const ContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward ) {
continue;
}
const NodeID target = _graph->GetTarget( outEdge );
const int pathDistance = inData.distance + outData.distance;
const int distance = heap.GetKey( target );
@@ -614,7 +640,7 @@ private:
_ContractorEdge newEdge;
newEdge.source = source;
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 );
std::swap( newEdge.source, newEdge.target );
newEdge.data.forward = false;
@@ -641,8 +667,9 @@ private:
found = true;
break;
}
if ( !found )
if ( !found ) {
insertedEdges[insertedEdgesSize++] = insertedEdges[i];
}
}
insertedEdges.resize( insertedEdgesSize );
}
@@ -706,9 +733,10 @@ private:
if ( priority > targetPriority )
return false;
//tie breaking
if ( fabs(priority - targetPriority) < FLT_EPSILON && bias(node, target) ) {
if ( std::abs(priority - targetPriority) < std::numeric_limits<double>::epsilon() && bias(node, target) ) {
return false;
}
// TODO: C++11 copy_if with lambda
neighbours.push_back( target );
}
@@ -728,7 +756,7 @@ private:
if ( priority > targetPriority)
return false;
//tie breaking
if ( fabs(priority - targetPriority) < FLT_EPSILON && bias(node, target) ) {
if ( std::abs(priority - targetPriority) < std::numeric_limits<double>::epsilon() && bias(node, target) ) {
return false;
}
}
@@ -752,7 +780,8 @@ private:
boost::shared_ptr<_DynamicGraph> _graph;
std::vector<_DynamicGraph::InputEdge> contractedEdges;
unsigned temporaryStorageSlotID;
unsigned edge_storage_slot;
uint64_t temp_edge_counter;
std::vector<NodeID> oldNodeIDFromNewNodeIDMap;
XORFastHash fastHash;
};
File diff suppressed because it is too large Load Diff
+172 -104
View File
@@ -1,145 +1,213 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
/*
* This class constructs the edge base representation of a graph from a given node based edge list
*/
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// This class constructs the edge-expanded routing graph
#ifndef EDGEBASEDGRAPHFACTORY_H_
#define EDGEBASEDGRAPHFACTORY_H_
#include <algorithm>
#include <queue>
#include <vector>
#include <stxxl.h>
#include <cstdlib>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../Extractor/ExtractorStructs.h"
#include "../DataStructures/EdgeBasedNode.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/OriginalEdgeData.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/BaseConfiguration.h"
#include "../DataStructures/Restriction.h"
#include "../Util/LuaUtil.h"
#include "../Util/SimpleLogger.h"
#include "GeometryCompressor.h"
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <algorithm>
#include <iosfwd>
#include <queue>
#include <vector>
class EdgeBasedGraphFactory : boost::noncopyable {
public:
struct SpeedProfileProperties;
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 std::string & original_edge_data_filename,
const std::string & geometry_filename,
lua_State *myLuaState
);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
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 GetNumberOfEdgeBasedNodes() const;
struct SpeedProfileProperties{
SpeedProfileProperties() :
trafficSignalPenalty(0),
uTurnPenalty(0),
has_turn_penalty_function(false)
{ }
int trafficSignalPenalty;
int uTurnPenalty;
bool has_turn_penalty_function;
} speed_profile;
class EdgeBasedGraphFactory {
private:
struct _NodeBasedEdgeData {
struct NodeBasedEdgeData {
NodeBasedEdgeData() {
//TODO: proper c'tor
edgeBasedNodeID = UINT_MAX;
}
int distance;
unsigned edgeBasedNodeID;
unsigned nameID:31;
unsigned nameID;
short type;
bool isAccessRestricted:1;
bool shortcut:1;
bool forward:1;
bool backward:1;
bool roundabout:1;
bool ignoreInGrid:1;
short type;
bool isAccessRestricted;
};
bool ignore_in_grid:1;
bool contraFlow:1;
struct _EdgeBasedEdgeData {
int distance;
unsigned via;
unsigned nameID;
bool forward;
bool backward;
TurnInstruction turnInstruction;
};
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
public:
struct EdgeBasedNode {
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
void SwapDirectionFlags() {
bool temp_flag = forward;
forward = backward;
backward = temp_flag;
}
bool operator==(const EdgeBasedNode & other) const {
return id == other.id;
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);
}
NodeID id;
int lat1;
int lat2;
int lon1;
int lon2:31;
bool belongsToTinyComponent:1;
NodeID nameID;
unsigned weight:31;
bool ignoreInGrid:1;
};
unsigned m_turn_restrictions_count;
unsigned m_number_of_edge_based_nodes;
struct SpeedProfileProperties{
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0) {}
int trafficSignalPenalty;
int uTurnPenalty;
} speedProfile;
private:
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
typedef NodeBasedDynamicGraph::NodeIterator NodeIterator;
typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator;
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
std::vector<NodeInfo> m_node_info_list;
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
std::vector<EdgeBasedNode> m_edge_based_node_list;
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges;
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
std::vector<OriginalEdgeData> originalEdgeData;
boost::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
boost::unordered_set<NodeID> m_barrier_nodes;
boost::unordered_set<NodeID> m_traffic_lights;
RestrictionMap m_restriction_map;
GeometryCompressor m_geometry_compressor;
NodeID CheckForEmanatingIsOnlyTurn(
const NodeID u,
const NodeID v
) const;
bool CheckIfTurnIsRestricted(
const NodeID u,
const NodeID v,
const NodeID w
) const;
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
void InsertEdgeBasedNode(
_NodeBasedDynamicGraph::EdgeIterator e1,
_NodeBasedDynamicGraph::NodeIterator u,
_NodeBasedDynamicGraph::NodeIterator v,
bool belongsToTinyComponent);
template<class CoordinateT>
double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const;
// SRTMLookup srtmLookup;
NodeBasedDynamicGraph::NodeIterator u,
NodeBasedDynamicGraph::NodeIterator v,
NodeBasedDynamicGraph::EdgeIterator e1,
bool belongsToTinyComponent
);
void BFSCompentExplorer(
std::vector<unsigned> & component_index_list,
std::vector<unsigned> & component_index_size
) const;
public:
template< class InputEdgeT >
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, SpeedProfileProperties speedProfile);
void FlushVectorToStream(
std::ofstream & edge_data_file,
std::vector<OriginalEdgeData> & original_edge_data_vector
) const;
void Run(const char * originalEdgeDataFilename);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( DeallocatingVector< EdgeBasedNode> & nodes);
void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const;
unsigned GetNumberOfNodes() const;
void 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_ */
+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
+117 -99
View File
@@ -1,144 +1,162 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
#include <boost/foreach.hpp>
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "TemporaryStorage.h"
TemporaryStorage::TemporaryStorage() {
try {
tempDirectory = boost::filesystem::temp_directory_path();
} catch(boost::filesystem::filesystem_error & e) {
ERR("could not retrieve location of temporary path: " << e.what());
}
temp_directory = boost::filesystem::temp_directory_path();
}
TemporaryStorage & TemporaryStorage::GetInstance(){
static TemporaryStorage runningInstance;
return runningInstance;
static TemporaryStorage static_instance;
return static_instance;
}
TemporaryStorage::~TemporaryStorage() {
removeAll();
RemoveAll();
}
void TemporaryStorage::removeAll() {
void TemporaryStorage::RemoveAll() {
boost::mutex::scoped_lock lock(mutex);
for(unsigned slot_id = 0; slot_id < stream_data_list.size(); ++slot_id) {
DeallocateSlot(slot_id);
}
stream_data_list.clear();
}
int TemporaryStorage::AllocateSlot() {
boost::mutex::scoped_lock lock(mutex);
try {
for(unsigned slotID = 0; slotID < vectorOfStreamDatas.size(); ++slotID)
deallocateSlot(slotID);
stream_data_list.push_back(StreamData());
} catch(boost::filesystem::filesystem_error & e) {
ERR("could not retrieve location of temporary path: " << e.what());
Abort(e);
}
vectorOfStreamDatas.clear();
CheckIfTemporaryDeviceFull();
return stream_data_list.size() - 1;
}
int TemporaryStorage::allocateSlot() {
boost::mutex::scoped_lock lock(mutex);
void TemporaryStorage::DeallocateSlot(const int slot_id) {
try {
vectorOfStreamDatas.push_back(StreamData());
//INFO("created new temporary file: " << vectorOfStreamDatas.back().pathToTemporaryFile);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
return vectorOfStreamDatas.size() - 1;
}
void TemporaryStorage::deallocateSlot(int slotID) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
StreamData & data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(!boost::filesystem::exists(data.pathToTemporaryFile)) {
if(!boost::filesystem::exists(data.temp_path)) {
return;
}
if(data.streamToTemporaryFile->is_open())
data.streamToTemporaryFile->close();
//INFO("deallocating slot " << slotID << " and its file: " << data.pathToTemporaryFile);
boost::filesystem::remove(data.pathToTemporaryFile);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
}
void TemporaryStorage::writeToSlot(int slotID, char * pointer, std::streamsize size) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(!data.writeMode)
ERR("Writing after first read is not allowed");
data.streamToTemporaryFile->write(pointer, size);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
}
void TemporaryStorage::readFromSlot(int slotID, char * pointer, std::streamsize size) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(data.writeMode) {
data.writeMode = false;
data.streamToTemporaryFile->seekg(0, data.streamToTemporaryFile->beg);
if(data.temp_file->is_open()) {
data.temp_file->close();
}
data.streamToTemporaryFile->read(pointer, size);
boost::filesystem::remove(data.temp_path);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
Abort(e);
}
}
unsigned TemporaryStorage::getFreeBytesOnTemporaryDevice() {
boost::filesystem::space_info tempSpaceInfo;
void TemporaryStorage::WriteToSlot(
const int slot_id,
char * pointer,
const std::size_t size
) {
try {
tempSpaceInfo = boost::filesystem::space(tempDirectory);
StreamData & data = stream_data_list[slot_id];
BOOST_ASSERT(data.write_mode);
boost::mutex::scoped_lock lock(*data.readWriteMutex);
BOOST_ASSERT_MSG(
data.write_mode,
"Writing after first read is not allowed"
);
if( 1073741824 < data.buffer.size() ) {
data.temp_file->write(&data.buffer[0], data.buffer.size());
// data.temp_file->write(pointer, size);
data.buffer.clear();
CheckIfTemporaryDeviceFull();
}
data.buffer.insert(data.buffer.end(), pointer, pointer+size);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
Abort(e);
}
}
void TemporaryStorage::ReadFromSlot(
const int slot_id,
char * pointer,
const std::size_t size
) {
try {
StreamData & data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
if( data.write_mode ) {
data.write_mode = false;
data.temp_file->write(&data.buffer[0], data.buffer.size());
data.buffer.clear();
data.temp_file->seekg( data.temp_file->beg );
BOOST_ASSERT( data.temp_file->beg == data.temp_file->tellg() );
}
BOOST_ASSERT( !data.write_mode );
data.temp_file->read(pointer, size);
} catch(boost::filesystem::filesystem_error & 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;
try {
StreamData & data = vectorOfStreamDatas[slotID];
StreamData & data = stream_data_list[slot_id];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
position = data.streamToTemporaryFile->tellp();
position = data.temp_file->tellp();
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
// INFO("telling position: " << position);
Abort(e);
}
return position;
}
void TemporaryStorage::abort(boost::filesystem::filesystem_error& ) {
removeAll();
// ERR("I/O Error occured: " << e.what());
}
void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type position) {
try {
StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex);
data.streamToTemporaryFile->seekg(position);
// INFO("seeking to position: " << position);
} catch(boost::filesystem::filesystem_error & e) {
abort(e);
}
void TemporaryStorage::Abort(const boost::filesystem::filesystem_error& e) {
RemoveAll();
throw OSRMException(e.what());
}
+69 -65
View File
@@ -1,60 +1,49 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TEMPORARYSTORAGE_H_
#define TEMPORARYSTORAGE_H_
#include <vector>
#include <fstream>
#include "../Util/BoostFileSystemFix.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#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>
#include "../typedefs.h"
//This is one big workaround for latest boost renaming woes.
#ifndef BOOST_FILESYSTEM_VERSION
#warning Boost Installation with Filesystem3 (>=1.44) is required, activating workaround
#include <cstdio>
namespace boost {
namespace filesystem {
inline path temp_directory_path() {
char * buffer;
buffer = tmpnam (NULL);
return path(buffer);
}
inline path unique_path(const path&) {
return temp_directory_path();
}
}
}
#endif
#define BOOST_FILESYSTEM_VERSION 3
#include <vector>
#include <fstream>
/**
* This class implements a singleton file storage for temporary data.
@@ -65,50 +54,65 @@ inline path unique_path(const path&) {
* -> Data is written in first phase and reread in second.
*/
static boost::filesystem::path tempDirectory;
static boost::filesystem::path temp_directory;
static std::string TemporaryFilePattern("OSRM-%%%%-%%%%-%%%%");
class TemporaryStorage {
public:
static TemporaryStorage & GetInstance();
virtual ~TemporaryStorage();
int allocateSlot();
void deallocateSlot(int slotID);
void writeToSlot(int slotID, char * pointer, std::streamsize size);
void readFromSlot(int slotID, char * pointer, std::streamsize size);
int AllocateSlot();
void DeallocateSlot(const int slot_id);
void WriteToSlot(const int slot_id, char * pointer, const std::size_t size);
void ReadFromSlot(const int slot_id, char * pointer, const std::size_t size);
//returns the number of free bytes
unsigned getFreeBytesOnTemporaryDevice();
boost::filesystem::fstream::pos_type tell(int slotID);
void seek(int slotID, boost::filesystem::fstream::pos_type);
void removeAll();
uint64_t GetFreeBytesOnTemporaryDevice();
boost::filesystem::fstream::pos_type Tell(const int slot_id);
void RemoveAll();
private:
TemporaryStorage();
TemporaryStorage(TemporaryStorage const &){};
TemporaryStorage& operator=(TemporaryStorage const &) {
TemporaryStorage & operator=(TemporaryStorage const &) {
return *this;
}
void abort(boost::filesystem::filesystem_error& e);
;
void Abort(const boost::filesystem::filesystem_error& e);
void CheckIfTemporaryDeviceFull();
struct StreamData {
bool writeMode;
boost::filesystem::path pathToTemporaryFile;
boost::shared_ptr<boost::filesystem::fstream> streamToTemporaryFile;
bool write_mode;
boost::filesystem::path temp_path;
boost::shared_ptr<boost::filesystem::fstream> temp_file;
boost::shared_ptr<boost::mutex> readWriteMutex;
std::vector<char> buffer;
StreamData() :
writeMode(true),
pathToTemporaryFile (boost::filesystem::unique_path(tempDirectory.append(TemporaryFilePattern.begin(), TemporaryFilePattern.end()))),
streamToTemporaryFile(new boost::filesystem::fstream(pathToTemporaryFile, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
readWriteMutex(new boost::mutex)
write_mode(true),
temp_path(
boost::filesystem::unique_path(
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())
ERR("Aborting, because temporary file at " << pathToTemporaryFile << " could not be created");
if( temp_file->fail() ) {
throw OSRMException("temporary file could not be created");
}
}
};
//vector of file streams that is used to store temporary data
std::vector<StreamData> vectorOfStreamDatas;
boost::mutex mutex;
std::vector<StreamData> stream_data_list;
};
#endif /* TEMPORARYSTORAGE_H_ */
+92 -56
View File
@@ -1,40 +1,49 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
#ifndef BINARYHEAP_H_INCLUDED
#define BINARYHEAP_H_INCLUDED
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BINARY_HEAP_H
#define BINARY_HEAP_H
//Not compatible with non contiguous node ids
#include <cassert>
#include <limits>
#include <vector>
#include <algorithm>
#include <map>
#include <boost/unordered_map.hpp>
#include <boost/assert.hpp>
#include <algorithm>
#include <limits>
#include <map>
#include <vector>
template< typename NodeID, typename Key >
class ArrayStorage {
public:
ArrayStorage( size_t size ) : positions( new Key[size] ) {
explicit ArrayStorage( size_t size ) : positions( new Key[size] ) {
memset(positions, 0, size*sizeof(Key));
}
@@ -56,7 +65,7 @@ template< typename NodeID, typename Key >
class MapStorage {
public:
MapStorage( size_t ) {}
explicit MapStorage( size_t ) {}
Key &operator[]( NodeID node ) {
return nodes[node];
@@ -73,14 +82,25 @@ private:
template< typename NodeID, typename Key >
class UnorderedMapStorage {
typedef boost::unordered_map<NodeID, Key> UnorderedMapType;
typedef typename UnorderedMapType::iterator UnorderedMapIterator;
typedef typename UnorderedMapType::const_iterator UnorderedMapConstIterator;
public:
UnorderedMapStorage( size_t ) { }
explicit UnorderedMapStorage( size_t ) {
//hash table gets 1000 Buckets
nodes.rehash(1000);
}
Key &operator[]( NodeID node ) {
Key & operator[]( const NodeID node ) {
return nodes[node];
}
Key const & operator[]( const NodeID node ) const {
UnorderedMapConstIterator iter = nodes.find(node);
return iter->second;
}
void Clear() {
nodes.clear();
}
@@ -89,13 +109,13 @@ private:
boost::unordered_map< NodeID, Key > nodes;
};
template<typename NodeID = unsigned>
struct _SimpleHeapData {
NodeID parent;
_SimpleHeapData( NodeID p ) : parent(p) { }
};
template < typename NodeID, typename Key, typename Weight, typename Data, typename IndexStorage = ArrayStorage<NodeID, NodeID> >
template<
typename NodeID,
typename Key,
typename Weight,
typename Data,
typename IndexStorage = ArrayStorage<NodeID, NodeID>
>
class BinaryHeap {
private:
BinaryHeap( const BinaryHeap& right );
@@ -104,8 +124,10 @@ public:
typedef Weight WeightType;
typedef Data DataType;
BinaryHeap( size_t maxID )
: nodeIndex( maxID ) {
explicit BinaryHeap( size_t maxID )
:
nodeIndex( maxID )
{
Clear();
}
@@ -120,6 +142,10 @@ public:
return static_cast<Key>( heap.size() - 1 );
}
bool Empty() const {
return 0 == Size();
}
void Insert( NodeID node, Weight weight, const Data &data ) {
HeapElement element;
element.index = static_cast<NodeID>(insertedNodes.size());
@@ -137,18 +163,23 @@ public:
return insertedNodes[index].data;
}
Data const & GetData( NodeID node ) const {
const Key index = nodeIndex[node];
return insertedNodes[index].data;
}
Weight& GetKey( NodeID node ) {
const Key index = nodeIndex[node];
return insertedNodes[index].weight;
}
bool WasRemoved( NodeID node ) {
assert( WasInserted( node ) );
bool WasRemoved( const NodeID node ) {
BOOST_ASSERT( WasInserted( node ) );
const Key index = nodeIndex[node];
return insertedNodes[index].key == 0;
}
bool WasInserted( NodeID node ) {
bool WasInserted( const NodeID node ) {
const Key index = nodeIndex[node];
if ( index >= static_cast<Key> (insertedNodes.size()) )
return false;
@@ -156,12 +187,12 @@ public:
}
NodeID Min() const {
assert( heap.size() > 1 );
BOOST_ASSERT( heap.size() > 1 );
return insertedNodes[heap[1].index].node;
}
NodeID DeleteMin() {
assert( heap.size() > 1 );
BOOST_ASSERT( heap.size() > 1 );
const Key removedIndex = heap[1].index;
heap[1] = heap[heap.size()-1];
heap.pop_back();
@@ -180,10 +211,10 @@ public:
}
void DecreaseKey( NodeID node, Weight weight ) {
assert( UINT_MAX != node );
const Key index = nodeIndex[node];
Key key = insertedNodes[index].key;
assert ( key >= 0 );
BOOST_ASSERT( UINT_MAX != node );
const Key & index = nodeIndex[node];
Key & key = insertedNodes[index].key;
BOOST_ASSERT ( key >= 0 );
insertedNodes[index].weight = weight;
heap[key].weight = weight;
@@ -194,11 +225,13 @@ public:
private:
class HeapNode {
public:
HeapNode() {
}
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;
Key key;
@@ -218,14 +251,17 @@ private:
const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight;
Key nextKey = key << 1;
while ( nextKey < static_cast<Key>( heap.size() ) ) {
while( nextKey < static_cast<Key>( heap.size() ) ){
const Key nextKeyOther = nextKey + 1;
if ( ( nextKeyOther < static_cast<Key> ( heap.size() ) )&& ( heap[nextKey].weight > heap[nextKeyOther].weight) )
if (
( nextKeyOther < static_cast<Key>( heap.size() ) ) &&
( heap[nextKey].weight > heap[nextKeyOther].weight )
) {
nextKey = nextKeyOther;
if ( weight <= heap[nextKey].weight )
}
if ( weight <= heap[nextKey].weight ){
break;
}
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
key = nextKey;
@@ -241,7 +277,7 @@ private:
const Weight weight = heap[key].weight;
Key nextKey = key >> 1;
while ( heap[nextKey].weight > weight ) {
assert( nextKey != 0 );
BOOST_ASSERT( nextKey != 0 );
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
key = nextKey;
@@ -255,10 +291,10 @@ private:
void CheckHeap() {
#ifndef NDEBUG
for ( Key i = 2; i < (Key) heap.size(); ++i ) {
assert( heap[i].weight >= heap[i >> 1].weight );
BOOST_ASSERT( heap[i].weight >= heap[i >> 1].weight );
}
#endif
}
};
#endif //#ifndef BINARYHEAP_H_INCLUDED
#endif //BINARY_HEAP_H
+56 -40
View File
@@ -1,25 +1,34 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
#ifndef CONCURRENTQUEUE_H_INCLUDED
#define CONCURRENTQUEUE_H_INCLUDED
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONCURRENTQUEUE_H_
#define CONCURRENTQUEUE_H_
#include "../typedefs.h"
#include <boost/bind.hpp>
#include <boost/circular_buffer.hpp>
@@ -27,57 +36,64 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include "../typedefs.h"
template<typename Data>
class ConcurrentQueue {
typedef typename boost::circular_buffer<Data>::size_type size_t;
public:
ConcurrentQueue(const size_t max_size) : internal_queue(max_size) { }
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { }
inline void push(Data const& data) {
inline void push(const Data & data) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_full, this));
internal_queue.push_back(data);
m_not_full.wait(
lock,
boost::bind(&ConcurrentQueue<Data>::is_not_full, this)
);
m_internal_queue.push_back(data);
lock.unlock();
m_not_empty.notify_one();
}
inline bool empty() const {
return internal_queue.empty();
return m_internal_queue.empty();
}
inline void wait_and_pop(Data& popped_value) {
inline void wait_and_pop(Data & popped_value) {
boost::mutex::scoped_lock lock(m_mutex);
m_not_empty.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_empty, this));
popped_value=internal_queue.front();
internal_queue.pop_front();
m_not_empty.wait(
lock,
boost::bind(&ConcurrentQueue<Data>::is_not_empty, this)
);
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
lock.unlock();
m_not_full.notify_one();
}
inline bool try_pop(Data& popped_value) {
boost::mutex::scoped_lock lock(m_mutex);
if(internal_queue.empty()) {
if(m_internal_queue.empty()) {
return false;
}
popped_value=internal_queue.front();
internal_queue.pop_front();
popped_value=m_internal_queue.front();
m_internal_queue.pop_front();
lock.unlock();
m_not_full.notify_one();
return true;
}
private:
boost::circular_buffer<Data> internal_queue;
boost::mutex m_mutex;
boost::condition m_not_empty;
boost::condition m_not_full;
inline bool is_not_empty() const {
return !m_internal_queue.empty();
}
inline bool is_not_empty() const { return internal_queue.size() > 0; }
inline bool is_not_full() const { return internal_queue.size() < internal_queue.capacity(); }
inline bool is_not_full() const {
return m_internal_queue.size() < m_internal_queue.capacity();
}
boost::circular_buffer<Data> m_internal_queue;
boost::mutex m_mutex;
boost::condition m_not_empty;
boost::condition m_not_full;
};
#endif //#ifndef CONCURRENTQUEUE_H_INCLUDED
#endif /* CONCURRENTQUEUE_H_ */
+183
View File
@@ -0,0 +1,183 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osrm/Coordinate.h>
#include "../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 << ")";
}
-106
View File
@@ -1,106 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef COORDINATE_H_
#define COORDINATE_H_
#include <climits>
#include <iostream>
struct _Coordinate {
int lat;
int lon;
_Coordinate () : lat(INT_MIN), lon(INT_MIN) {}
_Coordinate (int t, int n) : lat(t) , lon(n) {}
void Reset() {
lat = INT_MIN;
lon = INT_MIN;
}
bool isSet() const {
return (INT_MIN != lat) && (INT_MIN != lon);
}
inline bool isValid() const {
if(lat > 90*100000 || lat < -90*100000 || lon > 180*100000 || lon <-180*100000) {
return false;
}
return true;
}
bool operator==(const _Coordinate & other) const {
return lat == other.lat && lon == other.lon;
}
};
inline std::ostream & operator<<(std::ostream & out, const _Coordinate & c){
out << "(" << c.lat << "," << c.lon << ")";
return out;
}
inline double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ) {
assert(lat1 != INT_MIN);
assert(lon1 != INT_MIN);
assert(lat2 != INT_MIN);
assert(lon2 != INT_MIN);
double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1/100000.;
double ln1 = lon1/100000.;
double lt2 = lat2/100000.;
double ln2 = lon2/100000.;
double dlat1=lt1*(RAD);
double dlong1=ln1*(RAD);
double dlat2=lt2*(RAD);
double dlong2=ln2*(RAD);
double dLong=dlong1-dlong2;
double dLat=dlat1-dlat2;
double aHarv= pow(sin(dLat/2.0),2.0)+cos(dlat1)*cos(dlat2)*pow(sin(dLong/2.),2);
double cHarv=2.*atan2(sqrt(aHarv),sqrt(1.0-aHarv));
//earth's radius from wikipedia varies between 6,356.750 km — 6,378.135 km (˜3,949.901 — 3,963.189 miles)
//The IUGG value for the equatorial radius of the Earth is 6378.137 km (3963.19 mile)
const double earth=6372797.560856;//I am doing miles, just change this to radius in kilometers to get distances in km
double distance=earth*cHarv;
return distance;
}
inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) {
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
}
inline double ApproximateDistanceByEuclid(const _Coordinate &c1, const _Coordinate &c2) {
assert(c1.lat != INT_MIN);
assert(c1.lon != INT_MIN);
assert(c2.lat != INT_MIN);
assert(c2.lon != INT_MIN);
const double RAD = 0.017453292519943295769236907684886;
const double lat1 = (c1.lat/100000.)*RAD;
const double lon1 = (c1.lon/100000.)*RAD;
const double lat2 = (c2.lat/100000.)*RAD;
const double lon2 = (c2.lon/100000.)*RAD;
const double x = (lon2-lon1) * cos((lat1+lat2)/2.);
const double y = (lat2-lat1);
const double earthRadius = 6372797.560856;
const double d = sqrt(x*x + y*y) * earthRadius;
return d;
}
#endif /* COORDINATE_H_ */
+108 -91
View File
@@ -1,28 +1,35 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DEALLOCATINGVECTOR_H_
#define DEALLOCATINGVECTOR_H_
#include <cassert>
#include <cstdlib>
#include <boost/assert.hpp>
#include <cstring>
#include <vector>
#if __cplusplus > 199711L
@@ -32,7 +39,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#endif
template<typename ElementT, size_t bucketSizeC = 10485760/sizeof(ElementT), bool DeallocateC = false>
template<typename ElementT, std::size_t bucketSizeC = 8388608/sizeof(ElementT), bool DeallocateC = false>
class DeallocatingVectorIterator : public std::iterator<std::random_access_iterator_tag, ElementT> {
protected:
@@ -41,45 +48,32 @@ protected:
//make constructors explicit, so we do not mix random access and deallocation iterators.
DeallocatingVectorIteratorState();
public:
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r) : mData(r.mData), mIndex(r.mIndex), mBucketList(r.mBucketList) {}
//explicit DeallocatingVectorIteratorState(const ElementT * ptr, const size_t idx, const std::vector<ElementT *> & input_list) : mData(ptr), mIndex(idx), mBucketList(input_list) {}
explicit DeallocatingVectorIteratorState(const size_t idx, std::vector<ElementT *> & input_list) : mData(DEALLOCATION_VECTOR_NULL_PTR), mIndex(idx), mBucketList(input_list) {
setPointerForIndex();
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r) : /*mData(r.mData),*/ mIndex(r.mIndex), mBucketList(r.mBucketList) {}
explicit DeallocatingVectorIteratorState(const std::size_t idx, std::vector<ElementT *> & input_list) : /*mData(DEALLOCATION_VECTOR_NULL_PTR),*/ mIndex(idx), mBucketList(input_list) {
}
ElementT * mData;
size_t mIndex;
std::size_t mIndex;
std::vector<ElementT *> & mBucketList;
inline void setPointerForIndex() {
if(bucketSizeC*mBucketList.size() <= mIndex) {
mData = DEALLOCATION_VECTOR_NULL_PTR;
return;
}
size_t _bucket = mIndex/bucketSizeC;
size_t _index = mIndex%bucketSizeC;
mData = &(mBucketList[_bucket][_index]);
if(DeallocateC) {
//if we hopped over the border of the previous bucket, then delete that bucket.
if(0 == _index && _bucket) {
delete[] mBucketList[_bucket-1];
mBucketList[_bucket-1] = DEALLOCATION_VECTOR_NULL_PTR;
}
}
}
inline bool operator!=(const DeallocatingVectorIteratorState &other) {
return (mData != other.mData) || (mIndex != other.mIndex) || (mBucketList != other.mBucketList);
return mIndex != other.mIndex;
}
inline bool operator==(const DeallocatingVectorIteratorState &other) {
return (mData == other.mData) && (mIndex == other.mIndex) && (mBucketList == other.mBucketList);
return mIndex == other.mIndex;
}
inline bool operator<(const DeallocatingVectorIteratorState &other) {
bool operator<(const DeallocatingVectorIteratorState &other) const {
return mIndex < other.mIndex;
}
bool operator>(const DeallocatingVectorIteratorState &other) const {
return mIndex > other.mIndex;
}
bool operator>=(const DeallocatingVectorIteratorState &other) const {
return mIndex >= other.mIndex;
}
//This is a hack to make assignment operator possible with reference member
inline DeallocatingVectorIteratorState& operator= (const DeallocatingVectorIteratorState &a) {
if (this != &a) {
@@ -102,69 +96,72 @@ public:
DeallocatingVectorIterator() {}
template<typename T2>
DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> & r) : mState(r.mState) {}
explicit DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> & r) : mState(r.mState) {}
DeallocatingVectorIterator(size_t idx, std::vector<ElementT *> & input_list) : mState(idx, input_list) {}
//DeallocatingVectorIterator(size_t idx, const std::vector<ElementT *> & input_list) : mState(idx, input_list) {}
DeallocatingVectorIterator(const DeallocatingVectorIteratorState & r) : mState(r) {}
DeallocatingVectorIterator(std::size_t idx, std::vector<ElementT *> & input_list) : mState(idx, input_list) {}
explicit DeallocatingVectorIterator(const DeallocatingVectorIteratorState & r) : mState(r) {}
template<typename T2>
DeallocatingVectorIterator& operator=(const DeallocatingVectorIterator<T2> &r) {
if(DeallocateC) assert(false);
if(DeallocateC) BOOST_ASSERT(false);
mState = r.mState; return *this;
}
inline DeallocatingVectorIterator& operator++() { //prefix
// if(DeallocateC) assert(false);
++mState.mIndex; mState.setPointerForIndex(); return *this;
++mState.mIndex;
return *this;
}
inline DeallocatingVectorIterator& operator--() { //prefix
if(DeallocateC) assert(false);
--mState.mIndex; mState.setPointerForIndex(); return *this;
if(DeallocateC) BOOST_ASSERT(false);
--mState.mIndex;
return *this;
}
inline DeallocatingVectorIterator operator++(int) { //postfix
DeallocatingVectorIteratorState _myState(mState);
mState.mIndex++; mState.setPointerForIndex();
mState.mIndex++;
return DeallocatingVectorIterator(_myState);
}
inline DeallocatingVectorIterator operator --(int) { //postfix
if(DeallocateC) assert(false);
inline DeallocatingVectorIterator operator--(int) { //postfix
if(DeallocateC) BOOST_ASSERT(false);
DeallocatingVectorIteratorState _myState(mState);
mState.mIndex--; mState.setPointerForIndex();
mState.mIndex--;
return DeallocatingVectorIterator(_myState);
}
inline DeallocatingVectorIterator operator+(const difference_type& n) const {
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex+=n; _myState.setPointerForIndex();
_myState.mIndex+=n;
return DeallocatingVectorIterator(_myState);
}
inline DeallocatingVectorIterator& operator+=(const difference_type& n) const {
inline DeallocatingVectorIterator& operator+=(const difference_type& n) {
mState.mIndex+=n; return *this;
}
inline DeallocatingVectorIterator operator-(const difference_type& n) const {
if(DeallocateC) assert(false);
if(DeallocateC) BOOST_ASSERT(false);
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex-=n; _myState.setPointerForIndex();
_myState.mIndex-=n;
return DeallocatingVectorIterator(_myState);
}
inline DeallocatingVectorIterator& operator-=(const difference_type &n) const {
if(DeallocateC) assert(false);
if(DeallocateC) BOOST_ASSERT(false);
mState.mIndex-=n; return *this;
}
inline reference operator*() const { return *mState.mData; }
inline pointer operator->() const { return mState.mData; }
inline reference operator[](const difference_type &n) const {
if(DeallocateC) assert(false);
DeallocatingVectorIteratorState _myState(mState);
_myState.mIndex += n;
_myState.setPointerForIndex;
return _myState.mData;
inline reference operator*() const {
std::size_t _bucket = mState.mIndex/bucketSizeC;
std::size_t _index = mState.mIndex%bucketSizeC;
return (mState.mBucketList[_bucket][_index]);
}
inline pointer operator->() const {
std::size_t _bucket = mState.mIndex/bucketSizeC;
std::size_t _index = mState.mIndex%bucketSizeC;
return &(mState.mBucketList[_bucket][_index]);
}
inline bool operator!=(const DeallocatingVectorIterator & other) {
@@ -175,20 +172,28 @@ public:
return mState == other.mState;
}
bool operator<(const DeallocatingVectorIterator & other) {
inline bool operator<(const DeallocatingVectorIterator & other) const {
return mState < other.mState;
}
inline bool operator>(const DeallocatingVectorIterator & other) const {
return mState > other.mState;
}
inline bool operator>=(const DeallocatingVectorIterator & other) const {
return mState >= other.mState;
}
difference_type operator-(const DeallocatingVectorIterator & other) {
if(DeallocateC) assert(false);
if(DeallocateC) BOOST_ASSERT(false);
return mState.mIndex-other.mState.mIndex;
}
};
template<typename ElementT, size_t bucketSizeC = 10485760/sizeof(ElementT) >
template<typename ElementT, std::size_t bucketSizeC = 8388608/sizeof(ElementT) >
class DeallocatingVector {
private:
size_t mCurrentSize;
std::size_t mCurrentSize;
std::vector<ElementT *> mBucketList;
public:
@@ -227,21 +232,21 @@ public:
}
inline void push_back(const ElementT & element) {
size_t _capacity = capacity();
std::size_t _capacity = capacity();
if(mCurrentSize == _capacity) {
mBucketList.push_back(new ElementT[bucketSizeC]);
}
size_t _index = size()%bucketSizeC;
std::size_t _index = size()%bucketSizeC;
mBucketList.back()[_index] = element;
++mCurrentSize;
}
inline void reserve(const size_t) const {
inline void reserve(const std::size_t) const {
//don't do anything
}
inline void resize(const size_t new_size) {
inline void resize(const std::size_t new_size) {
if(new_size > mCurrentSize) {
while(capacity() < new_size) {
mBucketList.push_back(new ElementT[bucketSizeC]);
@@ -249,7 +254,7 @@ public:
mCurrentSize = new_size;
}
if(new_size < mCurrentSize) {
size_t number_of_necessary_buckets = 1+(new_size / bucketSizeC);
std::size_t number_of_necessary_buckets = 1+(new_size / bucketSizeC);
for(unsigned i = number_of_necessary_buckets; i < mBucketList.size(); ++i) {
delete[] mBucketList[i];
@@ -259,16 +264,16 @@ public:
}
}
inline size_t size() const {
inline std::size_t size() const {
return mCurrentSize;
}
inline size_t capacity() const {
inline std::size_t capacity() const {
return mBucketList.size() * bucketSizeC;
}
inline iterator begin() {
return iterator(static_cast<size_t>(0), mBucketList);
return iterator(static_cast<std::size_t>(0), mBucketList);
}
inline iterator end() {
@@ -276,7 +281,7 @@ public:
}
inline deallocation_iterator dbegin() {
return deallocation_iterator(static_cast<size_t>(0), mBucketList);
return deallocation_iterator(static_cast<std::size_t>(0), mBucketList);
}
inline deallocation_iterator dend() {
@@ -284,24 +289,36 @@ public:
}
inline const_iterator begin() const {
return const_iterator(static_cast<size_t>(0), mBucketList);
return const_iterator(static_cast<std::size_t>(0), mBucketList);
}
inline const_iterator end() const {
return const_iterator(size(), mBucketList);
}
inline ElementT & operator[](const size_t index) {
size_t _bucket = index / bucketSizeC;
size_t _index = index % bucketSizeC;
inline ElementT & operator[](const std::size_t index) {
std::size_t _bucket = index / bucketSizeC;
std::size_t _index = index % bucketSizeC;
return (mBucketList[_bucket][_index]);
}
const inline ElementT & operator[](const size_t index) const {
size_t _bucket = index / bucketSizeC;
size_t _index = index % bucketSizeC;
const inline ElementT & operator[](const std::size_t index) const {
std::size_t _bucket = index / bucketSizeC;
std::size_t _index = index % bucketSizeC;
return (mBucketList[_bucket][_index]);
}
inline ElementT & back() {
std::size_t _bucket = mCurrentSize / bucketSizeC;
std::size_t _index = mCurrentSize % bucketSizeC;
return (mBucketList[_bucket][_index]);
}
const inline ElementT & back() const {
std::size_t _bucket = mCurrentSize / bucketSizeC;
std::size_t _index = mCurrentSize % bucketSizeC;
return (mBucketList[_bucket][_index]);
}
};
#endif /* DEALLOCATINGVECTOR_H_ */
+63 -57
View File
@@ -1,31 +1,41 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DYNAMICGRAPH_H_INCLUDED
#define DYNAMICGRAPH_H_INCLUDED
#include <vector>
#include "../DataStructures/DeallocatingVector.h"
#include <boost/assert.hpp>
#include <boost/integer.hpp>
#include <algorithm>
#include <limits>
#include "../DataStructures/DeallocatingVector.h"
#include <vector>
template< typename EdgeDataT>
class DynamicGraph {
@@ -47,20 +57,20 @@ class DynamicGraph {
};
//Constructs an empty graph with a given number of nodes.
DynamicGraph( int 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.resize( m_numNodes );
m_edges.reserve( m_numNodes * 1.1 );
m_edges.resize( m_numNodes );
}
template<class ContainerT>
DynamicGraph( const int nodes, const ContainerT &graph )
{
DynamicGraph( const int32_t nodes, const ContainerT &graph ) {
m_numNodes = nodes;
m_numEdges = ( EdgeIterator ) graph.size();
m_nodes.reserve( m_numNodes );
m_nodes.resize( m_numNodes );
m_nodes.reserve( m_numNodes +1);
m_nodes.resize( m_numNodes +1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for ( NodeIterator node = 0; node < m_numNodes; ++node ) {
@@ -72,6 +82,7 @@ class DynamicGraph {
m_nodes[node].edges = edge - lastEdge;
position += m_nodes[node].edges;
}
m_nodes.back().firstEdge = position;
m_edges.reserve( position * 1.1 );
m_edges.resize( position );
edge = 0;
@@ -79,7 +90,10 @@ class DynamicGraph {
for ( EdgeIterator i = m_nodes[node].firstEdge, e = m_nodes[node].firstEdge + m_nodes[node].edges; i != e; ++i ) {
m_edges[i].target = graph[edge].target;
m_edges[i].data = graph[edge].data;
GUARANTEE(graph[edge].data.distance > 0, "edge: " << edge << "(" << graph[edge].source << "," << graph[edge].target << ")=" << graph[edge].data.distance);
BOOST_ASSERT_MSG(
graph[edge].data.distance > 0,
"edge distance invalid"
);
++edge;
}
}
@@ -87,50 +101,44 @@ class DynamicGraph {
~DynamicGraph(){ }
unsigned GetNumberOfNodes() const
{
unsigned GetNumberOfNodes() const {
return m_numNodes;
}
unsigned GetNumberOfEdges() const
{
unsigned GetNumberOfEdges() const {
return m_numEdges;
}
unsigned GetOutDegree( const NodeIterator &n ) const
{
unsigned GetOutDegree( const NodeIterator n ) const {
return m_nodes[n].edges;
}
NodeIterator GetTarget( const EdgeIterator &e ) const
{
NodeIterator GetTarget( const EdgeIterator e ) const {
return NodeIterator( m_edges[e].target );
}
EdgeDataT &GetEdgeData( const EdgeIterator &e )
{
void SetTarget( const EdgeIterator e, const NodeIterator n ) {
m_edges[e].target = n;
}
EdgeDataT &GetEdgeData( const EdgeIterator e ) {
return m_edges[e].data;
}
const EdgeDataT &GetEdgeData( const EdgeIterator &e ) const
{
const EdgeDataT &GetEdgeData( const EdgeIterator e ) const {
return m_edges[e].data;
}
EdgeIterator BeginEdges( const NodeIterator &n ) const
{
//assert( EndEdges( n ) - EdgeIterator( _nodes[n].firstEdge ) <= 100 );
EdgeIterator BeginEdges( const NodeIterator n ) const {
return EdgeIterator( m_nodes[n].firstEdge );
}
EdgeIterator EndEdges( const NodeIterator &n ) const
{
EdgeIterator EndEdges( const NodeIterator n ) const {
return EdgeIterator( m_nodes[n].firstEdge + m_nodes[n].edges );
}
//adds an edge. Invalidates edge iterators for the source node
EdgeIterator InsertEdge( const NodeIterator &from, const NodeIterator &to, const EdgeDataT &data )
{
EdgeIterator InsertEdge( const NodeIterator from, const NodeIterator to, const EdgeDataT &data ) {
Node &node = m_nodes[from];
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
if ( newFirstEdge >= m_edges.size() || !isDummy( newFirstEdge ) ) {
@@ -164,20 +172,22 @@ class DynamicGraph {
}
//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];
#pragma omp atomic
--m_numEdges;
--node.edges;
BOOST_ASSERT(UINT_MAX != node.edges);
const unsigned last = node.firstEdge + node.edges;
BOOST_ASSERT( UINT_MAX != last);
//swap with last edge
m_edges[e] = m_edges[last];
makeDummy( last );
}
//removes all edges (source,target)
int DeleteEdgesTo( const NodeIterator source, const NodeIterator target )
{
int deleted = 0;
int32_t DeleteEdgesTo( const NodeIterator source, const NodeIterator target ) {
int32_t deleted = 0;
for ( EdgeIterator i = BeginEdges( source ), iend = EndEdges( source ); i < iend - deleted; ++i ) {
if ( m_edges[i].target == target ) {
do {
@@ -196,10 +206,9 @@ class DynamicGraph {
}
//searches for a specific edge
EdgeIterator FindEdge( const NodeIterator &from, const NodeIterator &to ) const
{
EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const {
for ( EdgeIterator i = BeginEdges( from ), iend = EndEdges( from ); i != iend; ++i ) {
if ( m_edges[i].target == to ) {
if ( to == m_edges[i].target ) {
return i;
}
}
@@ -208,13 +217,11 @@ class DynamicGraph {
protected:
bool isDummy( EdgeIterator edge ) const
{
bool isDummy( const EdgeIterator edge ) const {
return m_edges[edge].target == (std::numeric_limits< NodeIterator >::max)();
}
void makeDummy( EdgeIterator edge )
{
void makeDummy( const EdgeIterator edge ) {
m_edges[edge].target = (std::numeric_limits< NodeIterator >::max)();
}
@@ -233,9 +240,8 @@ class DynamicGraph {
NodeIterator m_numNodes;
EdgeIterator m_numEdges;
DeallocatingVector< Node > m_nodes;
DeallocatingVector< Edge > m_edges;
std::vector< Node > m_nodes;
DeallocatingVector< Edge > m_edges;
};
#endif // DYNAMICGRAPH_H_INCLUDED
+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
-82
View File
@@ -1,82 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef GRIDEDGE_H_
#define GRIDEDGE_H_
#include "Coordinate.h"
struct _GridEdge {
_GridEdge(NodeID n, NodeID na, int w, _Coordinate sc, _Coordinate tc, bool bttc) : edgeBasedNode(n), nameID(na), weight(w), startCoord(sc), targetCoord(tc), belongsToTinyComponent(bttc) {}
_GridEdge() : edgeBasedNode(UINT_MAX), nameID(UINT_MAX), weight(INT_MAX), belongsToTinyComponent(false) {}
NodeID edgeBasedNode;
NodeID nameID;
int weight;
_Coordinate startCoord;
_Coordinate targetCoord;
bool belongsToTinyComponent;
bool operator< ( const _GridEdge& right) const {
return edgeBasedNode < right.edgeBasedNode;
}
bool operator== ( const _GridEdge& right) const {
return edgeBasedNode == right.edgeBasedNode;
}
};
struct GridEntry {
GridEntry() : fileIndex(UINT_MAX), ramIndex(UINT_MAX){}
GridEntry(_GridEdge e, unsigned f, unsigned r) : edge(e), fileIndex(f), ramIndex(r) {}
_GridEdge edge;
unsigned fileIndex;
unsigned ramIndex;
bool operator< ( const GridEntry& right ) const {
return (edge.edgeBasedNode < right.edge.edgeBasedNode);
}
bool operator==( const GridEntry& right ) const {
return right.edge.edgeBasedNode == edge.edgeBasedNode;
}
};
struct CompareGridEdgeDataByFileIndex {
bool operator () (const GridEntry & a, const GridEntry & b) const {
return a.fileIndex < b.fileIndex;
}
};
struct CompareGridEdgeDataByRamIndex {
typedef GridEntry value_type;
bool operator () (const GridEntry & a, const GridEntry & b) const {
return a.ramIndex < b.ramIndex;
}
value_type max_value() {
GridEntry e;
e.ramIndex = (1024*1024) - 1;
return e;
}
value_type min_value() {
GridEntry e;
e.ramIndex = 0;
return e;
}
};
#endif /* GRIDEDGE_H_ */
+56 -62
View File
@@ -1,79 +1,73 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Created on: 18.11.2010
Author: dennis
*/
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef HASHTABLE_H_
#define HASHTABLE_H_
*/
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
#include <boost/functional/hash.hpp>
#include <boost/ref.hpp>
#include <boost/unordered_map.hpp>
template<typename keyT, typename valueT>
class HashTable {
typedef boost::unordered_map<keyT, valueT> MyHashTable;
template<typename Key, typename Value, typename Hash = boost::hash<Key> >
class HashTable : public boost::unordered_map<Key, Value> {
private:
typedef boost::unordered_map<Key, Value, Hash> super;
public:
typedef typename boost::unordered_map<keyT, valueT>::const_iterator MyIterator;
typedef MyIterator iterator;
HashTable() { }
HashTable(const unsigned size) {
table.resize(size);
}
inline void Add(const keyT& key, const valueT& value){
table[key] = value;
}
inline void Set(const keyT& key, const valueT& value){
table[key] = value;
}
inline valueT Find(const keyT& key) const {
if(table.find(key) == table.end())
return valueT();
return table.find(key)->second;
static Value default_value;
HashTable() : super() { }
explicit HashTable(const unsigned size) : super(size) { }
inline void Add( Key const & key, Value const & value) {
super::emplace(std::make_pair(key, value));
}
inline bool Holds(const keyT& key) const {
if(table.find(key) == table.end())
inline const Value Find(Key const & key) const
{
typename super::const_iterator iter = super::find(key);
if (iter == super::end())
{
return boost::cref(default_value);
}
return boost::cref(iter->second);
}
inline const bool Holds( Key const & key) const
{
if(super::find(key) == super::end())
{
return false;
}
return true;
}
void EraseAll() {
if(table.size() > 0)
table.clear();
}
inline valueT operator[] (keyT key) const {
if(table.find(key) == table.end())
return valueT();
return table.find(key)->second;
}
inline unsigned Size() const {
return table.size();
}
MyIterator begin() const {
return table.begin();
}
MyIterator end() const {
return table.end();
}
private:
MyHashTable table;
};
#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;
}
}
+50
View File
@@ -0,0 +1,50 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HILBERTVALUE_H_
#define HILBERTVALUE_H_
#include <osrm/Coordinate.h>
#include <boost/integer.hpp>
#include <boost/noncopyable.hpp>
// computes a 64 bit value that corresponds to the hilbert space filling curve
class HilbertCode : boost::noncopyable
{
public:
uint64_t operator()
(
const FixedPointCoordinate & current_coordinate
) const;
private:
inline uint64_t BitInterleaving( const uint32_t a, const uint32_t b) const;
inline void TransposeCoordinate( uint32_t * X) const;
};
#endif /* HILBERTVALUE_H_ */
+133 -79
View File
@@ -1,31 +1,41 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef EDGE_H
#define EDGE_H
#ifndef IMPORT_EDGE_H
#define IMPORT_EDGE_H
#include <cassert>
#include "../Util/OSRMException.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
class NodeBasedEdge {
public:
public:
bool operator< (const NodeBasedEdge& e) const {
if (source() == e.source()) {
if (target() == e.target()) {
@@ -40,41 +50,74 @@ public:
return (source() < e.source());
}
/** Default constructor. target and weight are set to 0.*/
NodeBasedEdge() :
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false), _accessRestricted(false) { assert(false); } //shall not be used.
explicit NodeBasedEdge(
NodeID s,
NodeID t,
NodeID n,
EdgeWeight w,
bool f,
bool b,
short ty,
bool ra,
bool ig,
bool ar,
bool cf,
bool is_split
) : _source(s),
_target(t),
_name(n),
_weight(w),
_type(ty),
forward(f),
backward(b),
_roundabout(ra),
_ignoreInGrid(ig),
_accessRestricted(ar),
_contraFlow(cf),
is_split(is_split)
{
if(ty < 0) {
throw OSRMException("negative edge type");
}
}
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar) :
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar) { if(ty < 0) {ERR("Type: " << ty);}; }
NodeID target() const {return _target; }
NodeID source() const {return _source; }
NodeID name() const { return _name; }
EdgeWeight weight() const {return _weight; }
short type() const {
BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid");
return _type; }
bool isBackward() const { return backward; }
bool isForward() const { return forward; }
bool isLocatable() const { return _type != 14; }
bool isRoundabout() const { return _roundabout; }
bool ignoreInGrid() const { return _ignoreInGrid; }
bool isAccessRestricted() const { return _accessRestricted; }
bool isContraFlow() const { return _contraFlow; }
bool IsSplit() const { return is_split; }
NodeID target() const {return _target; }
NodeID source() const {return _source; }
NodeID name() const { return _name; }
EdgeWeight weight() const {return _weight; }
//TODO: names need to be fixed.
NodeID _source;
NodeID _target;
NodeID _name;
EdgeWeight _weight;
short _type;
bool forward:1;
bool backward:1;
bool _roundabout:1;
bool _ignoreInGrid:1;
bool _accessRestricted:1;
bool _contraFlow:1;
bool is_split:1;
short type() const { assert(_type >= 0); return _type; }
bool isBackward() const { return backward; }
bool isForward() const { return forward; }
bool isLocatable() const { return _type != 14; }
bool isRoundabout() const { return _roundabout; }
bool ignoreInGrid() const { return _ignoreInGrid; }
bool isAccessRestricted() const { return _accessRestricted; }
NodeID _source;
NodeID _target;
NodeID _name;
EdgeWeight _weight;
bool forward;
bool backward;
short _type;
bool _roundabout;
bool _ignoreInGrid;
bool _accessRestricted;
private:
NodeBasedEdge() { }
};
class EdgeBasedEdge {
public:
public:
bool operator< (const EdgeBasedEdge& e) const {
if (source() == e.source()) {
if (target() == e.target()) {
@@ -90,46 +133,57 @@ public:
}
template<class EdgeT>
EdgeBasedEdge(const EdgeT & myEdge ) :
_source(myEdge.source),
_target(myEdge.target),
_edgeID(myEdge.data.via),
// _nameID1(myEdge.data.nameID),
_weight(myEdge.data.distance),
_forward(myEdge.data.forward),
_backward(myEdge.data.backward)//,
// _turnInstruction(myEdge.data.turnInstruction)
{ }
explicit EdgeBasedEdge(const EdgeT & myEdge ) :
m_source(myEdge.source),
m_target(myEdge.target),
m_edgeID(myEdge.data.via),
m_weight(myEdge.data.distance),
m_forward(myEdge.data.forward),
m_backward(myEdge.data.backward)
{ }
/** Default constructor. target and weight are set to 0.*/
EdgeBasedEdge() :
_source(0), _target(0), _edgeID(0), _weight(0), _forward(false), _backward(false) { }
m_source(0),
m_target(0),
m_edgeID(0),
m_weight(0),
m_forward(false),
m_backward(false)
{ }
explicit EdgeBasedEdge(NodeID s, NodeID t, NodeID v, EdgeWeight w, bool f, bool b) :
_source(s), _target(t), _edgeID(v), _weight(w), _forward(f), _backward(b){}
explicit EdgeBasedEdge(
const NodeID s,
const NodeID t,
const NodeID v,
const EdgeWeight w,
const bool f,
const bool b
) :
m_source(s),
m_target(t),
m_edgeID(v),
m_weight(w),
m_forward(f),
m_backward(b)
{ }
NodeID target() const {return _target; }
NodeID source() const {return _source; }
EdgeWeight weight() const {return _weight; }
NodeID id() const { return _edgeID; }
bool isBackward() const { return _backward; }
bool isForward() const { return _forward; }
NodeID target() const { return m_target; }
NodeID source() const { return m_source; }
EdgeWeight weight() const { return m_weight; }
NodeID id() const { return m_edgeID; }
bool isBackward() const { return m_backward; }
bool isForward() const { return m_forward; }
NodeID _source;
NodeID _target;
NodeID _edgeID;
EdgeWeight _weight:30;
bool _forward:1;
bool _backward:1;
};
struct MinimalEdgeData {
public:
EdgeWeight distance;
bool forward;
bool backward;
private:
NodeID m_source;
NodeID m_target;
NodeID m_edgeID;
EdgeWeight m_weight:30;
bool m_forward:1;
bool m_backward:1;
};
typedef NodeBasedEdge ImportEdge;
#endif // EDGE_H
#endif /* IMPORT_EDGE_H */
+57 -26
View File
@@ -1,52 +1,83 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef IMPORTNODE_H_
#define IMPORTNODE_H_
#include "NodeCoords.h"
#include "QueryNode.h"
#include "../DataStructures/HashTable.h"
struct _Node : NodeInfo{
_Node(int _lat, int _lon, unsigned int _id, bool _bollard, bool _trafficLight) : NodeInfo(_lat, _lon, _id), bollard(_bollard), trafficLight(_trafficLight) {}
_Node() : bollard(false), trafficLight(false) {}
struct ExternalMemoryNode : NodeInfo {
ExternalMemoryNode(
int lat,
int lon,
unsigned int id,
bool bollard,
bool traffic_light
) :
NodeInfo(lat, lon, id),
bollard(bollard),
trafficLight(traffic_light)
{ }
static _Node min_value() {
return _Node(0,0,0, false, false);
ExternalMemoryNode()
:
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 {
return id;
}
bool bollard;
bool trafficLight;
};
struct ImportNode : public _Node {
struct ImportNode : public ExternalMemoryNode {
HashTable<std::string, std::string> keyVals;
inline void Clear() {
keyVals.EraseAll();
keyVals.clear();
lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false;
}
};
+30 -20
View File
@@ -1,26 +1,36 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef INPUTREADERFACTORY_H
#define INPUTREADERFACTORY_H
#include <boost/assert.hpp>
#include <bzlib.h>
#include <libxml/xmlreader.h>
@@ -43,21 +53,21 @@ int readFromBz2Stream( void* pointer, char* buffer, int len ) {
return read;
} else if(BZ_STREAM_END == context->error) {
BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused);
if(BZ_OK != context->error) { cerr << "Could not BZ2_bzReadGetUnused" << endl; exit(-1);};
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused");
unusedTmp = (char*)unusedTmpVoid;
for(int i=0;i<context->nUnused;i++) {
context->unused[i] = unusedTmp[i];
}
BZ2_bzReadClose(&context->error, context->bz2);
if(BZ_OK != context->error) { cerr << "Could not BZ2_bzReadClose" << endl; exit(-1);};
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose");
context->error = BZ_STREAM_END; // set to the stream end for next call to this function
if(0 == context->nUnused && feof(context->file)) {
return read;
} else {
context->bz2 = BZ2_bzReadOpen(&context->error, context->file, 0, 0, context->unused, context->nUnused);
if(NULL == context->bz2){ cerr << "Could not open file" << endl; exit(-1);};
BOOST_ASSERT_MSG(NULL != context->bz2, "Could not open file");
}
} else { cerr << "Could not read bz2 file" << endl; exit(-1); }
} else { BOOST_ASSERT_MSG(false, "Could not read bz2 file"); }
}
return read;
}
@@ -74,7 +84,7 @@ xmlTextReaderPtr inputReaderFactory( const char* name )
{
std::string inputName(name);
if(inputName.find(".osm.bz2")!=string::npos)
if(inputName.find(".osm.bz2")!=std::string::npos)
{
BZ2Context* context = new BZ2Context();
context->error = false;
+23 -16
View File
@@ -1,22 +1,29 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LRUCACHE_H
#define LRUCACHE_H
@@ -36,7 +43,7 @@ private:
std::list<CacheEntry> itemsInCache;
boost::unordered_map<KeyT, typename std::list<CacheEntry>::iterator > positionMap;
public:
LRUCache(unsigned c) : capacity(c) {}
explicit LRUCache(unsigned c) : capacity(c) {}
bool Holds(KeyT key) {
if(positionMap.find(key) != positionMap.end()) {
-594
View File
@@ -1,594 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef NNGRID_H_
#define NNGRID_H_
#include <algorithm>
#include <cassert>
#include <cfloat>
#include <cmath>
#include <fstream>
#include <limits>
#include <vector>
#ifndef ROUTED
#include <stxxl.h>
#endif
#ifdef _WIN32
#include <math.h>
#endif
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include "DeallocatingVector.h"
//#include "ExtractorStructs.h"
#include "GridEdge.h"
#include "Percent.h"
#include "PhantomNodes.h"
#include "Util.h"
#include "StaticGraph.h"
#include "../Algorithms/Bresenham.h"
namespace NNGrid{
static boost::thread_specific_ptr<std::ifstream> localStream;
template<bool WriteAccess = false>
class NNGrid {
public:
NNGrid() /*: cellCache(500), fileCache(500)*/ {
ramIndexTable.resize((1024*1024), ULONG_MAX);
}
NNGrid(const char* rif, const char* _i) {
if(WriteAccess) {
ERR("Not available in Write mode");
}
iif = std::string(_i);
ramIndexTable.resize((1024*1024), ULONG_MAX);
ramInFile.open(rif, std::ios::in | std::ios::binary);
if(!ramInFile) { ERR(rif << " not found"); }
}
~NNGrid() {
if(ramInFile.is_open()) ramInFile.close();
#ifndef ROUTED
if (WriteAccess) {
entries.clear();
}
#endif
if(localStream.get() && localStream->is_open()) {
localStream->close();
}
}
void OpenIndexFiles() {
assert(ramInFile.is_open());
ramInFile.read(static_cast<char*>(static_cast<void*>(&ramIndexTable[0]) ), sizeof(unsigned long)*1024*1024);
ramInFile.close();
}
#ifndef ROUTED
template<typename EdgeT>
inline void ConstructGrid(DeallocatingVector<EdgeT> & edgeList, char * ramIndexOut, char * fileIndexOut) {
//TODO: Implement this using STXXL-Streams
Percent p(edgeList.size());
BOOST_FOREACH(EdgeT & edge, edgeList) {
p.printIncrement();
if(edge.ignoreInGrid)
continue;
int slat = 100000*lat2y(edge.lat1/100000.);
int slon = edge.lon1;
int tlat = 100000*lat2y(edge.lat2/100000.);
int tlon = edge.lon2;
AddEdge( _GridEdge( edge.id, edge.nameID, edge.weight, _Coordinate(slat, slon), _Coordinate(tlat, tlon), edge.belongsToTinyComponent ) );
}
double timestamp = get_timestamp();
//create index file on disk, old one is over written
indexOutFile.open(fileIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
//sort entries
stxxl::sort(entries.begin(), entries.end(), CompareGridEdgeDataByRamIndex(), 1024*1024*1024);
INFO("finished sorting after " << (get_timestamp() - timestamp) << "s");
std::vector<GridEntry> entriesInFileWithRAMSameIndex;
unsigned indexInRamTable = entries.begin()->ramIndex;
unsigned long lastPositionInIndexFile = 0;
cout << "writing data ..." << flush;
p.reinit(entries.size());
boost::unordered_map< unsigned, unsigned > cellMap(1024);
BOOST_FOREACH(GridEntry & gridEntry, entries) {
p.printIncrement();
if(gridEntry.ramIndex != indexInRamTable) {
cellMap.clear();
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
lastPositionInIndexFile += numberOfBytesInCell;
entriesInFileWithRAMSameIndex.clear();
indexInRamTable = gridEntry.ramIndex;
}
entriesInFileWithRAMSameIndex.push_back(gridEntry);
}
cellMap.clear();
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
/*unsigned numberOfBytesInCell = */FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
entriesInFileWithRAMSameIndex.clear();
std::vector<GridEntry>().swap(entriesInFileWithRAMSameIndex);
assert(entriesInFileWithRAMSameIndex.size() == 0);
//close index file
indexOutFile.close();
//Serialize RAM Index
ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
//write 4 MB of index Table in RAM
ramFile.write((char *)&ramIndexTable[0], sizeof(unsigned long)*1024*1024 );
//close ram index file
ramFile.close();
}
#endif
inline bool CoordinatesAreEquivalent(const _Coordinate & a, const _Coordinate & b, const _Coordinate & c, const _Coordinate & d) const {
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
}
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel) {
bool ignoreTinyComponents = (zoomLevel <= 14);
// INFO("Coordinate: " << location << ", zoomLevel: " << zoomLevel << ", ignoring tinyComponentents: " << (ignoreTinyComponents ? "yes" : "no"));
// double time1 = get_timestamp();
bool foundNode = false;
const _Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
/** search for point on edge close to source */
const unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
const int lowerBoundForLoop = (fileIndex < 32768 ? 0 : -32768);
for(int j = lowerBoundForLoop; (j < (32768+1)) && (fileIndex != UINT_MAX); j+=32768) {
for(int i = -1; i < 2; ++i){
// unsigned oldSize = candidates.size();
GetContentsOfFileBucketEnumerated(fileIndex+i+j, candidates);
// INFO("Getting fileIndex=" << fileIndex+i+j << " with " << candidates.size() - oldSize << " candidates");
}
}
// INFO("looked up " << candidates.size());
_GridEdge smallestEdge;
_Coordinate tmp, edgeStartCoord, edgeEndCoord;
double dist = numeric_limits<double>::max();
double r, tmpDist;
BOOST_FOREACH(_GridEdge candidate, candidates) {
if(candidate.belongsToTinyComponent && ignoreTinyComponents)
continue;
r = 0.;
tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
// INFO("dist " << startCoord << "->[" << candidate.startCoord << "-" << candidate.targetCoord << "]=" << tmpDist );
// INFO("Looking at edge " << candidate.edgeBasedNode << " at distance " << tmpDist);
if(tmpDist < dist && !DoubleEpsilonCompare(dist, tmpDist)) {
// INFO("a) " << candidate.edgeBasedNode << ", dist: " << tmpDist << ", tinyCC: " << (candidate.belongsToTinyComponent ? "yes" : "no"));
dist = tmpDist;
resultNode.edgeBasedNode = candidate.edgeBasedNode;
resultNode.nodeBasedEdgeNameID = candidate.nameID;
resultNode.weight1 = candidate.weight;
resultNode.weight2 = INT_MAX;
resultNode.location.lat = tmp.lat;
resultNode.location.lon = tmp.lon;
edgeStartCoord = candidate.startCoord;
edgeEndCoord = candidate.targetCoord;
foundNode = true;
smallestEdge = candidate;
//} else if(tmpDist < dist) {
//INFO("a) ignored " << candidate.edgeBasedNode << " at distance " << std::fabs(dist - tmpDist));
} else if(DoubleEpsilonCompare(dist, tmpDist) && 1 == std::abs(static_cast<int>(candidate.edgeBasedNode)-static_cast<int>(resultNode.edgeBasedNode) ) && CoordinatesAreEquivalent(edgeStartCoord, candidate.startCoord, edgeEndCoord, candidate.targetCoord)) {
resultNode.edgeBasedNode = std::min(candidate.edgeBasedNode, resultNode.edgeBasedNode);
resultNode.weight2 = candidate.weight;
//INFO("b) " << candidate.edgeBasedNode << ", dist: " << tmpDist);
}
}
// INFO("startcoord: " << smallestEdge.startCoord << ", tgtcoord" << smallestEdge.targetCoord << "result: " << newEndpoint);
// INFO("length of old edge: " << ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
// INFO("Length of new edge: " << ApproximateDistance(smallestEdge.startCoord, newEndpoint));
// assert(!resultNode.isBidirected() || (resultNode.weight1 == resultNode.weight2));
// if(resultNode.weight1 != resultNode.weight2) {
// INFO("-> Weight1: " << resultNode.weight1 << ", weight2: " << resultNode.weight2);
// INFO("-> node: " << resultNode.edgeBasedNode << ", bidir: " << (resultNode.isBidirected() ? "yes" : "no"));
// }
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << "; newEndpoint: " << resultNode.location);
double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(resultNode.location.lat)/100000.)));
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
//Hack to fix rounding errors and wandering via nodes.
if(std::abs(location.lon - resultNode.location.lon) == 1)
resultNode.location.lon = location.lon;
if(std::abs(location.lat - resultNode.location.lat) == 1)
resultNode.location.lat = location.lat;
resultNode.weight1 *= ratio;
if(INT_MAX != resultNode.weight2) {
resultNode.weight2 -= resultNode.weight1;
}
resultNode.ratio = ratio;
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
// INFO("start: " << edgeStartCoord << ", end: " << edgeEndCoord);
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no") << "\n--");
// double time2 = get_timestamp();
// INFO("NN-Lookup in " << 1000*(time2-time1) << "ms");
return foundNode;
}
bool FindRoutingStarts(const _Coordinate& start, const _Coordinate& target, PhantomNodes & routingStarts, unsigned zoomLevel) {
routingStarts.Reset();
return (FindPhantomNodeForCoordinate( start, routingStarts.startPhantom, zoomLevel) &&
FindPhantomNodeForCoordinate( target, routingStarts.targetPhantom, zoomLevel) );
}
bool FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate, unsigned zoomLevel = 18) {
PhantomNode resultNode;
bool foundNode = FindPhantomNodeForCoordinate(inputCoordinate, resultNode, zoomLevel);
outputCoordinate = resultNode.location;
return foundNode;
}
void FindNearestPointOnEdge(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
_Coordinate startCoord(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
boost::unordered_map< unsigned, unsigned > cellMap;
for(int j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; ++i) {
GetContentsOfFileBucket(fileIndex+i+j, candidates, cellMap);
}
}
_Coordinate tmp;
double dist = (std::numeric_limits<double>::max)();
BOOST_FOREACH(_GridEdge candidate, candidates) {
double r = 0.;
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
if(tmpDist < dist) {
dist = tmpDist;
outputCoordinate.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
outputCoordinate.lon = tmp.lon;
}
}
}
private:
inline unsigned GetCellIndexFromRAMAndFileIndex(const unsigned ramIndex, const unsigned fileIndex) const {
unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768;
unsigned columnBase = ramIndex%1024;
columnBase=columnBase*32;
for (int i = 0;i < 32;++i) {
for (int j = 0;j < 32;++j) {
const unsigned localFileIndex = lineBase + i * 32768 + columnBase + j;
if(localFileIndex == fileIndex) {
unsigned cellIndex = i * 32 + j;
return cellIndex;
}
}
}
return UINT_MAX;
}
inline void BuildCellIndexToFileIndexMap(const unsigned ramIndex, boost::unordered_map<unsigned, unsigned >& cellMap){
unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768;
unsigned columnBase = ramIndex%1024;
columnBase=columnBase*32;
std::vector<std::pair<unsigned, unsigned> >insertionVector(1024);
for (int i = 0;i < 32;++i) {
for (int j = 0;j < 32;++j) {
unsigned fileIndex = lineBase + i * 32768 + columnBase + j;
unsigned cellIndex = i * 32 + j;
insertionVector[i * 32 + j] = std::make_pair(fileIndex, cellIndex);
}
}
cellMap.insert(insertionVector.begin(), insertionVector.end());
}
inline bool DoubleEpsilonCompare(const double d1, const double d2) {
return (std::fabs(d1 - d2) < FLT_EPSILON);
}
inline unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, const unsigned long fileOffset, boost::unordered_map< unsigned, unsigned > & cellMap ) {
std::vector<char> tmpBuffer(32*32*4096,0);
unsigned long indexIntoTmpBuffer = 0;
unsigned numberOfWrittenBytes = 0;
assert(indexOutFile.is_open());
std::vector<unsigned long> cellIndex(32*32,ULONG_MAX);
for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; ++i) {
assert(entriesWithSameRAMIndex[i].ramIndex== entriesWithSameRAMIndex[i+1].ramIndex);
}
//sort & unique
std::sort(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end(), CompareGridEdgeDataByFileIndex());
// entriesWithSameRAMIndex.erase(std::unique(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end()), entriesWithSameRAMIndex.end());
//traverse each file bucket and write its contents to disk
std::vector<GridEntry> entriesWithSameFileIndex;
unsigned fileIndex = entriesWithSameRAMIndex.begin()->fileIndex;
BOOST_FOREACH(GridEntry & gridEntry, entriesWithSameRAMIndex) {
assert(cellMap.find(gridEntry.fileIndex) != cellMap.end() ); //asserting that file index belongs to cell index
if(gridEntry.fileIndex != fileIndex) {
// start in cellIndex vermerken
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap.find(localFileIndex)->second;
assert(cellMap.find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap.end());
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
fileIndex = gridEntry.fileIndex;
}
entriesWithSameFileIndex.push_back(gridEntry);
}
assert(cellMap.find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap.end());
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap.find(localFileIndex)->second;
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
assert(entriesWithSameFileIndex.size() == 0);
indexOutFile.write(static_cast<char*>(static_cast<void*>(&cellIndex[0])),32*32*sizeof(unsigned long));
numberOfWrittenBytes += 32*32*sizeof(unsigned long);
//write contents of tmpbuffer to disk
indexOutFile.write(&tmpBuffer[0], indexIntoTmpBuffer*sizeof(char));
numberOfWrittenBytes += indexIntoTmpBuffer*sizeof(char);
return numberOfWrittenBytes;
}
inline unsigned FlushEntriesWithSameFileIndexToBuffer( std::vector<GridEntry> &vectorWithSameFileIndex, std::vector<char> & tmpBuffer, const unsigned long index) const {
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
const unsigned lengthOfBucket = vectorWithSameFileIndex.size();
tmpBuffer.resize(tmpBuffer.size()+(sizeof(_GridEdge)*lengthOfBucket) + sizeof(unsigned) );
unsigned counter = 0;
for(unsigned i = 0; i < vectorWithSameFileIndex.size()-1; ++i) {
assert( vectorWithSameFileIndex[i].fileIndex == vectorWithSameFileIndex[i+1].fileIndex );
assert( vectorWithSameFileIndex[i].ramIndex == vectorWithSameFileIndex[i+1].ramIndex );
}
//write length of bucket
memcpy((char*)&(tmpBuffer[index+counter]), (char*)&lengthOfBucket, sizeof(lengthOfBucket));
counter += sizeof(lengthOfBucket);
BOOST_FOREACH(const GridEntry & entry, vectorWithSameFileIndex) {
char * data = (char*)&(entry.edge);
memcpy(static_cast<char*>(static_cast<void*>(&(tmpBuffer[index+counter]) )), data, sizeof(entry.edge));
counter += sizeof(entry.edge);
}
//Freeing data
vectorWithSameFileIndex.clear();
return counter;
}
inline void GetContentsOfFileBucketEnumerated(const unsigned fileIndex, std::vector<_GridEdge>& result) const {
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
unsigned long startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == ULONG_MAX) {
return;
}
unsigned enumeratedIndex = GetCellIndexFromRAMAndFileIndex(ramIndex, fileIndex);
if(!localStream.get() || !localStream->is_open()) {
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
}
if(!localStream->good()) {
localStream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream");
}
//only read the single necessary cell index
localStream->seekg(startIndexInFile+(enumeratedIndex*sizeof(unsigned long)));
unsigned long fetchedIndex = 0;
localStream->read(static_cast<char*>( static_cast<void*>(&fetchedIndex)), sizeof(unsigned long));
if(fetchedIndex == ULONG_MAX) {
return;
}
const unsigned long position = fetchedIndex + 32*32*sizeof(unsigned long) ;
unsigned lengthOfBucket;
unsigned currentSizeOfResult = result.size();
localStream->seekg(position);
localStream->read(static_cast<char*>( static_cast<void*>(&(lengthOfBucket))), sizeof(unsigned));
result.resize(currentSizeOfResult+lengthOfBucket);
localStream->read(static_cast<char*>( static_cast<void*>(&result[currentSizeOfResult])), lengthOfBucket*sizeof(_GridEdge));
}
inline void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_GridEdge>& result, boost::unordered_map< unsigned, unsigned> & cellMap) {
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
unsigned long startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == ULONG_MAX) {
return;
}
unsigned long cellIndex[32*32];
cellMap.clear();
BuildCellIndexToFileIndexMap(ramIndex, cellMap);
if(!localStream.get() || !localStream->is_open()) {
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
}
if(!localStream->good()) {
localStream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream");
}
localStream->seekg(startIndexInFile);
localStream->read(static_cast<char*>(static_cast<void*>( cellIndex)), 32*32*sizeof(unsigned long));
assert(cellMap.find(fileIndex) != cellMap.end());
if(cellIndex[cellMap[fileIndex]] == ULONG_MAX) {
return;
}
const unsigned long position = cellIndex[cellMap[fileIndex]] + 32*32*sizeof(unsigned long) ;
unsigned lengthOfBucket;
unsigned currentSizeOfResult = result.size();
localStream->seekg(position);
localStream->read(static_cast<char*>(static_cast<void*>(&(lengthOfBucket))), sizeof(unsigned));
result.resize(currentSizeOfResult+lengthOfBucket);
localStream->read(static_cast<char*>(static_cast<void*>(&result[currentSizeOfResult])), lengthOfBucket*sizeof(_GridEdge));
}
#ifndef ROUTED
inline void AddEdge(const _GridEdge & edge) {
std::vector<BresenhamPixel> indexList;
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, indexList);
for(unsigned i = 0; i < indexList.size(); ++i) {
entries.push_back(GridEntry(edge, indexList[i].first, indexList[i].second));
}
}
#endif
inline double ComputeDistance(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target, _Coordinate& nearest, double *r) {
// INFO("comparing point " << inputPoint << " to edge [" << source << "-" << target << "]");
const double x = static_cast<double>(inputPoint.lat);
const double y = static_cast<double>(inputPoint.lon);
const double a = static_cast<double>(source.lat);
const double b = static_cast<double>(source.lon);
const double c = static_cast<double>(target.lat);
const double d = static_cast<double>(target.lon);
double p,q,mX,nY;
// INFO("x=" << x << ", y=" << y << ", a=" << a << ", b=" << b << ", c=" << c << ", d=" << d);
if(fabs(a-c) > FLT_EPSILON){
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m);
q = b + m*(p - a);
}
else{
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
mX = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we neednot calculate the values of m an n as we are just interested in the ratio
// INFO("p=" << p << ", q=" << q << ", nY=" << nY << ", mX=" << mX);
if(std::isnan(mX)) {
*r = (target == inputPoint) ? 1. : 0.;
} else {
*r = mX;
}
// INFO("r=" << *r);
if(*r<=0.){
nearest.lat = source.lat;
nearest.lon = source.lon;
// INFO("a returning distance " << ((b - y)*(b - y) + (a - x)*(a - x)))
return ((b - y)*(b - y) + (a - x)*(a - x));
}
else if(*r >= 1.){
nearest.lat = target.lat;
nearest.lon = target.lon;
// INFO("b returning distance " << ((d - y)*(d - y) + (c - x)*(c - x)))
return ((d - y)*(d - y) + (c - x)*(c - x));
}
// point lies in between
nearest.lat = p;
nearest.lon = q;
// INFO("c returning distance " << (p-x)*(p-x) + (q-y)*(q-y))
return (p-x)*(p-x) + (q-y)*(q-y);
}
inline void GetListOfIndexesForEdgeAndGridSize(const _Coordinate& start, const _Coordinate& target, std::vector<BresenhamPixel> &indexList) const {
double lat1 = start.lat/100000.;
double lon1 = start.lon/100000.;
double x1 = ( lon1 + 180.0 ) / 360.0;
double y1 = ( lat1 + 180.0 ) / 360.0;
double lat2 = target.lat/100000.;
double lon2 = target.lon/100000.;
double x2 = ( lon2 + 180.0 ) / 360.0;
double y2 = ( lat2 + 180.0 ) / 360.0;
Bresenham(x1*32768, y1*32768, x2*32768, y2*32768, indexList);
BOOST_FOREACH(BresenhamPixel & pixel, indexList) {
int fileIndex = (pixel.second-1)*32768 + pixel.first;
int ramIndex = GetRAMIndexFromFileIndex(fileIndex);
pixel.first = fileIndex;
pixel.second = ramIndex;
}
}
inline unsigned GetFileIndexForLatLon(const int lt, const int ln) {
double lat = lt/100000.;
double lon = ln/100000.;
double x = ( lon + 180.0 ) / 360.0;
double y = ( lat + 180.0 ) / 360.0;
if( x>1.0 || x < 0.)
return UINT_MAX;
if( y>1.0 || y < 0.)
return UINT_MAX;
unsigned line = (32768 * (32768-1))*y;
line = line - (line % 32768);
assert(line % 32768 == 0);
unsigned column = 32768.*x;
unsigned fileIndex = line+column;
return fileIndex;
}
inline unsigned GetRAMIndexFromFileIndex(const int fileIndex) const {
unsigned fileLine = fileIndex / 32768;
fileLine = fileLine / 32;
fileLine = fileLine * 1024;
unsigned fileColumn = (fileIndex % 32768);
fileColumn = fileColumn / 32;
unsigned ramIndex = fileLine + fileColumn;
assert(ramIndex < 1024*1024);
return ramIndex;
}
const static unsigned long END_OF_BUCKET_DELIMITER = UINT_MAX;
std::ofstream indexOutFile;
std::ifstream ramInFile;
#ifndef ROUTED
stxxl::vector<GridEntry> entries;
#endif
std::vector<unsigned long> ramIndexTable; //8 MB for first level index in RAM
std::string iif;
// LRUCache<int,std::vector<unsigned> > cellCache;
// LRUCache<int,std::vector<_Edge> > fileCache;
};
}
typedef NNGrid::NNGrid<false> ReadOnlyGrid;
typedef NNGrid::NNGrid<true > WritableGrid;
#endif /* NNGRID_H_ */
-69
View File
@@ -1,69 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef _NODE_COORDS_H
#define _NODE_COORDS_H
#include <cassert>
#include <cstddef>
#include <climits>
#include <limits>
#include "../typedefs.h"
template<typename NodeT>
struct NodeCoords {
typedef unsigned key_type; //type of NodeID
typedef int value_type; //type of lat,lons
NodeCoords(int _lat, int _lon, NodeT _id) : lat(_lat), lon(_lon), id(_id) {}
NodeCoords() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {}
int lat;
int lon;
NodeT id;
static NodeCoords<NodeT> min_value() {
return NodeCoords<NodeT>(-90*100000,-180*100000,std::numeric_limits<NodeT>::min());
}
static NodeCoords<NodeT> max_value() {
return NodeCoords<NodeT>(90*100000, 180*100000, std::numeric_limits<NodeT>::max());
}
value_type operator[](std::size_t n) const {
switch(n) {
case 1:
return lat;
break;
case 0:
return lon;
break;
default:
assert(false);
return UINT_MAX;
break;
}
assert(false);
return UINT_MAX;
}
};
typedef NodeCoords<NodeID> NodeInfo;
#endif //_NODE_COORDS_H
-124
View File
@@ -1,124 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef NODEINFORMATIONHELPDESK_H_
#define NODEINFORMATIONHELPDESK_H_
#include <fstream>
#include <iostream>
#include <vector>
#include "../typedefs.h"
#include "../DataStructures/QueryEdge.h"
#include "NNGrid.h"
#include "PhantomNodes.h"
#include "NodeCoords.h"
class NodeInformationHelpDesk{
public:
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, const unsigned _numberOfNodes, const unsigned crc) : numberOfNodes(_numberOfNodes), checkSum(crc) {
readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
assert(0 == coordinateVector.size());
}
//Todo: Shared memory mechanism
// NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, const unsigned crc) : checkSum(crc) {
// readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
// }
~NodeInformationHelpDesk() {
delete readOnlyGrid;
}
void initNNGrid(std::ifstream& nodesInstream, std::ifstream& edgesInStream) {
DEBUG("Loading node data");
NodeInfo b;
while(!nodesInstream.eof()) {
nodesInstream.read((char *)&b, sizeof(NodeInfo));
coordinateVector.push_back(_Coordinate(b.lat, b.lon));
}
std::vector<_Coordinate>(coordinateVector).swap(coordinateVector);
nodesInstream.close();
DEBUG("Loading edge data");
unsigned numberOfOrigEdges(0);
edgesInStream.read((char*)&numberOfOrigEdges, sizeof(unsigned));
origEdgeData.resize(numberOfOrigEdges);
edgesInStream.read((char*)&(origEdgeData[0]), numberOfOrigEdges*sizeof(OriginalEdgeData));
edgesInStream.close();
DEBUG("Loaded " << numberOfOrigEdges << " orig edges");
DEBUG("Opening NN indices");
readOnlyGrid->OpenIndexFiles();
}
void initNNGrid() {
readOnlyGrid->OpenIndexFiles();
}
inline int getLatitudeOfNode(const unsigned id) const {
const NodeID node = origEdgeData.at(id).viaNode;
return coordinateVector.at(node).lat;
}
inline int getLongitudeOfNode(const unsigned id) const {
const NodeID node = origEdgeData.at(id).viaNode;
return coordinateVector.at(node).lon;
}
inline unsigned getNameIndexFromEdgeID(const unsigned id) const {
return origEdgeData.at(id).nameID;
}
inline TurnInstruction getTurnInstructionFromEdgeID(const unsigned id) const {
return origEdgeData.at(id).turnInstruction;
}
inline NodeID getNumberOfNodes() const { return numberOfNodes; }
inline NodeID getNumberOfNodes2() const { return coordinateVector.size(); }
inline bool FindNearestNodeCoordForLatLon(const _Coordinate& coord, _Coordinate& result) const {
return readOnlyGrid->FindNearestCoordinateOnEdgeInNodeBasedGraph(coord, result);
}
inline bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel) const {
return readOnlyGrid->FindPhantomNodeForCoordinate(location, resultNode, zoomLevel);
}
inline void FindRoutingStarts(const _Coordinate &start, const _Coordinate &target, PhantomNodes & phantomNodes, const unsigned zoomLevel) const {
readOnlyGrid->FindRoutingStarts(start, target, phantomNodes, zoomLevel);
}
inline void FindNearestPointOnEdge(const _Coordinate & input, _Coordinate& output){
readOnlyGrid->FindNearestPointOnEdge(input, output);
}
inline unsigned GetCheckSum() const {
return checkSum;
}
private:
std::vector<_Coordinate> coordinateVector;
std::vector<OriginalEdgeData> origEdgeData;
ReadOnlyGrid * readOnlyGrid;
const unsigned numberOfNodes;
const unsigned checkSum;
};
#endif /*NODEINFORMATIONHELPDESK_H_*/
+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
+26 -21
View File
@@ -1,38 +1,44 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PERCENT_H
#define PERCENT_H
#include "../Util/OpenMPWrapper.h"
#include <iostream>
class Percent
{
class Percent {
public:
/**
* Constructor.
* @param maxValue the value that corresponds to 100%
* @param step the progress is shown in steps of 'step' percent
*/
Percent(unsigned maxValue, unsigned step = 5) {
explicit Percent(unsigned maxValue, unsigned step = 5) {
reinit(maxValue, step);
}
@@ -56,8 +62,7 @@ public:
std::cout << " 100%" << std::endl;
}
void printIncrement()
{
void printIncrement() {
#pragma omp atomic
++_current_value;
printStatus(_current_value);
+141 -61
View File
@@ -1,94 +1,174 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PHANTOMNODES_H_
#define PHANTOMNODES_H_
#include "Coordinate.h"
#include <osrm/Coordinate.h>
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
struct PhantomNode {
PhantomNode() : edgeBasedNode(UINT_MAX), nodeBasedEdgeNameID(UINT_MAX), weight1(INT_MAX), weight2(INT_MAX), ratio(0.) {}
NodeID edgeBasedNode;
unsigned nodeBasedEdgeNameID;
int weight1;
int weight2;
double ratio;
_Coordinate location;
void Reset() {
edgeBasedNode = UINT_MAX;
nodeBasedEdgeNameID = UINT_MAX;
weight1 = INT_MAX;
weight2 = INT_MAX;
ratio = 0.;
struct PhantomNode
{
PhantomNode() :
forward_node_id(SPECIAL_NODEID),
reverse_node_id(SPECIAL_NODEID),
name_id(std::numeric_limits<unsigned>::max()),
forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position(0)
{ }
NodeID forward_node_id;
NodeID reverse_node_id;
unsigned name_id;
int forward_weight;
int reverse_weight;
int forward_offset;
int reverse_offset;
unsigned packed_geometry_id;
FixedPointCoordinate location;
unsigned short fwd_segment_position;
int GetForwardWeightPlusOffset() const
{
if (SPECIAL_NODEID == forward_node_id)
{
return 0;
}
const int result = (forward_offset + forward_weight);
return result;
}
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 weight2 != INT_MAX;
}
bool isValid(const unsigned numberOfNodes) const {
return location.isValid() && (edgeBasedNode < numberOfNodes) && (weight1 != INT_MAX) && (ratio >= 0.) && (ratio <= 1.) && (nodeBasedEdgeNameID != UINT_MAX);
bool isBidirected() const
{
return (forward_node_id != SPECIAL_NODEID) &&
(reverse_node_id != SPECIAL_NODEID);
}
bool operator==(const PhantomNode & other) const {
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;
}
};
struct PhantomNodes {
PhantomNode startPhantom;
PhantomNode targetPhantom;
void Reset() {
startPhantom.Reset();
targetPhantom.Reset();
struct PhantomNodes
{
PhantomNode source_phantom;
PhantomNode target_phantom;
void Reset()
{
source_phantom.Reset();
target_phantom.Reset();
}
bool PhantomsAreOnSameNodeBasedEdge() const {
return (startPhantom.edgeBasedNode == targetPhantom.edgeBasedNode);
bool PhantomsAreOnSameNodeBasedEdge() const
{
return (source_phantom.forward_node_id == target_phantom.forward_node_id);
}
bool AtLeastOnePhantomNodeIsUINTMAX() const {
return !(startPhantom.edgeBasedNode == UINT_MAX || targetPhantom.edgeBasedNode == UINT_MAX);
bool AtLeastOnePhantomNodeIsInvalid() const
{
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 {
return startPhantom == targetPhantom;
bool PhantomNodesHaveEqualLocation() const
{
return source_phantom == target_phantom;
}
};
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn){
out << "Node1: " << pn.startPhantom.edgeBasedNode << std::endl;
out << "Node2: " << pn.targetPhantom.edgeBasedNode << std::endl;
out << "startCoord: " << pn.startPhantom.location << std::endl;
out << "targetCoord: " << pn.targetPhantom.location << std::endl;
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn)
{
out << "source_coord: " << pn.source_phantom.location << "\n";
out << "target_coord: " << pn.target_phantom.location << std::endl;
return out;
}
inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn){
out << "node: " << pn.edgeBasedNode << ", name: " << pn.nodeBasedEdgeNameID << ", w1: " << pn.weight1 << ", w2: " << pn.weight2 << ", ratio: " << pn.ratio << ", loc: " << pn.location;
inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn)
{
out << "node1: " << pn.forward_node_id << ", " <<
"node2: " << pn.reverse_node_id << ", " <<
"name: " << pn.name_id << ", " <<
"fwd-w: " << pn.forward_weight << ", " <<
"rev-w: " << pn.reverse_weight << ", " <<
"fwd-o: " << pn.forward_offset << ", " <<
"rev-o: " << pn.reverse_offset << ", " <<
"geom: " << pn.packed_geometry_id << ", " <<
"pos: " << pn.fwd_segment_position << ", " <<
"loc: " << pn.location;
return out;
}
struct NodesOfEdge {
NodeID edgeBasedNode;
double ratio;
_Coordinate projectedPoint;
};
#endif /* PHANTOMNODES_H_ */
+35 -47
View File
@@ -1,74 +1,62 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef QUERYEDGE_H_
#define QUERYEDGE_H_
#include "TurnInstructions.h"
#include "../typedefs.h"
#include <climits>
struct OriginalEdgeData{
explicit OriginalEdgeData(NodeID v, unsigned n, TurnInstruction t) : viaNode(v), nameID(n), turnInstruction(t) {}
OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {}
NodeID viaNode;
unsigned nameID;
TurnInstruction turnInstruction;
};
struct QueryEdge {
NodeID source;
NodeID target;
struct EdgeData {
NodeID id:31;
int distance:30;
bool shortcut:1;
bool forward:1;
bool backward:1;
bool shortcut:1;
int distance:30;
bool forward:1;
bool backward:1;
} data;
bool operator<( const QueryEdge& right ) const {
if ( source != right.source )
if ( source != right.source ) {
return source < right.source;
}
return target < right.target;
}
//sorts by source and other attributes
static bool CompareBySource( const QueryEdge& left, const QueryEdge& right ) {
if ( left.source != right.source )
return left.source < right.source;
int l = ( left.data.forward ? -1 : 0 ) + ( left.data.backward ? -1 : 0 );
int r = ( right.data.forward ? -1 : 0 ) + ( right.data.backward ? -1 : 0 );
if ( l != r )
return l < r;
if ( left.target != right.target )
return left.target < right.target;
return left.data.distance < right.data.distance;
}
bool operator== ( const QueryEdge& right ) const {
return ( source == right.source && target == right.target && data.distance == right.data.distance &&
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward
&& data.id == right.data.id
return (
source == right.source &&
target == right.target &&
data.distance == right.data.distance &&
data.shortcut == right.data.shortcut &&
data.forward == right.data.forward &&
data.backward == right.data.backward &&
data.id == right.data.id
);
}
};
+87
View File
@@ -0,0 +1,87 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef QUERY_NODE_H
#define QUERY_NODE_H
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <limits>
struct NodeInfo {
typedef NodeID key_type; //type of NodeID
typedef int value_type; //type of lat,lons
NodeInfo(int lat, int lon, NodeID id) : lat(lat), lon(lon), id(id) { }
NodeInfo()
:
lat(std::numeric_limits<int>::max()),
lon(std::numeric_limits<int>::max()),
id(std::numeric_limits<unsigned>::max())
{ }
int lat;
int lon;
NodeID id;
static NodeInfo min_value() {
return NodeInfo(
-90*COORDINATE_PRECISION,
-180*COORDINATE_PRECISION,
std::numeric_limits<NodeID>::min()
);
}
static NodeInfo max_value() {
return NodeInfo(
90*COORDINATE_PRECISION,
180*COORDINATE_PRECISION,
std::numeric_limits<NodeID>::max()
);
}
value_type operator[](const std::size_t n) const {
switch(n) {
case 1:
return lat;
// break;
case 0:
return lon;
// break;
default:
break;
}
BOOST_ASSERT_MSG(false, "should not happen");
return std::numeric_limits<unsigned>::max();
}
};
#endif //QUERY_NODE_H
+89
View File
@@ -0,0 +1,89 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RAWROUTEDATA_H_
#define RAWROUTEDATA_H_
#include "../DataStructures/PhantomNodes.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <limits>
#include <vector>
struct PathData {
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;
unsigned name_id;
unsigned durationOfSegment;
short turnInstruction;
};
struct RawRouteData {
std::vector< std::vector<PathData> > unpacked_path_segments;
std::vector< PathData > unpacked_alternative;
std::vector< PhantomNodes > segmentEndCoordinates;
std::vector< FixedPointCoordinate > rawViaNodeCoordinates;
unsigned checkSum;
int lengthOfShortestPath;
int lengthOfAlternativePath;
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_ */
+107 -55
View File
@@ -1,97 +1,149 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RESTRICTION_H_
#define RESTRICTION_H_
#include <climits>
#include "../typedefs.h"
struct _Restriction {
#include <limits>
struct TurnRestriction {
NodeID viaNode;
NodeID fromNode;
NodeID toNode;
struct Bits { //mostly unused
Bits() : isOnly(false), unused1(false), unused2(false), unused3(false), unused4(false), unused5(false), unused6(false), unused7(false) {}
char isOnly:1;
char unused1:1;
char unused2:1;
char unused3:1;
char unused4:1;
char unused5:1;
char unused6:1;
char unused7:1;
Bits()
:
isOnly(false),
unused1(false),
unused2(false),
unused3(false),
unused4(false),
unused5(false),
unused6(false),
unused7(false)
{ }
bool isOnly:1;
bool unused1:1;
bool unused2:1;
bool unused3:1;
bool unused4:1;
bool unused5:1;
bool unused6:1;
bool unused7:1;
} flags;
_Restriction(NodeID vn) : viaNode(vn), fromNode(UINT_MAX), toNode(UINT_MAX) { }
_Restriction(bool isOnly = false) : viaNode(UINT_MAX), fromNode(UINT_MAX), toNode(UINT_MAX) {
explicit TurnRestriction(NodeID viaNode) :
viaNode(viaNode),
fromNode(std::numeric_limits<unsigned>::max()),
toNode(std::numeric_limits<unsigned>::max()) {
}
explicit TurnRestriction(const bool isOnly = false) :
viaNode(UINT_MAX),
fromNode(UINT_MAX),
toNode(UINT_MAX) {
flags.isOnly = isOnly;
}
};
inline bool CmpRestrictionByFrom ( _Restriction a, _Restriction b) { return (a.fromNode < b.fromNode); }
struct _RawRestrictionContainer {
_Restriction restriction;
struct InputRestrictionContainer {
EdgeID fromWay;
EdgeID toWay;
unsigned viaNode;
TurnRestriction restriction;
_RawRestrictionContainer(EdgeID f, EdgeID t, NodeID vn, unsigned vw) : fromWay(f), toWay(t), viaNode(vw) { restriction.viaNode = vn;}
_RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaNode(UINT_MAX) { restriction.flags.isOnly = isOnly;}
static _RawRestrictionContainer min_value() {
return _RawRestrictionContainer(0, 0, 0, 0);
InputRestrictionContainer(
EdgeID fromWay,
EdgeID toWay,
NodeID vn,
unsigned vw
) :
fromWay(fromWay),
toWay(toWay),
viaNode(vw)
{
restriction.viaNode = vn;
}
static _RawRestrictionContainer max_value() {
return _RawRestrictionContainer(UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX);
explicit InputRestrictionContainer(
bool isOnly = false
) :
fromWay(std::numeric_limits<unsigned>::max()),
toWay(std::numeric_limits<unsigned>::max()),
viaNode(std::numeric_limits<unsigned>::max())
{
restriction.flags.isOnly = isOnly;
}
static InputRestrictionContainer min_value() {
return InputRestrictionContainer(0, 0, 0, 0);
}
static InputRestrictionContainer max_value() {
return InputRestrictionContainer(
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max()
);
}
};
struct CmpRestrictionContainerByFrom: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
struct CmpRestrictionContainerByFrom {
typedef InputRestrictionContainer value_type;
inline bool operator()(
const InputRestrictionContainer & a,
const InputRestrictionContainer & b
) const {
return a.fromWay < b.fromWay;
}
value_type max_value() {
return _RawRestrictionContainer::max_value();
inline value_type max_value() const {
return InputRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_value();
inline value_type min_value() const {
return InputRestrictionContainer::min_value();
}
};
struct CmpRestrictionContainerByTo: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
struct CmpRestrictionContainerByTo {
typedef InputRestrictionContainer value_type;
inline bool operator()(
const InputRestrictionContainer & a,
const InputRestrictionContainer & b
) const {
return a.toWay < b.toWay;
}
value_type max_value() {
return _RawRestrictionContainer::max_value();
value_type max_value() const {
return InputRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_value();
value_type min_value() const {
return InputRestrictionContainer::min_value();
}
};
#endif /* RESTRICTION_H_ */
+42 -145
View File
@@ -1,171 +1,68 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
#ifndef SEARCHENGINE_H_
#define SEARCHENGINE_H_
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <climits>
#include <deque>
#include "SimpleStack.h"
*/
#include <boost/thread.hpp>
#ifndef SEARCHENGINE_H
#define SEARCHENGINE_H
#include "BinaryHeap.h"
#include "NodeInformationHelpDesk.h"
#include "SearchEngineData.h"
#include "PhantomNodes.h"
#include "QueryEdge.h"
#include "../RoutingAlgorithms/AlternativePathRouting.h"
#include "../RoutingAlgorithms/BasicRoutingInterface.h"
#include "../RoutingAlgorithms/ShortestPathRouting.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
struct _HeapData {
NodeID parent;
_HeapData( NodeID p ) : parent(p) { }
};
#include <osrm/Coordinate.h>
typedef boost::thread_specific_ptr<BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> > > SearchEngineHeapPtr;
#include <boost/assert.hpp>
template<class EdgeData, class GraphT>
struct SearchEngineData {
typedef SearchEngineHeapPtr HeapPtr;
typedef GraphT Graph;
SearchEngineData(GraphT * g, NodeInformationHelpDesk * nh, std::vector<string> & n) :graph(g), nodeHelpDesk(nh), names(n) {}
const GraphT * graph;
NodeInformationHelpDesk * nodeHelpDesk;
std::vector<string> & names;
static HeapPtr forwardHeap;
static HeapPtr backwardHeap;
static HeapPtr forwardHeap2;
static HeapPtr backwardHeap2;
static HeapPtr forwardHeap3;
static HeapPtr backwardHeap3;
#include <climits>
#include <string>
#include <vector>
inline void InitializeOrClearFirstThreadLocalStorage() {
if(!forwardHeap.get()) {
forwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
forwardHeap->Clear();
if(!backwardHeap.get()) {
backwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
backwardHeap->Clear();
}
inline void InitializeOrClearSecondThreadLocalStorage() {
if(!forwardHeap2.get()) {
forwardHeap2.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
forwardHeap2->Clear();
if(!backwardHeap2.get()) {
backwardHeap2.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
backwardHeap2->Clear();
}
inline void InitializeOrClearThirdThreadLocalStorage() {
if(!forwardHeap3.get()) {
forwardHeap3.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
forwardHeap3->Clear();
if(!backwardHeap3.get()) {
backwardHeap3.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
backwardHeap3->Clear();
}
};
template<class EdgeData, class GraphT>
template<class DataFacadeT>
class SearchEngine {
private:
typedef SearchEngineData<EdgeData, GraphT> SearchEngineDataT;
SearchEngineDataT _queryData;
inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;}
DataFacadeT * facade;
SearchEngineData engine_working_data;
public:
ShortestPathRouting<SearchEngineDataT> shortestPath;
AlternativeRouting<SearchEngineDataT> alternativePaths;
ShortestPathRouting<DataFacadeT> shortest_path;
AlternativeRouting <DataFacadeT> alternative_path;
SearchEngine(GraphT * g, NodeInformationHelpDesk * nh, std::vector<string> & n) :
_queryData(g, nh, n),
shortestPath(_queryData),
alternativePaths(_queryData)
{}
~SearchEngine() {}
explicit SearchEngine( DataFacadeT * facade )
:
facade (facade),
shortest_path (facade, engine_working_data),
alternative_path (facade, engine_working_data)
{}
inline void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const {
result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id);
result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id);
}
inline void FindRoutingStarts(const _Coordinate & start, const _Coordinate & target, PhantomNodes & routingStarts) const {
_queryData.nodeHelpDesk->FindRoutingStarts(start, target, routingStarts);
}
inline void FindPhantomNodeForCoordinate(const _Coordinate & location, PhantomNode & result, unsigned zoomLevel) const {
_queryData.nodeHelpDesk->FindPhantomNodeForCoordinate(location, result, zoomLevel);
}
inline NodeID GetNameIDForOriginDestinationNodeID(const NodeID s, const NodeID t) const {
if(s == t)
return 0;
EdgeID e = _queryData.graph->FindEdge(s, t);
if(e == UINT_MAX)
e = _queryData.graph->FindEdge( t, s );
if(UINT_MAX == e) {
return 0;
}
assert(e != UINT_MAX);
const EdgeData ed = _queryData.graph->GetEdgeData(e);
return ed.via;
}
inline std::string GetEscapedNameForNameID(const unsigned nameID) const {
return ((nameID >= _queryData.names.size() || nameID == 0) ? std::string("") : HTMLEntitize(_queryData.names.at(nameID)));
}
inline std::string GetEscapedNameForEdgeBasedEdgeID(const unsigned edgeID) const {
const unsigned nameID = _queryData.graph->GetEdgeData(edgeID).nameID1;
return GetEscapedNameForNameID(nameID);
}
~SearchEngine() {}
};
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::forwardHeap;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::backwardHeap;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::forwardHeap2;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::backwardHeap2;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::forwardHeap3;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::backwardHeap3;
#endif /* SEARCHENGINE_H_ */
#endif // SEARCHENGINE_H
+91
View File
@@ -0,0 +1,91 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "SearchEngineData.h"
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap.get())
{
forwardHeap->Clear();
}
else
{
forwardHeap.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap.get())
{
backwardHeap->Clear();
}
else
{
backwardHeap.reset(new QueryHeap(number_of_nodes));
}
}
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap2.get())
{
forwardHeap2->Clear();
}
else
{
forwardHeap2.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap2.get())
{
backwardHeap2->Clear();
}
else
{
backwardHeap2.reset(new QueryHeap(number_of_nodes));
}
}
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap3.get())
{
forwardHeap3->Clear();
}
else
{
forwardHeap3.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap3.get())
{
backwardHeap3->Clear();
}
else
{
backwardHeap3.reset(new QueryHeap(number_of_nodes));
}
}
+67
View File
@@ -0,0 +1,67 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SEARCH_ENGINE_DATA_H
#define SEARCH_ENGINE_DATA_H
#include "BinaryHeap.h"
#include "QueryEdge.h"
#include "StaticGraph.h"
#include "../typedefs.h"
#include <boost/thread.hpp>
#include <string>
#include <vector>
struct _HeapData {
NodeID parent;
/* explicit */ _HeapData( NodeID p ) : parent(p) { }
};
// typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
struct SearchEngineData {
typedef BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> > QueryHeap;
typedef boost::thread_specific_ptr<QueryHeap> SearchEngineHeapPtr;
static SearchEngineHeapPtr forwardHeap;
static SearchEngineHeapPtr backwardHeap;
static SearchEngineHeapPtr forwardHeap2;
static SearchEngineHeapPtr backwardHeap2;
static SearchEngineHeapPtr forwardHeap3;
static SearchEngineHeapPtr backwardHeap3;
void InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes);
void InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes);
void InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes);
};
#endif // SEARCH_ENGINE_DATA_H
+65 -26
View File
@@ -1,42 +1,81 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SEGMENTINFORMATION_H_
#define SEGMENTINFORMATION_H_
#include <climits>
#include "TurnInstructions.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
// Struct fits everything in one cache line
struct SegmentInformation {
_Coordinate location;
NodeID nameID;
double length;
FixedPointCoordinate location;
NodeID name_id;
unsigned duration;
double bearing;
TurnInstruction turnInstruction;
double length;
short bearing; //more than enough [0..3600] fits into 12 bits
TurnInstruction turn_instruction;
bool necessary;
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec) {}
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {}
explicit SegmentInformation(
const FixedPointCoordinate & location,
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_ */
+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
-71
View File
@@ -1,71 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef SIMPLESTACK_H_
#define SIMPLESTACK_H_
#include <cassert>
#include <vector>
template<typename StackItemT, class ContainerT = std::vector<StackItemT> >
class SimpleStack {
private:
int last;
ContainerT arr;
public:
SimpleStack() : last(-1) {
}
SimpleStack(std::size_t size_hint) : last(-1) {
hint(size_hint);
}
inline void hint(std::size_t size_hint) {
arr.reserve(size_hint);
}
inline void push(StackItemT t) {
++last;
arr.push_back(t);
}
inline void pop() {
arr.pop_back();
--last;
}
inline StackItemT top() {
assert (last >= 0);
return arr[last];
}
inline int size() {
return last+1;
}
inline bool empty() {
return (-1 == last);
}
};
#endif /* SIMPLESTACK_H_ */
+61 -43
View File
@@ -1,33 +1,42 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STATICGRAPH_H_INCLUDED
#define STATICGRAPH_H_INCLUDED
#include <vector>
#include <algorithm>
#include "../DataStructures/Percent.h"
#include "../DataStructures/SharedMemoryVectorWrapper.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include "ImportEdge.h"
template< typename EdgeDataT>
#include <algorithm>
#include <vector>
template< typename EdgeDataT, bool UseSharedMemory = false>
class StaticGraph {
public:
typedef NodeID NodeIterator;
@@ -39,8 +48,9 @@ public:
NodeIterator source;
NodeIterator target;
bool operator<( const InputEdge& right ) const {
if ( source != right.source )
if ( source != right.source ) {
return source < right.source;
}
return target < right.target;
}
};
@@ -81,16 +91,16 @@ public:
}
}
StaticGraph( std::vector<_StrNode> & nodes, std::vector<_StrEdge> & edges) {
_numNodes = nodes.size();
StaticGraph(
typename ShM<_StrNode, UseSharedMemory>::vector & nodes,
typename ShM<_StrEdge, UseSharedMemory>::vector & edges
) {
_numNodes = nodes.size()-1;
_numEdges = edges.size();
_nodes.swap(nodes);
_edges.swap(edges);
//Add dummy node to end of _nodes array;
_nodes.push_back(_nodes.back());
#ifndef NDEBUG
Percent p(GetNumberOfNodes());
for(unsigned u = 0; u < GetNumberOfNodes(); ++u) {
@@ -100,13 +110,20 @@ public:
if(data.shortcut) {
unsigned eid2 = FindEdgeInEitherDirection(u, data.id);
if(eid2 == UINT_MAX) {
DEBUG("cannot find first segment of edge (" << u << "," << data.id << "," << v << ")");
SimpleLogger().Write(logWARNING) <<
"cannot find first segment of edge (" <<
u << "," << data.id << "," << v << "), eid: " << eid;
data.shortcut = false;
BOOST_ASSERT(false);
}
eid2 = FindEdgeInEitherDirection(data.id, v);
if(eid2 == UINT_MAX) {
DEBUG("cannot find second segment of edge (" << u << "," << data.id << "," << v << ")");
SimpleLogger().Write(logWARNING) <<
"cannot find second segment of edge (" <<
u << "," << data.id << "," << v << "), eid2: " << eid2;
data.shortcut = false;
BOOST_ASSERT(false);
}
}
}
@@ -123,34 +140,34 @@ public:
return _numEdges;
}
unsigned GetOutDegree( const NodeIterator &n ) const {
unsigned GetOutDegree( const NodeIterator n ) const {
return BeginEdges(n)-EndEdges(n) - 1;
}
inline NodeIterator GetTarget( const EdgeIterator &e ) const {
inline NodeIterator GetTarget( const EdgeIterator e ) const {
return NodeIterator( _edges[e].target );
}
inline EdgeDataT &GetEdgeData( const EdgeIterator &e ) {
inline EdgeDataT &GetEdgeData( const EdgeIterator e ) {
return _edges[e].data;
}
const EdgeDataT &GetEdgeData( const EdgeIterator &e ) const {
const EdgeDataT &GetEdgeData( const EdgeIterator e ) const {
return _edges[e].data;
}
EdgeIterator BeginEdges( const NodeIterator &n ) const {
return EdgeIterator( _nodes[n].firstEdge );
EdgeIterator BeginEdges( const NodeIterator n ) const {
return EdgeIterator( _nodes.at(n).firstEdge );
}
EdgeIterator EndEdges( const NodeIterator &n ) const {
return EdgeIterator( _nodes[n+1].firstEdge );
EdgeIterator EndEdges( const NodeIterator n ) const {
return EdgeIterator( _nodes.at(n+1).firstEdge );
}
//searches for a specific edge
EdgeIterator FindEdge( const NodeIterator &from, const NodeIterator &to ) const {
EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const {
EdgeIterator smallestEdge = SPECIAL_EDGEID;
EdgeWeight smallestWeight = UINT_MAX;
EdgeWeight smallestWeight = INVALID_EDGE_WEIGHT;
for ( EdgeIterator edge = BeginEdges( from ); edge < EndEdges(from); edge++ ) {
const NodeID target = GetTarget(edge);
const EdgeWeight weight = GetEdgeData(edge).distance;
@@ -161,17 +178,18 @@ public:
return smallestEdge;
}
EdgeIterator FindEdgeInEitherDirection( const NodeIterator &from, const NodeIterator &to ) const {
EdgeIterator FindEdgeInEitherDirection( const NodeIterator from, const NodeIterator to ) const {
EdgeIterator tmp = FindEdge( from, to );
return (UINT_MAX != tmp ? tmp : FindEdge( to, from ));
}
EdgeIterator FindEdgeIndicateIfReverse( const NodeIterator &from, const NodeIterator &to, bool & result ) const {
EdgeIterator FindEdgeIndicateIfReverse( const NodeIterator from, const NodeIterator to, bool & result ) const {
EdgeIterator tmp = FindEdge( from, to );
if(UINT_MAX == tmp) {
tmp = FindEdge( to, from );
if(UINT_MAX != tmp)
if(UINT_MAX != tmp) {
result = true;
}
}
return tmp;
}
@@ -181,8 +199,8 @@ private:
NodeIterator _numNodes;
EdgeIterator _numEdges;
std::vector< _StrNode > _nodes;
std::vector< _StrEdge > _edges;
typename ShM< _StrNode, UseSharedMemory >::vector _nodes;
typename ShM< _StrEdge, UseSharedMemory >::vector _edges;
};
#endif // STATICGRAPH_H_INCLUDED
+30 -23
View File
@@ -1,29 +1,36 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
KD Tree coded by Christian Vetter, Monav Project
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// KD Tree coded by Christian Vetter, Monav Project
*/
#ifndef STATICKDTREE_H_INCLUDED
#define STATICKDTREE_H_INCLUDED
#include <cassert>
#include <boost/assert.hpp>
#include <vector>
#include <algorithm>
#include <stack>
@@ -92,9 +99,9 @@ public:
}
};
StaticKDTree( std::vector< InputPoint > * points ){
assert( k > 0 );
assert ( points->size() > 0 );
explicit StaticKDTree( std::vector< InputPoint > * points ){
BOOST_ASSERT( k > 0 );
BOOST_ASSERT ( points->size() > 0 );
size = points->size();
kdtree = new InputPoint[size];
for ( Iterator i = 0; i != size; ++i ) {
@@ -200,13 +207,13 @@ private:
};
class Less {
public:
Less( unsigned d ) {
explicit Less( unsigned d ) {
dimension = d;
assert( dimension < k );
BOOST_ASSERT( dimension < k );
}
bool operator() ( const InputPoint& left, const InputPoint& right ) {
assert( dimension < k );
BOOST_ASSERT( dimension < k );
return left.coordinates[dimension] < right.coordinates[dimension];
}
private:
+828
View File
@@ -0,0 +1,828 @@
/*
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 STATICRTREE_H_
#define STATICRTREE_H_
#include "DeallocatingVector.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/SimpleLogger.h"
#include "../Util/TimingUtil.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/minmax.hpp>
#include <boost/algorithm/minmax_element.hpp>
#include <boost/range/algorithm_ext/erase.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/type_traits.hpp>
#include <algorithm>
#include <limits>
#include <queue>
#include <string>
#include <vector>
//tuning parameters
const static uint32_t RTREE_BRANCHING_FACTOR = 50;
const static uint32_t RTREE_LEAF_NODE_SIZE = 1170;
// Implements a static, i.e. packed, R-tree
static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtree_stream;
template<class DataT, class CoordinateListT = std::vector<FixedPointCoordinate>, bool UseSharedMemory = false>
class StaticRTree : boost::noncopyable {
public:
struct RectangleInt2D {
RectangleInt2D() :
min_lon(INT_MAX),
max_lon(INT_MIN),
min_lat(INT_MAX),
max_lat(INT_MIN) {}
int32_t min_lon, max_lon;
int32_t min_lat, max_lat;
inline void InitializeMBRectangle(
DataT const * objects,
const uint32_t element_count,
const std::vector<NodeInfo> & coordinate_list
) {
for(uint32_t i = 0; i < element_count; ++i) {
min_lon = std::min(
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(
coordinate_list.at(objects[i].u).lon,
coordinate_list.at(objects[i].v).lon
)
);
min_lat = std::min(
min_lat, std::min(
coordinate_list.at(objects[i].u).lat,
coordinate_list.at(objects[i].v).lon
)
);
max_lat = std::max(
max_lat, std::max(
coordinate_list.at(objects[i].u).lat,
coordinate_list.at(objects[i].v).lon
)
);
}
}
inline void AugmentMBRectangle(const RectangleInt2D & other) {
min_lon = std::min(min_lon, other.min_lon);
max_lon = std::max(max_lon, other.max_lon);
min_lat = std::min(min_lat, other.min_lat);
max_lat = std::max(max_lat, other.max_lat);
}
inline FixedPointCoordinate Centroid() const {
FixedPointCoordinate centroid;
//The coordinates of the midpoints are given by:
//x = (x1 + x2) /2 and y = (y1 + y2) /2.
centroid.lon = (min_lon + max_lon)/2;
centroid.lat = (min_lat + max_lat)/2;
return centroid;
}
inline bool Intersects(const RectangleInt2D & other) const {
FixedPointCoordinate upper_left (other.max_lat, other.min_lon);
FixedPointCoordinate upper_right(other.max_lat, other.max_lon);
FixedPointCoordinate lower_right(other.min_lat, other.max_lon);
FixedPointCoordinate lower_left (other.min_lat, other.min_lon);
return (
Contains(upper_left ) ||
Contains(upper_right) ||
Contains(lower_right) ||
Contains(lower_left )
);
}
inline double GetMinDist(const FixedPointCoordinate & location) const {
bool is_contained = Contains(location);
if (is_contained) {
return 0.0;
}
double min_dist = std::numeric_limits<double>::max();
min_dist = std::min(
min_dist,
FixedPointCoordinate::ApproximateDistance(
location.lat,
location.lon,
max_lat,
min_lon
)
);
min_dist = std::min(
min_dist,
FixedPointCoordinate::ApproximateDistance(
location.lat,
location.lon,
max_lat,
max_lon
)
);
min_dist = std::min(
min_dist,
FixedPointCoordinate::ApproximateDistance(
location.lat,
location.lon,
min_lat,
max_lon
)
);
min_dist = std::min(
min_dist,
FixedPointCoordinate::ApproximateDistance(
location.lat,
location.lon,
min_lat,
min_lon
)
);
return min_dist;
}
inline double GetMinMaxDist(const FixedPointCoordinate & location) const {
double min_max_dist = std::numeric_limits<double>::max();
//Get minmax distance to each of the four sides
FixedPointCoordinate upper_left (max_lat, min_lon);
FixedPointCoordinate upper_right(max_lat, max_lon);
FixedPointCoordinate lower_right(min_lat, max_lon);
FixedPointCoordinate lower_left (min_lat, min_lon);
min_max_dist = std::min(
min_max_dist,
std::max(
FixedPointCoordinate::ApproximateDistance(location, upper_left ),
FixedPointCoordinate::ApproximateDistance(location, upper_right)
)
);
min_max_dist = std::min(
min_max_dist,
std::max(
FixedPointCoordinate::ApproximateDistance(location, upper_right),
FixedPointCoordinate::ApproximateDistance(location, lower_right)
)
);
min_max_dist = std::min(
min_max_dist,
std::max(
FixedPointCoordinate::ApproximateDistance(location, lower_right),
FixedPointCoordinate::ApproximateDistance(location, lower_left )
)
);
min_max_dist = std::min(
min_max_dist,
std::max(
FixedPointCoordinate::ApproximateDistance(location, lower_left ),
FixedPointCoordinate::ApproximateDistance(location, upper_left )
)
);
return min_max_dist;
}
inline bool Contains(const FixedPointCoordinate & location) const {
const bool lats_contained =
(location.lat > min_lat) && (location.lat < max_lat);
const bool lons_contained =
(location.lon > min_lon) && (location.lon < max_lon);
return lats_contained && lons_contained;
}
inline friend std::ostream & operator<< (
std::ostream & out,
const RectangleInt2D & rect
) {
out << rect.min_lat/COORDINATE_PRECISION << ","
<< rect.min_lon/COORDINATE_PRECISION << " "
<< rect.max_lat/COORDINATE_PRECISION << ","
<< rect.max_lon/COORDINATE_PRECISION;
return out;
}
};
typedef RectangleInt2D RectangleT;
struct TreeNode {
TreeNode() : child_count(0), child_is_on_disk(false) {}
RectangleT minimum_bounding_rectangle;
uint32_t child_count:31;
bool child_is_on_disk:1;
uint32_t children[RTREE_BRANCHING_FACTOR];
};
private:
struct WrappedInputElement {
explicit WrappedInputElement(
const uint32_t _array_index,
const uint64_t _hilbert_value
) : m_array_index(_array_index), m_hilbert_value(_hilbert_value) {}
WrappedInputElement() : m_array_index(UINT_MAX), m_hilbert_value(0) {}
uint32_t m_array_index;
uint64_t m_hilbert_value;
inline bool operator<(const WrappedInputElement & other) const {
return m_hilbert_value < other.m_hilbert_value;
}
};
struct LeafNode {
LeafNode() : object_count(0) {}
uint32_t object_count;
DataT objects[RTREE_LEAF_NODE_SIZE];
};
struct QueryCandidate {
explicit QueryCandidate(
const uint32_t n_id,
const double dist
) : node_id(n_id), min_dist(dist) {}
QueryCandidate() : node_id(UINT_MAX), min_dist(std::numeric_limits<double>::max()) {}
uint32_t node_id;
double min_dist;
inline bool operator<(const QueryCandidate & other) const {
return min_dist < other.min_dist;
}
};
typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
uint64_t m_element_count;
const std::string m_leaf_node_filename;
boost::shared_ptr<CoordinateListT> m_coordinate_list;
public:
//Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
explicit StaticRTree(
std::vector<DataT> & input_data_vector,
const std::string tree_node_filename,
const std::string leaf_node_filename,
const std::vector<NodeInfo> & coordinate_list
)
: m_element_count(input_data_vector.size()),
m_leaf_node_filename(leaf_node_filename)
{
SimpleLogger().Write() <<
"constructing r-tree of " << m_element_count <<
" edge elements build on-top of " << coordinate_list.size() << " coordinates";
double time1 = get_timestamp();
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
HilbertCode get_hilbert_number;
//generate auxiliary vector of hilbert-values
#pragma omp parallel for schedule(guided)
for(uint64_t element_counter = 0; element_counter < m_element_count; ++element_counter) {
input_wrapper_vector[element_counter].m_array_index = element_counter;
//Get Hilbert-Value for centroid in mercartor projection
DataT const & current_element = input_data_vector[element_counter];
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);
uint64_t current_hilbert_value = get_hilbert_number(current_centroid);
input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value;
}
//open leaf file
boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
leaf_node_file.write((char*) &m_element_count, sizeof(uint64_t));
//sort the hilbert-value representatives
std::sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
std::vector<TreeNode> tree_nodes_in_level;
//pack M elements into leaf node and write to leaf file
uint64_t processed_objects_count = 0;
while(processed_objects_count < m_element_count) {
LeafNode current_leaf;
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) {
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;
current_leaf.objects[current_element_index] = input_data_vector[index_of_next_object];
++current_leaf.object_count;
}
}
//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,
coordinate_list
);
current_node.child_is_on_disk = true;
current_node.children[0] = tree_nodes_in_level.size();
tree_nodes_in_level.push_back(current_node);
//write leaf_node to leaf node file
leaf_node_file.write((char*)&current_leaf, sizeof(current_leaf));
processed_objects_count += current_leaf.object_count;
}
//close leaf file
leaf_node_file.close();
uint32_t processing_level = 0;
while(1 < tree_nodes_in_level.size()) {
std::vector<TreeNode> tree_nodes_in_next_level;
uint32_t processed_tree_nodes_in_level = 0;
while(processed_tree_nodes_in_level < tree_nodes_in_level.size()) {
TreeNode parent_node;
//pack RTREE_BRANCHING_FACTOR elements into tree_nodes each
for(
uint32_t current_child_node_index = 0;
RTREE_BRANCHING_FACTOR > current_child_node_index;
++current_child_node_index
) {
if(processed_tree_nodes_in_level < tree_nodes_in_level.size()) {
TreeNode & current_child_node = tree_nodes_in_level[processed_tree_nodes_in_level];
//add tree node to parent entry
parent_node.children[current_child_node_index] = m_search_tree.size();
m_search_tree.push_back(current_child_node);
//augment MBR of parent
parent_node.minimum_bounding_rectangle.AugmentMBRectangle(current_child_node.minimum_bounding_rectangle);
//increase counters
++parent_node.child_count;
++processed_tree_nodes_in_level;
}
}
tree_nodes_in_next_level.push_back(parent_node);
}
tree_nodes_in_level.swap(tree_nodes_in_next_level);
++processing_level;
}
BOOST_ASSERT_MSG(1 == tree_nodes_in_level.size(), "tree broken, more than one root node");
//last remaining entry is the root node, store it
m_search_tree.push_back(tree_nodes_in_level[0]);
//reverse and renumber tree to have root at index 0
std::reverse(m_search_tree.begin(), m_search_tree.end());
#pragma omp parallel for schedule(guided)
for(uint32_t i = 0; i < m_search_tree.size(); ++i) {
TreeNode & current_tree_node = m_search_tree[i];
for(uint32_t j = 0; j < current_tree_node.child_count; ++j) {
const uint32_t old_id = current_tree_node.children[j];
const uint32_t new_id = m_search_tree.size() - old_id - 1;
current_tree_node.children[j] = new_id;
}
}
//open tree file
boost::filesystem::ofstream tree_node_file(
tree_node_filename,
std::ios::binary
);
uint32_t size_of_tree = m_search_tree.size();
BOOST_ASSERT_MSG(0 < size_of_tree, "tree empty");
tree_node_file.write((char *)&size_of_tree, sizeof(uint32_t));
tree_node_file.write((char *)&m_search_tree[0], sizeof(TreeNode)*size_of_tree);
//close tree node file.
tree_node_file.close();
double time2 = get_timestamp();
SimpleLogger().Write() <<
"finished r-tree construction in " << (time2-time1) << " seconds";
}
//Read-only operation for queries
explicit StaticRTree(
const boost::filesystem::path & node_file,
const boost::filesystem::path & leaf_file,
const boost::shared_ptr<CoordinateListT> coordinate_list
) : m_leaf_node_filename( leaf_file.string() ) {
//open tree node file and load into RAM.
m_coordinate_list = coordinate_list;
if ( !boost::filesystem::exists( node_file ) ) {
throw OSRMException("ram index file does not exist");
}
if ( 0 == boost::filesystem::file_size( node_file ) ) {
throw OSRMException("ram index file is empty");
}
boost::filesystem::ifstream tree_node_file( node_file, std::ios::binary );
uint32_t tree_size = 0;
tree_node_file.read((char*)&tree_size, sizeof(uint32_t));
m_search_tree.resize(tree_size);
tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size);
tree_node_file.close();
//open leaf node file and store thread specific pointer
if ( !boost::filesystem::exists( leaf_file ) ) {
throw OSRMException("mem index file does not exist");
}
if ( 0 == boost::filesystem::file_size( leaf_file ) ) {
throw OSRMException("mem index file is empty");
}
boost::filesystem::ifstream leaf_node_file( leaf_file, std::ios::binary );
leaf_node_file.read((char*)&m_element_count, sizeof(uint64_t));
leaf_node_file.close();
//SimpleLogger().Write() << tree_size << " nodes in search tree";
//SimpleLogger().Write() << m_element_count << " elements in leafs";
}
explicit StaticRTree(
TreeNode * tree_node_ptr,
const uint32_t number_of_nodes,
const boost::filesystem::path & leaf_file,
boost::shared_ptr<CoordinateListT> coordinate_list
) : m_search_tree(tree_node_ptr, number_of_nodes),
m_leaf_node_filename(leaf_file.string()),
m_coordinate_list(coordinate_list)
{
//open leaf node file and store thread specific pointer
if ( !boost::filesystem::exists( leaf_file ) ) {
throw OSRMException("mem index file does not exist");
}
if ( 0 == boost::filesystem::file_size( leaf_file ) ) {
throw OSRMException("mem index file is empty");
}
boost::filesystem::ifstream leaf_node_file( leaf_file, std::ios::binary );
leaf_node_file.read((char*)&m_element_count, sizeof(uint64_t));
leaf_node_file.close();
if( thread_local_rtree_stream.get() ) {
thread_local_rtree_stream->close();
}
//SimpleLogger().Write() << tree_size << " nodes in search tree";
//SimpleLogger().Write() << m_element_count << " elements in leafs";
}
//Read-only operation for queries
bool LocateClosestEndPointForCoordinate(
const FixedPointCoordinate & input_coordinate,
FixedPointCoordinate & result_coordinate,
const unsigned zoom_level
) {
bool ignore_tiny_components = (zoom_level <= 14);
DataT nearest_edge;
double min_dist = std::numeric_limits<double>::max();
double min_max_dist = std::numeric_limits<double>::max();
bool found_a_nearest_edge = false;
//initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue;
double current_min_dist = m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate);
traversal_queue.push(
QueryCandidate(0, current_min_dist)
);
BOOST_ASSERT_MSG(
std::numeric_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();
const bool prune_downward = (current_query_node.min_dist >= min_max_dist);
const 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
);
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
DataT const & current_edge = current_leaf_node.objects[i];
if(
ignore_tiny_components &&
current_edge.belongsToTinyComponent
) {
continue;
}
double current_minimum_distance = FixedPointCoordinate::ApproximateDistance(
input_coordinate.lat,
input_coordinate.lon,
m_coordinate_list->at(current_edge.u).lat,
m_coordinate_list->at(current_edge.u).lon
);
if( current_minimum_distance < min_dist ) {
//found a new minimum
min_dist = current_minimum_distance;
result_coordinate.lat = m_coordinate_list->at(current_edge.u).lat;
result_coordinate.lon = m_coordinate_list->at(current_edge.u).lon;
found_a_nearest_edge = true;
}
current_minimum_distance = FixedPointCoordinate::ApproximateDistance(
input_coordinate.lat,
input_coordinate.lon,
m_coordinate_list->at(current_edge.v).lat,
m_coordinate_list->at(current_edge.v).lon
);
if( current_minimum_distance < min_dist ) {
//found a new minimum
min_dist = current_minimum_distance;
result_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
result_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
found_a_nearest_edge = true;
}
}
} 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];
const TreeNode & child_tree_node = m_search_tree[child_id];
const 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)
);
}
}
}
}
return found_a_nearest_edge;
}
bool FindPhantomNodeForCoordinate(
const FixedPointCoordinate & input_coordinate,
PhantomNode & result_phantom_node,
const unsigned zoom_level
) {
bool ignore_tiny_components = (zoom_level <= 14);
DataT nearest_edge;
// uint32_t io_count = 0;
uint32_t explored_tree_nodes_count = 0;
//SimpleLogger().Write() << "searching for coordinate " << input_coordinate;
double min_dist = std::numeric_limits<double>::max();
double min_max_dist = std::numeric_limits<double>::max();
bool found_a_nearest_edge = false;
FixedPointCoordinate nearest, current_start_coordinate, current_end_coordinate;
//initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue;
double current_min_dist = m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate);
traversal_queue.push( QueryCandidate(0, current_min_dist) );
BOOST_ASSERT_MSG(
std::numeric_limits<double>::epsilon() > (0. - traversal_queue.top().min_dist),
"Root element in NN Search has min dist != 0."
);
LeafNode current_leaf_node;
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) {
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.;
const double current_perpendicular_distance = current_edge.ComputePerpendicularDistance(
m_coordinate_list->at(current_edge.u),
m_coordinate_list->at(current_edge.v),
input_coordinate,
nearest,
current_ratio
);
BOOST_ASSERT( 0. <= current_perpendicular_distance );
if(
( current_perpendicular_distance < min_dist ) &&
!DoubleEpsilonCompare(
current_perpendicular_distance,
min_dist
)
) { //found a new minimum
min_dist = current_perpendicular_distance;
//TODO: use assignment c'tor in PhantomNode
result_phantom_node.forward_node_id = current_edge.forward_edge_based_node_id;
result_phantom_node.reverse_node_id = current_edge.reverse_edge_based_node_id;
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;
current_start_coordinate.lat = m_coordinate_list->at(current_edge.u).lat;
current_start_coordinate.lon = m_coordinate_list->at(current_edge.u).lon;
current_end_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
current_end_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
nearest_edge = current_edge;
found_a_nearest_edge = true;
}
}
} 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));
}
}
}
}
//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;
}
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:
inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode& result_node) {
if(
!thread_local_rtree_stream.get() ||
!thread_local_rtree_stream->is_open()
) {
thread_local_rtree_stream.reset(
new boost::filesystem::ifstream(
m_leaf_node_filename,
std::ios::in | std::ios::binary
)
);
}
if(!thread_local_rtree_stream->good()) {
thread_local_rtree_stream->clear(std::ios::goodbit);
SimpleLogger().Write(logDEBUG) << "Resetting stale filestream";
}
uint64_t seek_pos = sizeof(uint64_t) + leaf_id*sizeof(LeafNode);
thread_local_rtree_stream->seekg(seek_pos);
thread_local_rtree_stream->read((char *)&result_node, sizeof(LeafNode));
}
inline bool EdgesAreEquivalent(
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);
}
inline bool DoubleEpsilonCompare(const double d1, const double d2) const {
return (std::abs(d1 - d2) < std::numeric_limits<double>::epsilon() );
}
};
//[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403
//[2] "Nearest Neighbor Queries", N. Roussopulos et al; 1995; DOI: 10.1145/223784.223794
#endif /* STATICRTREE_H_ */
+26 -55
View File
@@ -1,32 +1,39 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
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 TURNINSTRUCTIONS_H_
#define TURNINSTRUCTIONS_H_
#include <string>
#include <boost/noncopyable.hpp>
typedef unsigned char TurnInstruction;
//This is a hack until c++0x is available enough to use scoped enums
struct TurnInstructionsClass {
struct TurnInstructionsClass : boost::noncopyable {
const static TurnInstruction NoTurn = 0; //Give no instruction at all
const static TurnInstruction GoStraight = 1; //Tell user to go straight!
@@ -44,48 +51,14 @@ struct TurnInstructionsClass {
const static TurnInstruction StayOnRoundAbout = 13;
const static TurnInstruction StartAtEndOfStreet = 14;
const static TurnInstruction ReachedYourDestination = 15;
const static TurnInstruction EnterAgainstAllowedDirection = 16;
const static TurnInstruction LeaveAgainstAllowedDirection = 17;
const static TurnInstruction AccessRestrictionFlag = 128;
const static TurnInstruction InverseAccessRestrictionFlag = 0x7f; // ~128 does not work without a warning.
const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag
// std::string TurnStrings[16];
// std::string Ordinals[12];
//This is a hack until c++0x is available enough to use initializer lists.
// TurnInstructionsClass(){
// TurnStrings [0] = "";
// TurnStrings [1] = "Continue";
// TurnStrings [2] = "Turn slight right";
// TurnStrings [3] = "Turn right";
// TurnStrings [4] = "Turn sharp right";
// TurnStrings [5] = "U-Turn";
// TurnStrings [6] = "Turn sharp left";
// TurnStrings [7] = "Turn left";
// TurnStrings [8] = "Turn slight left";
// TurnStrings [9] = "Reach via point";
// TurnStrings[10] = "Head";
// TurnStrings[11] = "Enter roundabout";
// TurnStrings[12] = "Leave roundabout";
// TurnStrings[13] = "Stay on roundabout";
// TurnStrings[14] = "Start";
// TurnStrings[15] = "You have reached your destination";
//
// Ordinals[0] = "zeroth";
// Ordinals[1] = "first";
// Ordinals[2] = "second";
// Ordinals[3] = "third";
// Ordinals[4] = "fourth";
// Ordinals[5] = "fifth";
// Ordinals[6] = "sixth";
// Ordinals[7] = "seventh";
// Ordinals[8] = "eighth";
// Ordinals[9] = "nineth";
// Ordinals[10] = "tenth";
// Ordinals[11] = "one of the too many";
// };
static inline TurnInstruction GetTurnDirectionOfInstruction( const double angle ) {
if(angle >= 23 && angle < 67) {
return TurnSharpRight;
@@ -119,6 +92,4 @@ struct TurnInstructionsClass {
};
static TurnInstructionsClass TurnInstructions;
#endif /* TURNINSTRUCTIONS_H_ */
-70
View File
@@ -1,70 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef TIMEUTIL_H_
#define TIMEUTIL_H_
#include <climits>
#include <cmath>
#include <cstdlib>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifdef _WIN32
#include <sys/timeb.h>
#include <sys/types.h>
#include <winsock.h>
void gettimeofday(struct timeval* t,void* timezone)
{ struct _timeb timebuffer;
_ftime( &timebuffer );
t->tv_sec=timebuffer.time;
t->tv_usec=1000*timebuffer.millitm;
}
#else
#include <sys/time.h>
#endif
#ifdef _WIN32
#include <boost/functional/hash.hpp>
#else
#include <tr1/functional_hash.h>
#endif
#include <boost/thread.hpp>
/** Returns a timestamp (now) in seconds (incl. a fractional part). */
static inline double get_timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
}
static inline double y2lat(double a) { return 180/M_PI * (2 * atan(exp(a*M_PI/180)) - M_PI/2); }
static inline double lat2y(double a) { return 180/M_PI * log(tan(M_PI/4+a*(M_PI/180)/2)); }
static inline unsigned boost_thread_id_hash(boost::thread::id const& id) {
std::stringstream ostr;
ostr << id;
std::tr1::hash<std::string> h;
return h(ostr.str());
}
#endif /* TIMEUTIL_H_ */
+25 -18
View File
@@ -1,22 +1,29 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FASTXORHASH_H_
#define FASTXORHASH_H_
@@ -49,7 +56,7 @@ public:
table1.resize(2 << 16);
table2.resize(2 << 16);
for(unsigned i = 0; i < (2 << 16); ++i) {
table1[i] = i; table2[i];
table1[i] = i; table2[i] = i;
}
std::random_shuffle(table1.begin(), table1.end());
std::random_shuffle(table2.begin(), table2.end());
@@ -75,8 +82,8 @@ public:
table3.resize(1 << 8);
table4.resize(1 << 8);
for(unsigned i = 0; i < (1 << 8); ++i) {
table1[i] = i; table2[i];
table3[i] = i; table4[i];
table1[i] = i; table2[i] = i;
table3[i] = i; table4[i] = i;
}
std::random_shuffle(table1.begin(), table1.end());
std::random_shuffle(table2.begin(), table2.end());
+25 -18
View File
@@ -1,32 +1,39 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
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 XORFASTHASHSTORAGE_H_
#define XORFASTHASHSTORAGE_H_
#include "XORFastHash.h"
#include <climits>
#include <vector>
#include <bitset>
#include "XORFastHash.h"
template< typename NodeID, typename Key >
class XORFastHashStorage {
public:
@@ -47,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 ) {
unsigned short position = fastHash(node);
+45 -32
View File
@@ -1,55 +1,68 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BASE_DESCRIPTOR_H_
#define BASE_DESCRIPTOR_H_
#include <cassert>
#include <cmath>
#include <cstdio>
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../typedefs.h"
#include <osrm/Reply.h>
#include <string>
#include <vector>
#include "../typedefs.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/HashTable.h"
#include "../Util/StringUtil.h"
#include "../Plugins/RawRouteData.h"
struct _DescriptorConfig {
_DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(true), z(18) {}
struct DescriptorConfig {
DescriptorConfig() :
instructions(true),
geometry(true),
encode_geometry(true),
zoom_level(18)
{ }
bool instructions;
bool geometry;
bool encodeGeometry;
unsigned short z;
bool encode_geometry;
unsigned short zoom_level;
};
template<class SearchEngineT>
template<class DataFacadeT>
class BaseDescriptor {
public:
BaseDescriptor() { }
//Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BaseDescriptor() { }
virtual void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) = 0;
virtual void SetConfig(const _DescriptorConfig & config) = 0;
virtual void Run(
const RawRouteData & rawRoute,
const PhantomNodes & phantomNodes,
DataFacadeT * facade,
http::Reply & reply
) = 0;
virtual void SetConfig(const DescriptorConfig & config) = 0;
};
#endif /* BASE_DESCRIPTOR_H_ */
+103 -173
View File
@@ -1,22 +1,29 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "DescriptionFactory.h"
@@ -24,187 +31,110 @@ DescriptionFactory::DescriptionFactory() : entireLength(0) { }
DescriptionFactory::~DescriptionFactory() { }
inline double DescriptionFactory::DegreeToRadian(const double degree) const {
return degree * (M_PI/180);
inline double DescriptionFactory::DegreeToRadian(const double degree) const
{
return degree * (M_PI/180.);
}
inline double DescriptionFactory::RadianToDegree(const double radian) const {
return radian * (180/M_PI);
inline double DescriptionFactory::RadianToDegree(const double radian) const
{
return radian * (180./M_PI);
}
double DescriptionFactory::GetBearing(const _Coordinate& A, const _Coordinate& B) const {
double deltaLong = DegreeToRadian(B.lon/100000. - A.lon/100000.);
double DescriptionFactory::GetBearing(const FixedPointCoordinate & A, const FixedPointCoordinate & B) const
{
double delta_long = DegreeToRadian(B.lon/COORDINATE_PRECISION - A.lon/COORDINATE_PRECISION);
double lat1 = DegreeToRadian(A.lat/100000.);
double lat2 = DegreeToRadian(B.lat/100000.);
const double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION);
const double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION);
double y = sin(deltaLong) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong);
const double y = sin(delta_long) * cos(lat2);
const double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_long);
double result = RadianToDegree(atan2(y, x));
while(result <= 0.)
while (result < 0.)
{
result += 360.;
while(result >= 360.)
result -= 360.;
}
while (result >= 360.)
{
result -= 360.;
}
return result;
}
void DescriptionFactory::SetStartSegment(const PhantomNode & _startPhantom) {
startPhantom = _startPhantom;
AppendSegment(_startPhantom.location, _PathData(0, _startPhantom.nodeBasedEdgeNameID, 10, _startPhantom.weight1));
void DescriptionFactory::SetStartSegment(const PhantomNode & source, const bool source_traversed_in_reverse)
{
start_phantom = source;
AppendSegment(
source.location,
PathData(0, source.name_id, 10, source.forward_weight)
);
}
void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) {
targetPhantom = _targetPhantom;
pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) );
void DescriptionFactory::SetEndSegment(const PhantomNode & target, const bool target_traversed_in_reverse)
{
target_phantom = target;
pathDescription.push_back(
SegmentInformation(
target.location,
target.name_id,
0,
target.reverse_weight,
0,
true
)
);
}
void DescriptionFactory::AppendSegment(const _Coordinate & coordinate, const _PathData & data ) {
if(1 == pathDescription.size() && pathDescription.back().location == coordinate) {
pathDescription.back().nameID = data.nameID;
} else {
pathDescription.push_back(SegmentInformation(coordinate, data.nameID, 0, data.durationOfSegment, data.turnInstruction) );
void DescriptionFactory::AppendSegment(const FixedPointCoordinate & coordinate, const PathData & path_point)
{
if ((1 == pathDescription.size()) && ( pathDescription.back().location == coordinate))
{
pathDescription.back().name_id = path_point.name_id;
}
}
void DescriptionFactory::AppendEncodedPolylineString(std::string & output, bool isEncoded) {
if(isEncoded)
pc.printEncodedString(pathDescription, output);
else
pc.printUnencodedString(pathDescription, output);
}
void DescriptionFactory::AppendEncodedPolylineString(std::string &output) {
pc.printEncodedString(pathDescription, output);
}
void DescriptionFactory::AppendUnencodedPolylineString(std::string &output) {
pc.printUnencodedString(pathDescription, output);
}
void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLevel) {
if(0 == pathDescription.size())
return;
// unsigned entireLength = 0;
/** starts at index 1 */
pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
pathDescription[i].length = ApproximateDistanceByEuclid(pathDescription[i-1].location, pathDescription[i].location);
{
pathDescription.push_back(
SegmentInformation(coordinate, path_point.name_id, path_point.durationOfSegment, 0, path_point.turnInstruction)
);
}
}
double lengthOfSegment = 0;
unsigned durationOfSegment = 0;
unsigned indexOfSegmentBegin = 0;
std::string string0 = sEngine.GetEscapedNameForNameID(pathDescription[0].nameID);
std::string string1;
/*Simplify turn instructions
Input :
10. Turn left on B 36 for 20 km
11. Continue on B 35; B 36 for 2 km
12. Continue on B 36 for 13 km
becomes:
10. Turn left on B 36 for 35 km
*/
//TODO: rework to check only end and start of string.
// stl string is way to expensive
// unsigned lastTurn = 0;
// for(unsigned i = 1; i < pathDescription.size(); ++i) {
// string1 = sEngine.GetEscapedNameForNameID(pathDescription[i].nameID);
// if(TurnInstructionsClass::GoStraight == pathDescription[i].turnInstruction) {
// if(std::string::npos != string0.find(string1+";")
// || std::string::npos != string0.find(";"+string1)
// || std::string::npos != string0.find(string1+" ;")
// || std::string::npos != string0.find("; "+string1)
// ){
// INFO("->next correct: " << string0 << " contains " << string1);
// for(; lastTurn != i; ++lastTurn)
// pathDescription[lastTurn].nameID = pathDescription[i].nameID;
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
// } else if(std::string::npos != string1.find(string0+";")
// || std::string::npos != string1.find(";"+string0)
// || std::string::npos != string1.find(string0+" ;")
// || std::string::npos != string1.find("; "+string0)
// ){
// INFO("->prev correct: " << string1 << " contains " << string0);
// pathDescription[i].nameID = pathDescription[i-1].nameID;
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
// }
// }
// if (TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
// lastTurn = i;
// }
// string0 = string1;
// }
for(unsigned i = 1; i < pathDescription.size(); ++i) {
entireLength += pathDescription[i].length;
lengthOfSegment += pathDescription[i].length;
durationOfSegment += pathDescription[i].duration;
pathDescription[indexOfSegmentBegin].length = lengthOfSegment;
pathDescription[indexOfSegmentBegin].duration = durationOfSegment;
if(TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
//INFO("Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID);
assert(pathDescription[i].necessary);
lengthOfSegment = 0;
durationOfSegment = 0;
indexOfSegmentBegin = i;
}
}
// INFO("#segs: " << pathDescription.size());
//Post-processing to remove empty or nearly empty path segments
if(FLT_EPSILON > pathDescription.back().length) {
// INFO("#segs: " << pathDescription.size() << ", last ratio: " << targetPhantom.ratio << ", length: " << pathDescription.back().length);
if(pathDescription.size() > 2){
pathDescription.pop_back();
pathDescription.back().necessary = true;
pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
// INFO("Deleting last turn instruction");
}
void DescriptionFactory::AppendEncodedPolylineString(
const bool return_encoded,
std::vector<std::string> & output
) {
std::string temp;
if(return_encoded) {
polyline_compressor.printEncodedString(pathDescription, temp);
} else {
pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio);
polyline_compressor.printUnencodedString(pathDescription, temp);
}
if(FLT_EPSILON > pathDescription[0].length) {
//TODO: this is never called actually?
if(pathDescription.size() > 2) {
pathDescription.erase(pathDescription.begin());
pathDescription[0].turnInstruction = TurnInstructions.HeadOn;
pathDescription[0].necessary = true;
startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
// INFO("Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length);
}
} else {
pathDescription[0].duration *= startPhantom.ratio;
}
//Generalize poly line
dp.Run(pathDescription, zoomLevel);
//fix what needs to be fixed else
for(unsigned i = 0; i < pathDescription.size()-1 && pathDescription.size() >= 2; ++i){
if(pathDescription[i].necessary) {
double angle = GetBearing(pathDescription[i].location, pathDescription[i+1].location);
pathDescription[i].bearing = angle;
}
}
// BuildRouteSummary(entireLength, duration);
return;
output.push_back(temp);
}
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time) {
summary.startName = startPhantom.nodeBasedEdgeNameID;
summary.destName = targetPhantom.nodeBasedEdgeNameID;
void DescriptionFactory::AppendEncodedPolylineString(
std::vector<std::string> &output
) const {
std::string temp;
polyline_compressor.printEncodedString(pathDescription, temp);
output.push_back(temp);
}
void DescriptionFactory::AppendUnencodedPolylineString(
std::vector<std::string>& output
) const {
std::string temp;
polyline_compressor.printUnencodedString(pathDescription, temp);
output.push_back(temp);
}
void DescriptionFactory::BuildRouteSummary(
const double distance,
const unsigned time
) {
summary.startName = start_phantom.name_id;
summary.destName = target_phantom.name_id;
summary.BuildDurationAndLengthStrings(distance, time);
}
+169 -44
View File
@@ -1,65 +1,78 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DESCRIPTIONFACTORY_H_
#define DESCRIPTIONFACTORY_H_
#include <vector>
#include "../typedefs.h"
#include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/SearchEngine.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <limits>
#include <vector>
/* This class is fed with all way segments in consecutive order
* and produces the description plus the encoded polyline */
class DescriptionFactory {
DouglasPeucker<SegmentInformation> dp;
PolylineCompressor pc;
PhantomNode startPhantom, targetPhantom;
typedef SearchEngine<QueryEdge::EdgeData, StaticGraph<QueryEdge::EdgeData> > SearchEngineT;
DouglasPeucker polyline_generalizer;
PolylineCompressor polyline_compressor;
PhantomNode start_phantom, target_phantom;
double DegreeToRadian(const double degree) const;
double RadianToDegree(const double degree) const;
public:
struct _RouteSummary {
struct RouteSummary {
std::string lengthString;
std::string durationString;
unsigned startName;
unsigned destName;
_RouteSummary() : lengthString("0"), durationString("0"), startName(0), destName(0) {}
void BuildDurationAndLengthStrings(const double distance, const unsigned time) {
RouteSummary() :
lengthString("0"),
durationString("0"),
startName(0),
destName(0)
{}
void BuildDurationAndLengthStrings(
const double distance,
const unsigned time
) {
//compute distance/duration for route summary
std::ostringstream s;
s << round(distance);
lengthString = s.str();
int travelTime = time/10 + 1;
s.str("");
s << travelTime;
durationString = s.str();
intToString(round(distance), lengthString);
int travel_time = round(time/10.);
intToString(std::max(travel_time, 1), durationString);
}
} summary;
@@ -69,15 +82,127 @@ public:
std::vector <SegmentInformation> pathDescription;
DescriptionFactory();
virtual ~DescriptionFactory();
double GetBearing(const _Coordinate& C, const _Coordinate& B) const;
void AppendEncodedPolylineString(std::string &output);
void AppendUnencodedPolylineString(std::string &output);
void AppendSegment(const _Coordinate & coordinate, const _PathData & data);
double GetBearing(const FixedPointCoordinate& C, const FixedPointCoordinate& B) const;
void AppendEncodedPolylineString(std::vector<std::string> &output) const;
void AppendUnencodedPolylineString(std::vector<std::string> &output) const;
void AppendSegment(const FixedPointCoordinate & coordinate, const PathData & data);
void BuildRouteSummary(const double distance, const unsigned time);
void SetStartSegment(const PhantomNode & startPhantom);
void SetEndSegment(const PhantomNode & startPhantom);
void AppendEncodedPolylineString(std::string & output, bool isEncoded);
void Run(const SearchEngineT &sEngine, const unsigned zoomLevel);
void SetStartSegment(const PhantomNode & start_phantom, const bool source_traversed_in_reverse);
void SetEndSegment(const PhantomNode & start_phantom, const bool target_traversed_in_reverse);
void AppendEncodedPolylineString(
const bool return_encoded,
std::vector<std::string> & output
);
template<class DataFacadeT>
void Run(
const DataFacadeT * facade,
const unsigned zoomLevel
) {
if( pathDescription.empty() ) {
return;
}
/** 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_ */
+84 -43
View File
@@ -1,65 +1,106 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GPX_DESCRIPTOR_H_
#define GPX_DESCRIPTOR_H_
#include <boost/foreach.hpp>
#include "BaseDescriptor.h"
template<class SearchEngineT>
class GPXDescriptor : public BaseDescriptor<SearchEngineT>{
#include <boost/foreach.hpp>
template<class DataFacadeT>
class GPXDescriptor : public BaseDescriptor<DataFacadeT> {
private:
_DescriptorConfig config;
_Coordinate current;
DescriptorConfig config;
FixedPointCoordinate current;
std::string tmp;
public:
void SetConfig(const _DescriptorConfig& c) { config = c; }
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) {
reply.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
reply.content += "<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" xmlns=\"http://www.topografix.com/GPX/1/1\" "
void SetConfig(const DescriptorConfig & c) { config = c; }
//TODO: reorder parameters
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\" "
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd"
"\">";
reply.content += "<rte>";
if(rawRoute.lengthOfShortestPath != INT_MAX && rawRoute.computedShortestPath.size()) {
convertInternalLatLonToString(phantomNodes.startPhantom.location.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(phantomNodes.startPhantom.location.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
"\">");
reply.content.push_back(
"<metadata><copyright author=\"Project OSRM\"><license>Data (c)"
" OpenStreetMap contributors (ODbL)</license></copyright>"
"</metadata>");
reply.content.push_back("<rte>");
bool found_route = (raw_route.lengthOfShortestPath != INT_MAX) &&
(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(_PathData pathData, rawRoute.computedShortestPath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
for(unsigned i=0; i < raw_route.unpacked_path_segments.size(); ++i){
BOOST_FOREACH(
const PathData & pathData,
raw_route.unpacked_path_segments[i]
) {
current = facade->GetCoordinateOfNode(pathData.node);
convertInternalLatLonToString(current.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(current.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
FixedPointCoordinate::convertInternalLatLonToString(current.lat, tmp);
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
FixedPointCoordinate::convertInternalLatLonToString(current.lon, tmp);
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
}
}
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
// Add the via point or the end coordinate
FixedPointCoordinate::convertInternalLatLonToString(
phantom_node_list.target_phantom.location.lat,
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_
+436 -285
View File
@@ -1,31 +1,33 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JSON_DESCRIPTOR_H_
#define JSON_DESCRIPTOR_H_
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/bind.hpp>
#include "BaseDescriptor.h"
#include "DescriptionFactory.h"
#include "../Algorithms/ObjectToBase64.h"
@@ -34,28 +36,41 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Util/Azimuth.h"
#include "../Util/StringUtil.h"
template<class SearchEngineT>
class JSONDescriptor : public BaseDescriptor<SearchEngineT>{
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <algorithm>
template<class DataFacadeT>
class JSONDescriptor : public BaseDescriptor<DataFacadeT> {
private:
_DescriptorConfig config;
DescriptionFactory descriptionFactory;
DescriptionFactory alternateDescriptionFactory;
_Coordinate current;
unsigned numberOfEnteredRestrictedAreas;
struct {
int startIndex;
int nameID;
int leaveAtExit;
} roundAbout;
// TODO: initalize in c'tor
DataFacadeT * facade;
DescriptorConfig config;
DescriptionFactory description_factory;
DescriptionFactory alternate_descriptionFactory;
FixedPointCoordinate current;
unsigned entered_restricted_area_count;
struct RoundAbout{
RoundAbout() :
start_index(INT_MAX),
name_id(INT_MAX),
leave_at_exit(INT_MAX)
{}
int start_index;
int name_id;
int leave_at_exit;
} round_about;
struct Segment {
Segment() : nameID(-1), length(-1), position(-1) {}
Segment(int n, int l, int p) : nameID(n), length(l), position(p) {}
int nameID;
Segment() : name_id(-1), length(-1), position(-1) {}
Segment(int n, int l, int p) : name_id(n), length(l), position(p) {}
int name_id;
int length;
int position;
};
std::vector<Segment> shortestSegments, alternativeSegments;
std::vector<Segment> shortest_path_segments, alternative_path_segments;
std::vector<unsigned> shortest_leg_end_indices, alternative_leg_end_indices;
struct RouteNames {
std::string shortestPathName1;
@@ -65,220 +80,336 @@ private:
};
public:
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {}
void SetConfig(const _DescriptorConfig & c) { config = c; }
JSONDescriptor() :
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, SearchEngineT &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) {
descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
reply.content += "0,"
"\"status_message\": \"Found route between points\",";
void Run(
const RawRouteData & raw_route,
const PhantomNodes & phantom_nodes,
// 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
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedShortestPath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
descriptionFactory.AppendSegment(current, pathData );
}
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
} else {
if (INVALID_EDGE_WEIGHT == raw_route.lengthOfShortestPath)
{
//We do not need to do much, if there is no route ;-)
reply.content += "207,"
"\"status_message\": \"Cannot find route between points\",";
reply.content.push_back(
"207,\"status_message\": \"Cannot find route between points\"}"
);
return;
}
descriptionFactory.Run(sEngine, config.z);
reply.content += "\"route_geometry\": ";
if(config.geometry) {
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
} else {
reply.content += "[]";
}
SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.lengthOfShortestPath;
reply.content += ","
"\"route_instructions\": [";
numberOfEnteredRestrictedAreas = 0;
if(config.instructions) {
BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, sEngine, shortestSegments);
} else {
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
//check if first segment is non-zero
std::string road_name;
road_name = facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id);
// for each unpacked segment add the leg to the description
BOOST_ASSERT( raw_route.unpacked_path_segments.size() == raw_route.segmentEndCoordinates.size() );
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
{
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\":";
reply.content += "{";
reply.content += "\"total_distance\":";
reply.content += descriptionFactory.summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += descriptionFactory.summary.durationString;
reply.content += ","
"\"start_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
reply.content += "\","
"\"end_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
reply.content += "\"";
reply.content += "}";
reply.content +=",";
//check if last segment is non-zero
road_name = facade->GetEscapedNameForNameID(phantom_nodes.target_phantom.name_id);
description_factory.SetStartSegment(phantom_nodes.source_phantom, raw_route.source_traversed_in_reverse);
reply.content.push_back("0,"
"\"status_message\": \"Found route between points\",");
BOOST_ASSERT( raw_route.unpacked_path_segments.size() == raw_route.segmentEndCoordinates.size() );
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
{
const int added_segments = DescribeLeg(
raw_route.unpacked_path_segments[i],
raw_route.segmentEndCoordinates[i]
);
BOOST_ASSERT( 0 < added_segments );
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
if(rawRoute.lengthOfAlternativePath != INT_MAX) {
alternateDescriptionFactory.SetStartSegment(phantomNodes.startPhantom);
if(raw_route.lengthOfAlternativePath != INVALID_EDGE_WEIGHT)
{
alternate_descriptionFactory.SetStartSegment(phantom_nodes.source_phantom, raw_route.alt_source_traversed_in_reverse);
//Get all the coordinates for the computed route
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedAlternativePath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
alternateDescriptionFactory.AppendSegment(current, pathData );
BOOST_FOREACH(const PathData & path_data, raw_route.unpacked_alternative) {
current = facade->GetCoordinateOfNode(path_data.node);
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
reply.content += "\"alternative_geometries\": [";
if(config.geometry && INT_MAX != rawRoute.lengthOfAlternativePath) {
// //give an array of alternative routes
reply.content.push_back("\"alternative_geometries\": [");
if(config.geometry && INT_MAX != raw_route.lengthOfAlternativePath) {
//Generate the linestrings for each alternative
alternateDescriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
alternate_descriptionFactory.AppendEncodedPolylineString(
config.encode_geometry,
reply.content
);
}
reply.content += "],";
reply.content += "\"alternative_instructions\":[";
numberOfEnteredRestrictedAreas = 0;
if(INT_MAX != rawRoute.lengthOfAlternativePath) {
reply.content += "[";
reply.content.push_back("],");
reply.content.push_back("\"alternative_instructions\":[");
if(INT_MAX != raw_route.lengthOfAlternativePath) {
reply.content.push_back("[");
//Generate instructions for each alternative
if(config.instructions) {
BuildTextualDescription(alternateDescriptionFactory, reply, rawRoute.lengthOfAlternativePath, sEngine, alternativeSegments);
} else {
BOOST_FOREACH(const SegmentInformation & segment, alternateDescriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
}
BuildTextualDescription(
alternate_descriptionFactory,
reply,
raw_route.lengthOfAlternativePath,
facade,
alternative_path_segments
);
}
reply.content += "]";
reply.content.push_back("]");
}
reply.content += "],";
reply.content += "\"alternative_summaries\":[";
if(INT_MAX != rawRoute.lengthOfAlternativePath) {
reply.content.push_back("],");
reply.content.push_back("\"alternative_summaries\":[");
if(INT_MAX != raw_route.lengthOfAlternativePath) {
//Generate route summary (length, duration) for each alternative
alternateDescriptionFactory.BuildRouteSummary(alternateDescriptionFactory.entireLength, rawRoute.lengthOfAlternativePath - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenalty));
reply.content += "{";
reply.content += "\"total_distance\":";
reply.content += alternateDescriptionFactory.summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += alternateDescriptionFactory.summary.durationString;
reply.content += ","
"\"start_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.startName);
reply.content += "\","
"\"end_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
reply.content += "\"";
reply.content += "}";
alternate_descriptionFactory.BuildRouteSummary(
alternate_descriptionFactory.entireLength,
raw_route.lengthOfAlternativePath
);
reply.content.push_back("{");
reply.content.push_back("\"total_distance\":");
reply.content.push_back(
alternate_descriptionFactory.summary.lengthString
);
reply.content.push_back(","
"\"total_time\":");
reply.content.push_back(
alternate_descriptionFactory.summary.durationString
);
reply.content.push_back(","
"\"start_point\":\"");
reply.content.push_back(
facade->GetEscapedNameForNameID(
description_factory.summary.startName
)
);
reply.content.push_back("\","
"\"end_point\":\"");
reply.content.push_back(facade->GetEscapedNameForNameID(description_factory.summary.destName));
reply.content.push_back("\"");
reply.content.push_back("}");
}
reply.content += "],";
reply.content.push_back("],");
//Get Names for both routes
// //Get Names for both routes
RouteNames routeNames;
GetRouteNames(shortestSegments, alternativeSegments, sEngine, routeNames);
GetRouteNames(shortest_path_segments, alternative_path_segments, facade, routeNames);
reply.content += "\"route_name\":[\"";
reply.content += routeNames.shortestPathName1;
reply.content += "\",\"";
reply.content += routeNames.shortestPathName2;
reply.content += "\"],"
"\"alternative_names\":[";
reply.content += "[\"";
reply.content += routeNames.alternativePathName1;
reply.content += "\",\"";
reply.content += routeNames.alternativePathName2;
reply.content += "\"]";
reply.content += "],";
reply.content.push_back("\"route_name\":[\"");
reply.content.push_back(routeNames.shortestPathName1);
reply.content.push_back("\",\"");
reply.content.push_back(routeNames.shortestPathName2);
reply.content.push_back("\"],"
"\"alternative_names\":[");
reply.content.push_back("[\"");
reply.content.push_back(routeNames.alternativePathName1);
reply.content.push_back("\",\"");
reply.content.push_back(routeNames.alternativePathName2);
reply.content.push_back("\"]");
reply.content.push_back("],");
//list all viapoints so that the client may display it
reply.content += "\"via_points\":[";
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.push_back("\"via_points\":[");
reply.content += tmp;
reply.content += "],";
}
reply.content += "[";
if(rawRoute.segmentEndCoordinates.back().startPhantom.location.isSet())
convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates.back().targetPhantom.location, tmp);
else
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates.back(), tmp);
reply.content += tmp;
reply.content += "]";
BOOST_ASSERT( !raw_route.segmentEndCoordinates.empty() );
std::string tmp;
FixedPointCoordinate::convertInternalReversedCoordinateToString(
raw_route.segmentEndCoordinates.front().source_phantom.location,
tmp
);
reply.content.push_back("[");
reply.content.push_back(tmp);
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 += "\"checksum\":";
intToString(rawRoute.checkSum, tmp);
reply.content += tmp;
reply.content += ", \"locations\": [";
reply.content.push_back("],");
reply.content.push_back("\"via_indices\":[");
BOOST_FOREACH(const unsigned index, shortest_leg_end_indices) {
tmp.clear();
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;
for(unsigned i = 0; i < rawRoute.segmentEndCoordinates.size(); ++i) {
reply.content += "\"";
EncodeObjectToBase64(rawRoute.segmentEndCoordinates[i].startPhantom, hint);
reply.content += hint;
reply.content += "\", ";
for(unsigned i = 0; i < raw_route.segmentEndCoordinates.size(); ++i) {
reply.content.push_back("\"");
EncodeObjectToBase64(raw_route.segmentEndCoordinates[i].source_phantom, hint);
reply.content.push_back(hint);
reply.content.push_back("\", ");
}
EncodeObjectToBase64(rawRoute.segmentEndCoordinates.back().targetPhantom, hint);
reply.content += "\"";
reply.content += hint;
reply.content += "\"]";
reply.content += "},";
reply.content += "\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.3)\"";
reply.content += "}";
EncodeObjectToBase64(raw_route.segmentEndCoordinates.back().target_phantom, hint);
reply.content.push_back("\"");
reply.content.push_back(hint);
reply.content.push_back("\"]");
reply.content.push_back("}}");
}
void GetRouteNames(std::vector<Segment> & shortestSegments, std::vector<Segment> & alternativeSegments, SearchEngineT &sEngine, RouteNames & routeNames) {
/*** extract names for both alternatives ***/
// construct routes names
void GetRouteNames(
std::vector<Segment> & shortest_path_segments,
std::vector<Segment> & alternative_path_segments,
const DataFacadeT * facade,
RouteNames & routeNames
) {
Segment shortestSegment1, shortestSegment2;
Segment alternativeSegment1, alternativeSegment2;
if(0 < shortestSegments.size()) {
sort(shortestSegments.begin(), shortestSegments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
shortestSegment1 = shortestSegments[0];
if(0 < alternativeSegments.size()) {
sort(alternativeSegments.begin(), alternativeSegments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
alternativeSegment1 = alternativeSegments[0];
if(0 < shortest_path_segments.size()) {
sort(shortest_path_segments.begin(), shortest_path_segments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
shortestSegment1 = shortest_path_segments[0];
if(0 < alternative_path_segments.size()) {
sort(alternative_path_segments.begin(), alternative_path_segments.end(), boost::bind(&Segment::length, _1) > boost::bind(&Segment::length, _2) );
alternativeSegment1 = alternative_path_segments[0];
}
std::vector<Segment> shortestDifference(shortestSegments.size());
std::vector<Segment> alternativeDifference(alternativeSegments.size());
std::set_difference(shortestSegments.begin(), shortestSegments.end(), alternativeSegments.begin(), alternativeSegments.end(), shortestDifference.begin(), boost::bind(&Segment::nameID, _1) < boost::bind(&Segment::nameID, _2) );
if(0 < shortestDifference.size() ) {
unsigned i = 0;
while( i < shortestDifference.size() && shortestDifference[i].nameID == shortestSegments[0].nameID) {
std::vector<Segment> shortestDifference(shortest_path_segments.size());
std::vector<Segment> alternativeDifference(alternative_path_segments.size());
std::set_difference(shortest_path_segments.begin(), shortest_path_segments.end(), alternative_path_segments.begin(), alternative_path_segments.end(), shortestDifference.begin(), boost::bind(&Segment::name_id, _1) < boost::bind(&Segment::name_id, _2) );
int size_of_difference = shortestDifference.size();
if(0 < size_of_difference ) {
int i = 0;
while( i < size_of_difference && shortestDifference[i].name_id == shortest_path_segments[0].name_id) {
++i;
}
if(i < shortestDifference.size()) {
if(i < size_of_difference ) {
shortestSegment2 = shortestDifference[i];
}
}
std::set_difference(alternativeSegments.begin(), alternativeSegments.end(), shortestSegments.begin(), shortestSegments.end(), alternativeDifference.begin(), boost::bind(&Segment::nameID, _1) < boost::bind(&Segment::nameID, _2) );
if(0 < alternativeDifference.size() ) {
unsigned i = 0;
while( i < alternativeDifference.size() && alternativeDifference[i].nameID == alternativeSegments[0].nameID) {
std::set_difference(alternative_path_segments.begin(), alternative_path_segments.end(), shortest_path_segments.begin(), shortest_path_segments.end(), alternativeDifference.begin(), boost::bind(&Segment::name_id, _1) < boost::bind(&Segment::name_id, _2) );
size_of_difference = alternativeDifference.size();
if(0 < size_of_difference ) {
int i = 0;
while( i < size_of_difference && alternativeDifference[i].name_id == alternative_path_segments[0].name_id) {
++i;
}
if(i < alternativeDifference.size()) {
if(i < size_of_difference ) {
alternativeSegment2 = alternativeDifference[i];
}
}
@@ -288,104 +419,124 @@ public:
if(alternativeSegment1.position > alternativeSegment2.position)
std::swap(alternativeSegment1, alternativeSegment2);
routeNames.shortestPathName1 = sEngine.GetEscapedNameForNameID(shortestSegment1.nameID);
routeNames.shortestPathName2 = sEngine.GetEscapedNameForNameID(shortestSegment2.nameID);
routeNames.shortestPathName1 = facade->GetEscapedNameForNameID(
shortestSegment1.name_id
);
routeNames.shortestPathName2 = facade->GetEscapedNameForNameID(
shortestSegment2.name_id
);
routeNames.alternativePathName1 = sEngine.GetEscapedNameForNameID(alternativeSegment1.nameID);
routeNames.alternativePathName2 += sEngine.GetEscapedNameForNameID(alternativeSegment2.nameID);
routeNames.alternativePathName1 = facade->GetEscapedNameForNameID(
alternativeSegment1.name_id
);
routeNames.alternativePathName2 = facade->GetEscapedNameForNameID(
alternativeSegment2.name_id
);
}
}
inline void WriteHeaderToOutput(std::string & output) {
output += "{"
"\"version\": 0.3,"
"\"status\":";
}
inline void BuildTextualDescription(DescriptionFactory & descriptionFactory, http::Reply & reply, const int lengthOfRoute, const SearchEngineT &sEngine, std::vector<Segment> & segmentVector) {
//TODO: reorder parameters
inline void BuildTextualDescription(
DescriptionFactory & description_factory,
http::Reply & reply,
const int route_length,
const DataFacadeT * facade,
std::vector<Segment> & route_segments_list
) {
//Segment information has following format:
//["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
//Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5]
//See also: http://developers.cloudmade.com/wiki/navengine/JSON_format
unsigned prefixSumOfNecessarySegments = 0;
roundAbout.leaveAtExit = 0;
roundAbout.nameID = 0;
std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction;
unsigned necessary_segments_running_index = 0;
round_about.leave_at_exit = 0;
round_about.name_id = 0;
std::string temp_dist, temp_length, temp_duration, temp_bearing, temp_instruction;
//Fetch data from Factory and generate a string from it.
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) {
if(TurnInstructions.EnterRoundAbout == currentInstruction) {
roundAbout.nameID = segment.nameID;
roundAbout.startIndex = prefixSumOfNecessarySegments;
} else {
if(0 != prefixSumOfNecessarySegments){
reply.content += ",";
}
reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == currentInstruction) {
intToString(TurnInstructions.EnterRoundAbout, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "-";
intToString(roundAbout.leaveAtExit+1, tmpInstruction);
reply.content += tmpInstruction;
roundAbout.leaveAtExit = 0;
} else {
intToString(currentInstruction, tmpInstruction);
reply.content += tmpInstruction;
}
reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
reply.content += "\",";
intToString(segment.length, tmpDist);
reply.content += tmpDist;
reply.content += ",";
intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content += tmpLength;
reply.content += ",";
intToString(segment.duration/10, tmpDuration);
reply.content += tmpDuration;
reply.content += ",\"";
intToString(segment.length, tmpLength);
reply.content += tmpLength;
reply.content += "m\",\"";
reply.content += Azimuth::Get(segment.bearing);
reply.content += "\",";
intToString(round(segment.bearing), tmpBearing);
reply.content += tmpBearing;
reply.content += "]";
segmentVector.push_back( Segment(segment.nameID, segment.length, segmentVector.size() ));
BOOST_FOREACH(const SegmentInformation & segment, description_factory.pathDescription) {
TurnInstruction current_instruction = segment.turn_instruction & TurnInstructionsClass::InverseAccessRestrictionFlag;
entered_restricted_area_count += (current_instruction != segment.turn_instruction);
if (TurnInstructionsClass::TurnIsNecessary( current_instruction) )
{
if (TurnInstructionsClass::EnterRoundAbout == current_instruction)
{
round_about.name_id = segment.name_id;
round_about.start_index = necessary_segments_running_index;
}
} else if(TurnInstructions.StayOnRoundAbout == currentInstruction) {
++roundAbout.leaveAtExit;
else
{
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)
++prefixSumOfNecessarySegments;
++necessary_segments_running_index;
}
if(INT_MAX != lengthOfRoute) {
reply.content += ",[\"";
intToString(TurnInstructions.ReachedYourDestination, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "\",\"";
reply.content += "\",";
reply.content += "0";
reply.content += ",";
intToString(prefixSumOfNecessarySegments-1, tmpLength);
reply.content += tmpLength;
reply.content += ",";
reply.content += "0";
reply.content += ",\"";
reply.content += "\",\"";
reply.content += Azimuth::Get(0.0);
reply.content += "\",";
reply.content += "0.0";
reply.content += "]";
if(INT_MAX != route_length) {
reply.content.push_back(",[\"");
intToString(TurnInstructionsClass::ReachedYourDestination, temp_instruction);
reply.content.push_back(temp_instruction);
reply.content.push_back("\",\"");
reply.content.push_back("\",");
reply.content.push_back("0");
reply.content.push_back(",");
intToString(necessary_segments_running_index-1, temp_length);
reply.content.push_back(temp_length);
reply.content.push_back(",");
reply.content.push_back("0");
reply.content.push_back(",\"");
reply.content.push_back("\",\"");
reply.content.push_back(Azimuth::Get(0.0));
reply.content.push_back("\",");
reply.content.push_back("0.0");
reply.content.push_back("]");
}
}
};
#endif /* JSON_DESCRIPTOR_H_ */
Submodule Docs deleted from f7150057d5
+3
View File
@@ -0,0 +1,3 @@
The javascript based web client is a seperate project available at
https://github.com/DennisSchiefer/Project-OSRM-Web
+139
View File
@@ -0,0 +1,139 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BaseParser.h"
#include "ExtractionWay.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/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();
ReadRestrictionExceptions();
}
void BaseParser::ReadUseRestrictionsSetting() {
if( 0 != luaL_dostring( lua_state, "return use_turn_restrictions\n") ) {
throw OSRMException("ERROR occured in scripting block");
}
if( lua_isboolean( lua_state, -1) ) {
use_turn_restrictions = lua_toboolean(lua_state, -1);
}
if( use_turn_restrictions ) {
SimpleLogger().Write() << "Using turn restrictions";
} else {
SimpleLogger().Write() << "Ignoring turn restrictions";
}
}
void BaseParser::ReadRestrictionExceptions() {
if(lua_function_exists(lua_state, "get_exceptions" )) {
//get list of turn restriction exceptions
luabind::call_function<void>(
lua_state,
"get_exceptions",
boost::ref(restriction_exceptions)
);
const unsigned exception_count = restriction_exceptions.size();
SimpleLogger().Write() <<
"Found " << exception_count << " exceptions to turn restrictions:";
BOOST_FOREACH(const std::string & str, restriction_exceptions) {
SimpleLogger().Write() << " " << str;
}
} else {
SimpleLogger().Write() << "Found no exceptions to turn restrictions";
}
}
void BaseParser::report_errors(lua_State *L, const int status) const {
if( 0!=status ) {
std::cerr << "-- " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1); // remove error message
}
}
void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* local_lua_state) {
luabind::call_function<void>(
local_lua_state,
"node_function",
boost::ref(n)
);
}
void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* local_lua_state) {
luabind::call_function<void>(
local_lua_state,
"way_function",
boost::ref(w)
);
}
bool BaseParser::ShouldIgnoreRestriction(
const std::string & except_tag_string
) const {
//should this restriction be ignored? yes if there's an overlap between:
// a) the list of modes in the except tag of the restriction
// (except_tag_string), eg: except=bus;bicycle
// b) the lua profile defines a hierachy of modes,
// eg: [access, vehicle, bicycle]
if( except_tag_string.empty() ) {
return false;
}
//Be warned, this is quadratic work here, but we assume that
//only a few exceptions are actually defined.
std::vector<std::string> exceptions;
boost::algorithm::split_regex(exceptions, except_tag_string, boost::regex("[;][ ]*"));
BOOST_FOREACH(std::string& current_string, exceptions) {
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 false;
}
+54 -30
View File
@@ -1,50 +1,74 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BASEPARSER_H_
#define BASEPARSER_H_
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include "ScriptingEnvironment.h"
#include <boost/noncopyable.hpp>
#include <string>
#include <vector>
template<class ExternalMemoryT, typename NodeT, typename RestrictionT, typename WayT>
class BaseParser {
class ExtractorCallbacks;
class ScriptingEnvironment;
struct ExtractionWay;
struct ImportNode;
class BaseParser : boost::noncopyable {
public:
BaseParser(
ExtractorCallbacks * extractor_callbacks,
ScriptingEnvironment & scripting_environment
);
virtual ~BaseParser() {}
virtual bool Init() = 0;
virtual void RegisterCallbacks(ExternalMemoryT * externalMemory) = 0;
virtual void RegisterScriptingEnvironment(ScriptingEnvironment & _se) = 0;
virtual bool ReadHeader() = 0;
virtual bool Parse() = 0;
void report_errors(lua_State *L, int status) {
if ( status!=0 ) {
std::cerr << "-- " << lua_tostring(L, -1) << std::endl;
lua_pop(L, 1); // remove error message
}
}
virtual void ParseNodeInLua(ImportNode & n, lua_State* thread_lua_state);
virtual void ParseWayInLua(ExtractionWay & n, lua_State* thread_lua_state);
virtual void report_errors(lua_State * lua_state, const int status) const;
protected:
virtual void ReadUseRestrictionsSetting();
virtual void ReadRestrictionExceptions();
virtual bool ShouldIgnoreRestriction(
const std::string & except_tag_string
) const;
ExtractorCallbacks * extractor_callbacks;
lua_State * lua_state;
ScriptingEnvironment & scripting_environment;
std::vector<std::string> restriction_exceptions;
bool use_turn_restrictions;
};
#endif /* BASEPARSER_H_ */
+371 -213
View File
@@ -1,305 +1,463 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ExtractionContainers.h"
#include "ExtractionWay.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
void ExtractionContainers::PrepareData(const std::string & outputFileName, 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 {
unsigned usedNodeCounter = 0;
unsigned usedEdgeCounter = 0;
unsigned number_of_used_nodes = 0;
unsigned number_of_used_edges = 0;
double time = get_timestamp();
boost::uint64_t memory_to_use = static_cast<boost::uint64_t>(amountOfRAM) * 1024 * 1024 * 1024;
cout << "[extractor] Sorting used nodes ... " << flush;
stxxl::sort(usedNodeIDs.begin(), usedNodeIDs.end(), Cmp(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "[extractor] Sorting used nodes ... " << std::flush;
stxxl::sort(
used_node_id_list.begin(),
used_node_id_list.end(),
Cmp(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
cout << "[extractor] Erasing duplicate nodes ... " << flush;
stxxl::vector<NodeID>::iterator NewEnd = unique ( usedNodeIDs.begin(),usedNodeIDs.end() ) ;
usedNodeIDs.resize ( NewEnd - usedNodeIDs.begin() );
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "[extractor] Erasing duplicate nodes ... " << std::flush;
stxxl::vector<NodeID>::iterator NewEnd = std::unique ( used_node_id_list.begin(),used_node_id_list.end() ) ;
used_node_id_list.resize ( NewEnd - used_node_id_list.begin() );
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
cout << "[extractor] Sorting all nodes ... " << flush;
stxxl::sort(allNodes.begin(), allNodes.end(), CmpNodeByID(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "[extractor] Sorting all nodes ... " << std::flush;
stxxl::sort(
all_nodes_list.begin(),
all_nodes_list.end(),
CmpNodeByID(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
cout << "[extractor] Sorting used ways ... " << flush;
stxxl::sort(wayStartEndVector.begin(), wayStartEndVector.end(), CmpWayByID(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "[extractor] Sorting used ways ... " << std::flush;
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;
cout << "[extractor] Sorting restrctns. by from... " << flush;
stxxl::sort(restrictionsVector.begin(), restrictionsVector.end(), CmpRestrictionContainerByFrom(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "[extractor] Sorting restrctns. by from... " << std::flush;
stxxl::sort(
restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByFrom(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
cout << "[extractor] Fixing restriction starts ... " << flush;
STXXLRestrictionsVector::iterator restrictionsIT = restrictionsVector.begin();
STXXLWayIDStartEndVector::iterator wayStartAndEndEdgeIT = wayStartEndVector.begin();
std::cout << "[extractor] Fixing restriction starts ... " << std::flush;
STXXLRestrictionsVector::iterator restrictions_iterator = restrictions_list.begin();
STXXLWayIDStartEndVector::iterator way_start_and_end_iterator = way_start_end_id_list.begin();
while(wayStartAndEndEdgeIT != wayStartEndVector.end() && restrictionsIT != restrictionsVector.end()) {
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->fromWay){
++wayStartAndEndEdgeIT;
while(
way_start_and_end_iterator != way_start_end_id_list.end() &&
restrictions_iterator != restrictions_list.end()
) {
if(way_start_and_end_iterator->wayID < restrictions_iterator->fromWay){
++way_start_and_end_iterator;
continue;
}
if(wayStartAndEndEdgeIT->wayID > restrictionsIT->fromWay) {
++restrictionsIT;
if(way_start_and_end_iterator->wayID > restrictions_iterator->fromWay) {
++restrictions_iterator;
continue;
}
assert(wayStartAndEndEdgeIT->wayID == restrictionsIT->fromWay);
NodeID viaNode = restrictionsIT->restriction.viaNode;
if(wayStartAndEndEdgeIT->firstStart == viaNode) {
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->firstTarget;
} else if(wayStartAndEndEdgeIT->firstTarget == viaNode) {
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->firstStart;
} else if(wayStartAndEndEdgeIT->lastStart == viaNode) {
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->lastTarget;
} else if(wayStartAndEndEdgeIT->lastTarget == viaNode) {
restrictionsIT->restriction.fromNode = wayStartAndEndEdgeIT->lastStart;
BOOST_ASSERT(way_start_and_end_iterator->wayID == restrictions_iterator->fromWay);
NodeID via_node_id = restrictions_iterator->restriction.viaNode;
if(way_start_and_end_iterator->firstStart == via_node_id) {
restrictions_iterator->restriction.fromNode = way_start_and_end_iterator->firstTarget;
} else if(way_start_and_end_iterator->firstTarget == via_node_id) {
restrictions_iterator->restriction.fromNode = way_start_and_end_iterator->firstStart;
} else if(way_start_and_end_iterator->lastStart == via_node_id) {
restrictions_iterator->restriction.fromNode = way_start_and_end_iterator->lastTarget;
} else if(way_start_and_end_iterator->lastTarget == via_node_id) {
restrictions_iterator->restriction.fromNode = way_start_and_end_iterator->lastStart;
}
++restrictionsIT;
++restrictions_iterator;
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
cout << "[extractor] Sorting restrctns. by to ... " << flush;
stxxl::sort(restrictionsVector.begin(), restrictionsVector.end(), CmpRestrictionContainerByTo(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "[extractor] Sorting restrctns. by to ... " << std::flush;
stxxl::sort(
restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByTo(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
unsigned usableRestrictionsCounter(0);
cout << "[extractor] Fixing restriction ends ... " << flush;
restrictionsIT = restrictionsVector.begin();
wayStartAndEndEdgeIT = wayStartEndVector.begin();
while(wayStartAndEndEdgeIT != wayStartEndVector.end() && restrictionsIT != restrictionsVector.end()) {
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->toWay){
++wayStartAndEndEdgeIT;
std::cout << "[extractor] Fixing restriction ends ... " << std::flush;
restrictions_iterator = restrictions_list.begin();
way_start_and_end_iterator = way_start_end_id_list.begin();
while(
way_start_and_end_iterator != way_start_end_id_list.end() &&
restrictions_iterator != restrictions_list.end()
) {
if(way_start_and_end_iterator->wayID < restrictions_iterator->toWay){
++way_start_and_end_iterator;
continue;
}
if(wayStartAndEndEdgeIT->wayID > restrictionsIT->toWay) {
++restrictionsIT;
if(way_start_and_end_iterator->wayID > restrictions_iterator->toWay) {
++restrictions_iterator;
continue;
}
NodeID viaNode = restrictionsIT->restriction.viaNode;
if(wayStartAndEndEdgeIT->lastStart == viaNode) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->lastTarget;
} else if(wayStartAndEndEdgeIT->lastTarget == viaNode) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->lastStart;
} else if(wayStartAndEndEdgeIT->firstStart == viaNode) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstTarget;
} else if(wayStartAndEndEdgeIT->firstTarget == viaNode) {
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstStart;
NodeID via_node_id = restrictions_iterator->restriction.viaNode;
if(way_start_and_end_iterator->lastStart == via_node_id) {
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastTarget;
} else if(way_start_and_end_iterator->lastTarget == via_node_id) {
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastStart;
} else if(way_start_and_end_iterator->firstStart == via_node_id) {
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstTarget;
} else if(way_start_and_end_iterator->firstTarget == via_node_id) {
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstStart;
}
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
if(
UINT_MAX != restrictions_iterator->restriction.fromNode &&
UINT_MAX != restrictions_iterator->restriction.toNode
) {
++usableRestrictionsCounter;
}
++restrictionsIT;
++restrictions_iterator;
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
INFO("usable restrictions: " << usableRestrictionsCounter );
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
SimpleLogger().Write() << "usable restrictions: " << usableRestrictionsCounter;
//serialize restrictions
ofstream restrictionsOutstream;
restrictionsOutstream.open(restrictionsFileName.c_str(), ios::binary);
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned));
for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) {
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(_Restriction));
std::ofstream restrictions_out_stream;
restrictions_out_stream.open(restrictions_file_name.c_str(), std::ios::binary);
restrictions_out_stream.write((char*)&uuid, sizeof(UUID));
restrictions_out_stream.write(
(char*)&usableRestrictionsCounter,
sizeof(unsigned)
);
for(
restrictions_iterator = restrictions_list.begin();
restrictions_iterator != restrictions_list.end();
++restrictions_iterator
) {
if(
UINT_MAX != restrictions_iterator->restriction.fromNode &&
UINT_MAX != restrictions_iterator->restriction.toNode
) {
restrictions_out_stream.write(
(char *)&(restrictions_iterator->restriction),
sizeof(TurnRestriction)
);
}
}
restrictionsOutstream.close();
restrictions_out_stream.close();
ofstream fout;
fout.open(outputFileName.c_str(), ios::binary);
fout.write((char*)&usedNodeCounter, sizeof(unsigned));
std::ofstream file_out_stream;
file_out_stream.open(output_file_name.c_str(), std::ios::binary);
file_out_stream.write((char*)&uuid, sizeof(UUID));
file_out_stream.write((char*)&number_of_used_nodes, sizeof(unsigned));
time = get_timestamp();
cout << "[extractor] Confirming/Writing used nodes ... " << flush;
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
STXXLNodeVector::iterator nodesIT = allNodes.begin();
STXXLNodeIDVector::iterator usedNodeIDsIT = usedNodeIDs.begin();
while(usedNodeIDsIT != usedNodeIDs.end() && nodesIT != allNodes.end()) {
if(*usedNodeIDsIT < nodesIT->id){
++usedNodeIDsIT;
//identify all used nodes by a merging step of two sorted lists
STXXLNodeVector::iterator node_iterator = all_nodes_list.begin();
STXXLNodeIDVector::iterator node_id_iterator = used_node_id_list.begin();
while(
node_id_iterator != used_node_id_list.end() &&
node_iterator != all_nodes_list.end()
) {
if(*node_id_iterator < node_iterator->id){
++node_id_iterator;
continue;
}
if(*usedNodeIDsIT > nodesIT->id) {
++nodesIT;
if(*node_id_iterator > node_iterator->id) {
++node_iterator;
continue;
}
if(*usedNodeIDsIT == nodesIT->id) {
fout.write((char*)&(*nodesIT), sizeof(_Node));
++usedNodeCounter;
++usedNodeIDsIT;
++nodesIT;
}
BOOST_ASSERT( *node_id_iterator == node_iterator->id);
file_out_stream.write(
(char*)&(*node_iterator),
sizeof(ExternalMemoryNode)
);
++number_of_used_nodes;
++node_id_iterator;
++node_iterator;
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
cout << "[extractor] setting number of nodes ... " << flush;
ios::pos_type positionInFile = fout.tellp();
fout.seekp(ios::beg);
fout.write((char*)&usedNodeCounter, sizeof(unsigned));
fout.seekp(positionInFile);
std::cout << "[extractor] setting number of nodes ... " << std::flush;
std::ios::pos_type previous_file_position = file_out_stream.tellp();
file_out_stream.seekp(std::ios::beg+sizeof(UUID));
file_out_stream.write((char*)&number_of_used_nodes, sizeof(unsigned));
file_out_stream.seekp(previous_file_position);
cout << "ok" << endl;
std::cout << "ok" << std::endl;
time = get_timestamp();
// Sort edges by start.
cout << "[extractor] Sorting edges by start ... " << flush;
stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByStartID(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "[extractor] Sorting edges by start ... " << std::flush;
stxxl::sort(
all_edges_list.begin(),
all_edges_list.end(),
CmpEdgeByStartID(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
cout << "[extractor] Setting start coords ... " << flush;
fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
std::cout << "[extractor] Setting start coords ... " << std::flush;
file_out_stream.write((char*)&number_of_used_edges, sizeof(unsigned));
// Traverse list of edges and nodes in parallel and set start coord
nodesIT = allNodes.begin();
STXXLEdgeVector::iterator edgeIT = allEdges.begin();
while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) {
if(edgeIT->start < nodesIT->id){
++edgeIT;
node_iterator = all_nodes_list.begin();
STXXLEdgeVector::iterator edge_iterator = all_edges_list.begin();
while(
edge_iterator != all_edges_list.end() &&
node_iterator != all_nodes_list.end()
) {
if(edge_iterator->start < node_iterator->id){
++edge_iterator;
continue;
}
if(edgeIT->start > nodesIT->id) {
nodesIT++;
if(edge_iterator->start > node_iterator->id) {
node_iterator++;
continue;
}
if(edgeIT->start == nodesIT->id) {
edgeIT->startCoord.lat = nodesIT->lat;
edgeIT->startCoord.lon = nodesIT->lon;
++edgeIT;
}
BOOST_ASSERT(edge_iterator->start == node_iterator->id);
edge_iterator->startCoord.lat = node_iterator->lat;
edge_iterator->startCoord.lon = node_iterator->lon;
++edge_iterator;
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
// Sort Edges by target
cout << "[extractor] Sorting edges by target ... " << flush;
stxxl::sort(allEdges.begin(), allEdges.end(), CmpEdgeByTargetID(), memory_to_use);
cout << "ok, after " << get_timestamp() - time << "s" << endl;
std::cout << "[extractor] Sorting edges by target ... " << std::flush;
stxxl::sort(
all_edges_list.begin(),
all_edges_list.end(),
CmpEdgeByTargetID(),
4294967296
);
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
time = get_timestamp();
cout << "[extractor] Setting target coords ... " << flush;
std::cout << "[extractor] Setting target coords ... " << std::flush;
// Traverse list of edges and nodes in parallel and set target coord
nodesIT = allNodes.begin();
edgeIT = allEdges.begin();
node_iterator = all_nodes_list.begin();
edge_iterator = all_edges_list.begin();
while(edgeIT != allEdges.end() && nodesIT != allNodes.end()) {
if(edgeIT->target < nodesIT->id){
++edgeIT;
while(
edge_iterator != all_edges_list.end() &&
node_iterator != all_nodes_list.end()
) {
if(edge_iterator->target < node_iterator->id){
++edge_iterator;
continue;
}
if(edgeIT->target > nodesIT->id) {
++nodesIT;
if(edge_iterator->target > node_iterator->id) {
++node_iterator;
continue;
}
if(edgeIT->target == nodesIT->id) {
if(edgeIT->startCoord.lat != INT_MIN && edgeIT->startCoord.lon != INT_MIN) {
edgeIT->targetCoord.lat = nodesIT->lat;
edgeIT->targetCoord.lon = nodesIT->lon;
BOOST_ASSERT(edge_iterator->target == node_iterator->id);
if(edge_iterator->startCoord.lat != INT_MIN && edge_iterator->startCoord.lon != INT_MIN) {
edge_iterator->targetCoord.lat = node_iterator->lat;
edge_iterator->targetCoord.lon = node_iterator->lon;
double distance = ApproximateDistance(edgeIT->startCoord.lat, edgeIT->startCoord.lon, nodesIT->lat, nodesIT->lon);
assert(edgeIT->speed != -1);
double weight = ( distance * 10. ) / (edgeIT->speed / 3.6);
int intWeight = std::max(1, (int)std::floor((edgeIT->isDurationSet ? edgeIT->speed : weight)+.5) );
int intDist = std::max(1, (int)distance);
short zero = 0;
short one = 1;
const double distance = FixedPointCoordinate::ApproximateDistance(
edge_iterator->startCoord.lat,
edge_iterator->startCoord.lon,
node_iterator->lat,
node_iterator->lon
);
fout.write((char*)&edgeIT->start, sizeof(unsigned));
fout.write((char*)&edgeIT->target, sizeof(unsigned));
fout.write((char*)&intDist, sizeof(int));
switch(edgeIT->direction) {
case _Way::notSure:
fout.write((char*)&zero, sizeof(short));
break;
case _Way::oneway:
fout.write((char*)&one, sizeof(short));
break;
case _Way::bidirectional:
fout.write((char*)&zero, sizeof(short));
BOOST_ASSERT(edge_iterator->speed != -1);
const double weight = ( distance * 10. ) / (edge_iterator->speed / 3.6);
int integer_weight = std::max( 1, (int)std::floor((edge_iterator->isDurationSet ? edge_iterator->speed : weight)+.5) );
int integer_distance = std::max( 1, (int)distance );
short zero = 0;
short one = 1;
break;
case _Way::opposite:
fout.write((char*)&one, sizeof(short));
break;
default:
cerr << "[error] edge with no direction: " << edgeIT->direction << endl;
assert(false);
break;
}
fout.write((char*)&intWeight, sizeof(int));
assert(edgeIT->type >= 0);
fout.write((char*)&edgeIT->type, sizeof(short));
fout.write((char*)&edgeIT->nameID, sizeof(unsigned));
fout.write((char*)&edgeIT->isRoundabout, sizeof(bool));
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool));
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool));
file_out_stream.write((char*)&edge_iterator->start, sizeof(unsigned));
file_out_stream.write((char*)&edge_iterator->target, sizeof(unsigned));
file_out_stream.write((char*)&integer_distance, sizeof(int));
switch(edge_iterator->direction) {
case ExtractionWay::notSure:
file_out_stream.write((char*)&zero, sizeof(short));
break;
case ExtractionWay::oneway:
file_out_stream.write((char*)&one, sizeof(short));
break;
case ExtractionWay::bidirectional:
file_out_stream.write((char*)&zero, sizeof(short));
break;
case ExtractionWay::opposite:
file_out_stream.write((char*)&one, sizeof(short));
break;
default:
throw OSRMException("edge has broken direction");
}
++usedEdgeCounter;
++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;
}
cout << "ok, after " << get_timestamp() - time << "s" << endl;
cout << "[extractor] setting number of edges ... " << flush;
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] setting number of edges ... " << std::flush;
fout.seekp(positionInFile);
fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
fout.close();
cout << "ok" << endl;
file_out_stream.seekp(previous_file_position);
file_out_stream.write((char*)&number_of_used_edges, sizeof(unsigned));
file_out_stream.close();
std::cout << "ok" << std::endl;
time = get_timestamp();
cout << "[extractor] writing street name index ... " << flush;
std::string nameOutFileName = (outputFileName + ".names");
ofstream nameOutFile(nameOutFileName.c_str(), ios::binary);
unsigned sizeOfNameIndex = nameVector.size();
nameOutFile.write((char *)&(sizeOfNameIndex), sizeof(unsigned));
BOOST_FOREACH(string str, nameVector) {
unsigned lengthOfRawString = strlen(str.c_str());
nameOutFile.write((char *)&(lengthOfRawString), sizeof(unsigned));
nameOutFile.write(str.c_str(), lengthOfRawString);
std::cout << "[extractor] writing street name index ... " << std::flush;
std::string name_file_streamName = (output_file_name + ".names");
boost::filesystem::ofstream name_file_stream(
name_file_streamName,
std::ios::binary
);
//write number of names
const unsigned number_of_names = name_list.size()+1;
name_file_stream.write((char *)&(number_of_names), sizeof(unsigned));
//compute total number of chars
unsigned total_number_of_chars = 0;
BOOST_FOREACH(const std::string & temp_string, name_list) {
total_number_of_chars += temp_string.length();
}
//write total number of chars
name_file_stream.write(
(char *)&(total_number_of_chars),
sizeof(unsigned)
);
//write prefixe sums
unsigned name_lengths_prefix_sum = 0;
BOOST_FOREACH(const std::string & temp_string, name_list) {
name_file_stream.write(
(char *)&(name_lengths_prefix_sum),
sizeof(unsigned)
);
name_lengths_prefix_sum += temp_string.length();
}
//duplicate on purpose!
name_file_stream.write(
(char *)&(name_lengths_prefix_sum),
sizeof(unsigned)
);
//write all chars consecutively
BOOST_FOREACH(const std::string & temp_string, name_list) {
const unsigned string_length = temp_string.length();
name_file_stream.write(temp_string.c_str(), string_length);
}
nameOutFile.close();
cout << "ok, after " << get_timestamp() - time << "s" << endl;
name_file_stream.close();
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
SimpleLogger().Write() << "Processed " <<
number_of_used_nodes << " nodes and " <<
number_of_used_edges << " edges";
// time = get_timestamp();
// cout << "[extractor] writing address list ... " << flush;
//
// adressFileName.append(".address");
// ofstream addressOutFile(adressFileName.c_str());
// for(STXXLAddressVector::iterator it = adressVector.begin(); it != adressVector.end(); it++) {
// addressOutFile << it->node.id << "|" << it->node.lat << "|" << it->node.lon << "|" << it->city << "|" << it->street << "|" << it->housenumber << "|" << it->state << "|" << it->country << "\n";
// }
// addressOutFile.close();
// cout << "ok, after " << get_timestamp() - time << "s" << endl;
INFO("Processed " << usedNodeCounter << " nodes and " << usedEdgeCounter << " edges");
} catch ( const exception& e ) {
cerr << "Caught Execption:" << e.what() << endl;
} catch ( const std::exception& e ) {
std::cerr << "Caught Execption:" << e.what() << std::endl;
}
}
+46 -50
View File
@@ -1,69 +1,65 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EXTRACTIONCONTAINERS_H_
#define EXTRACTIONCONTAINERS_H_
#include <boost/foreach.hpp>
#include <stxxl.h>
#include "InternalExtractorEdge.h"
#include "ExtractorStructs.h"
#include "../DataStructures/Util.h"
#include "../DataStructures/Restriction.h"
#include "../Util/UUID.h"
#include <stxxl/vector>
class ExtractionContainers {
public:
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
typedef stxxl::vector<_Node> STXXLNodeVector;
typedef stxxl::vector<_Edge> STXXLEdgeVector;
typedef stxxl::vector<std::string> STXXLStringVector;
typedef stxxl::vector<_RawRestrictionContainer> STXXLRestrictionsVector;
typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
typedef stxxl::vector<ExternalMemoryNode> STXXLNodeVector;
typedef stxxl::vector<InternalExtractorEdge> STXXLEdgeVector;
typedef stxxl::vector<std::string> STXXLStringVector;
typedef stxxl::vector<InputRestrictionContainer> STXXLRestrictionsVector;
typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
ExtractionContainers() {
//Check if another instance of stxxl is already running or if there is a general problem
try {
stxxl::vector<unsigned> testForRunningInstance;
} catch(std::exception & e) {
ERR("Could not instantiate STXXL layer." << std::endl << e.what());
}
STXXLNodeIDVector used_node_id_list;
STXXLNodeVector all_nodes_list;
STXXLEdgeVector all_edges_list;
STXXLStringVector name_list;
STXXLRestrictionsVector restrictions_list;
STXXLWayIDStartEndVector way_start_end_id_list;
const UUID uuid;
nameVector.push_back("");
}
virtual ~ExtractionContainers() {
usedNodeIDs.clear();
allNodes.clear();
allEdges.clear();
nameVector.clear();
restrictionsVector.clear();
wayStartEndVector.clear();
}
ExtractionContainers();
void PrepareData( const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM);
STXXLNodeIDVector usedNodeIDs;
STXXLNodeVector allNodes;
STXXLEdgeVector allEdges;
STXXLStringVector nameVector;
STXXLRestrictionsVector restrictionsVector;
STXXLWayIDStartEndVector wayStartEndVector;
virtual ~ExtractionContainers();
void PrepareData(
const std::string & output_file_name,
const std::string & restrictions_file_name
);
};
#endif /* EXTRACTIONCONTAINERS_H_ */
+49 -32
View File
@@ -1,39 +1,46 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EXTRACTIONHELPERFUNCTIONS_H_
#define EXTRACTIONHELPERFUNCTIONS_H_
#include "../Util/StringUtil.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string_regex.hpp>
#include <boost/regex.hpp>
#include <climits>
#include "../Util/StringUtil.h"
namespace qi = boost::spirit::qi;
//TODO: Move into LUA
inline bool durationIsValid(const std::string &s) {
boost::regex e ("((\\d|\\d\\d):)*(\\d|\\d\\d)",boost::regex_constants::icase|boost::regex_constants::perl);
boost::regex e ("((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)",boost::regex_constants::icase|boost::regex_constants::perl);
std::vector< std::string > result;
boost::algorithm::split_regex( result, s, boost::regex( ":" ) ) ;
@@ -42,29 +49,39 @@ inline bool durationIsValid(const std::string &s) {
}
inline unsigned parseDuration(const std::string &s) {
int hours = 0;
int minutes = 0;
boost::regex e ("((\\d|\\d\\d):)*(\\d|\\d\\d)",boost::regex_constants::icase|boost::regex_constants::perl);
unsigned hours = 0;
unsigned minutes = 0;
unsigned seconds = 0;
boost::regex e ("((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)",boost::regex_constants::icase|boost::regex_constants::perl);
std::vector< std::string > result;
boost::algorithm::split_regex( result, s, boost::regex( ":" ) ) ;
bool matched = regex_match(s, e);
if(matched) {
hours = (result.size()== 2) ? stringToInt(result[0]) : 0;
minutes = (result.size()== 2) ? stringToInt(result[1]) : stringToInt(result[0]);
return 600*(hours*60+minutes);
if(1 == result.size()) {
minutes = stringToInt(result[0]);
}
if(2 == result.size()) {
minutes = stringToInt(result[1]);
hours = stringToInt(result[0]);
}
if(3 == result.size()) {
seconds = stringToInt(result[2]);
minutes = stringToInt(result[1]);
hours = stringToInt(result[0]);
}
return 10*(3600*hours+60*minutes+seconds);
}
return UINT_MAX;
}
inline int parseMaxspeed(std::string input) { //call-by-value on purpose.
boost::algorithm::to_lower(input);
int n = stringToInt(input);
if (input.find("mph") != std::string::npos || input.find("mp/h") != std::string::npos) {
n = (n*1609)/1000;
}
return n;
}
// inline int parseMaxspeed(std::string input) { //call-by-value on purpose.
// boost::algorithm::to_lower(input);
// int n = stringToInt(input);
// if (input.find("mph") != std::string::npos || input.find("mp/h") != std::string::npos) {
// n = (n*1609)/1000;
// }
// return n;
// }
#endif /* EXTRACTIONHELPERFUNCTIONS_H_ */
+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
+122 -73
View File
@@ -1,105 +1,154 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ExtractorCallbacks.h"
#include "ExtractionHelperFunctions.h"
#include "ExtractionContainers.h"
#include "ExtractionWay.h"
ExtractorCallbacks::ExtractorCallbacks() {externalMemory = NULL; stringMap = NULL; }
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap) {
externalMemory = ext;
stringMap = strMap;
}
#include "../DataStructures/Restriction.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/SimpleLogger.h"
ExtractorCallbacks::~ExtractorCallbacks() {
}
#include <osrm/Coordinate.h>
#include <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() { }
/** warning: caller needs to take care of synchronization! */
bool ExtractorCallbacks::nodeFunction(_Node &n) {
if(n.lat <= 85*100000 && n.lat >= -85*100000)
externalMemory->allNodes.push_back(n);
return true;
void ExtractorCallbacks::nodeFunction(const ExternalMemoryNode &n) {
if(n.lat <= 85*COORDINATE_PRECISION && n.lat >= -85*COORDINATE_PRECISION) {
externalMemory->all_nodes_list.push_back(n);
}
}
bool ExtractorCallbacks::restrictionFunction(_RawRestrictionContainer &r) {
externalMemory->restrictionsVector.push_back(r);
bool ExtractorCallbacks::restrictionFunction(const InputRestrictionContainer &r) {
externalMemory->restrictions_list.push_back(r);
return true;
}
/** warning: caller needs to take care of synchronization! */
bool ExtractorCallbacks::wayFunction(_Way &w) {
/*** Store name of way and split it into edge segments ***/
void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
if((0 < parsed_way.speed) || (0 < parsed_way.duration)) { //Only true if the way is specified by the speed profile
if(UINT_MAX == parsed_way.id){
SimpleLogger().Write(logDEBUG) <<
"found bogus way with id: " << parsed_way.id <<
" of size " << parsed_way.path.size();
return;
}
if ( w.speed > 0 ) { //Only true if the way is specified by the speed profile
if(0 < parsed_way.duration) {
//TODO: iterate all way segments and set duration corresponding to the length of each segment
parsed_way.speed = parsed_way.duration/(parsed_way.path.size()-1);
}
if(std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.speed)){
SimpleLogger().Write(logDEBUG) <<
"found way with bogus speed, id: " << parsed_way.id;
return;
}
//Get the unique identifier for the street name
const StringMap::const_iterator strit = stringMap->find(w.name);
if(strit == stringMap->end()) {
w.nameID = externalMemory->nameVector.size();
externalMemory->nameVector.push_back(w.name);
stringMap->insert(StringMap::value_type(w.name, w.nameID));
const boost::unordered_map<std::string, NodeID>::const_iterator & string_map_iterator = string_map->find(parsed_way.name);
if(string_map->end() == string_map_iterator) {
parsed_way.nameID = externalMemory->name_list.size();
externalMemory->name_list.push_back(parsed_way.name);
string_map->insert(std::make_pair(parsed_way.name, parsed_way.nameID));
} else {
w.nameID = strit->second;
parsed_way.nameID = string_map_iterator->second;
}
if(fabs(-1. - w.speed) < FLT_EPSILON){
WARN("found way with bogus speed, id: " << w.id);
return true;
}
if(w.id == UINT_MAX) {
WARN("found way with unknown type: " << w.id);
return true;
if(ExtractionWay::opposite == parsed_way.direction) {
std::reverse( parsed_way.path.begin(), parsed_way.path.end() );
parsed_way.direction = ExtractionWay::oneway;
}
if ( w.direction == _Way::opposite ){
std::reverse( w.path.begin(), w.path.end() );
}
const bool split_bidirectional_edge = (parsed_way.backward_speed > 0) && (parsed_way.speed != parsed_way.backward_speed);
for(vector< NodeID >::size_type n = 0; n < w.path.size()-1; ++n) {
externalMemory->allEdges.push_back(_Edge(w.path[n], w.path[n+1], w.type, w.direction, w.speed, w.nameID, w.roundabout, w.ignoreInGrid, w.isDurationSet, w.isAccessRestricted));
externalMemory->usedNodeIDs.push_back(w.path[n]);
for(std::vector< NodeID >::size_type n = 0; n < parsed_way.path.size()-1; ++n) {
externalMemory->all_edges_list.push_back(
InternalExtractorEdge(
parsed_way.path[n],
parsed_way.path[n+1],
parsed_way.type,
(split_bidirectional_edge ? ExtractionWay::oneway : parsed_way.direction),
parsed_way.speed,
parsed_way.nameID,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
false,
split_bidirectional_edge
)
);
externalMemory->used_node_id_list.push_back(parsed_way.path[n]);
}
externalMemory->usedNodeIDs.push_back(w.path.back());
externalMemory->used_node_id_list.push_back(parsed_way.path.back());
//The following information is needed to identify start and end segments of restrictions
externalMemory->wayStartEndVector.push_back(_WayIDStartAndEndEdge(w.id, w.path[0], w.path[1], w.path[w.path.size()-2], w.path[w.path.size()-1]));
externalMemory->way_start_end_id_list.push_back(_WayIDStartAndEndEdge(parsed_way.id, parsed_way.path[0], parsed_way.path[1], parsed_way.path[parsed_way.path.size()-2], parsed_way.path.back()));
if(split_bidirectional_edge) { //Only true if the way should be split
std::reverse( parsed_way.path.begin(), parsed_way.path.end() );
for(std::vector< NodeID >::size_type n = 0; n < parsed_way.path.size()-1; ++n) {
externalMemory->all_edges_list.push_back(
InternalExtractorEdge(
parsed_way.path[n],
parsed_way.path[n+1],
parsed_way.type,
ExtractionWay::oneway,
parsed_way.backward_speed,
parsed_way.nameID,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
(ExtractionWay::oneway == parsed_way.direction),
split_bidirectional_edge
)
);
}
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()));
}
}
return true;
}
+38 -29
View File
@@ -1,56 +1,65 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EXTRACTORCALLBACKS_H_
#define EXTRACTORCALLBACKS_H_
#include "../typedefs.h"
#include <boost/unordered_map.hpp>
#include <string>
#include <vector>
#include <cfloat>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include "ExtractionContainers.h"
#include "ExtractorStructs.h"
struct ExternalMemoryNode;
class ExtractionContainers;
struct ExtractionWay;
struct InputRestrictionContainer;
class ExtractorCallbacks{
private:
StringMap * stringMap;
boost::unordered_map<std::string, NodeID> * string_map;
ExtractionContainers * externalMemory;
ExtractorCallbacks();
public:
explicit ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap);
explicit ExtractorCallbacks(
ExtractionContainers * ext,
boost::unordered_map<std::string, NodeID> * string_map
);
~ExtractorCallbacks();
/** warning: caller needs to take care of synchronization! */
bool nodeFunction(_Node &n);
void nodeFunction(const ExternalMemoryNode &n);
bool restrictionFunction(_RawRestrictionContainer &r);
bool restrictionFunction(const InputRestrictionContainer &r);
/** warning: caller needs to take care of synchronization! */
bool wayFunction(_Way &w);
void wayFunction(ExtractionWay &w);
};
+67 -156
View File
@@ -1,140 +1,90 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EXTRACTORSTRUCTS_H_
#define EXTRACTORSTRUCTS_H_
#include <climits>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include <boost/unordered_map.hpp>
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/NodeCoords.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/Util.h"
#include "../typedefs.h"
typedef boost::unordered_map<std::string, NodeID > StringMap;
typedef boost::unordered_map<std::string, std::pair<int, short> > StringToIntPairMap;
#include <string>
struct _Way {
_Way() {
Clear();
}
inline void Clear(){
id = UINT_MAX;
nameID = UINT_MAX;
path.clear();
keyVals.EraseAll();
direction = _Way::notSure;
speed = -1;
type = -1;
access = true;
roundabout = false;
isDurationSet = false;
isAccessRestricted = false;
ignoreInGrid = false;
}
enum {
notSure = 0, oneway, bidirectional, opposite
} direction;
unsigned id;
unsigned nameID;
std::string name;
double speed;
short type;
bool access;
bool roundabout;
bool isDurationSet;
bool isAccessRestricted;
bool ignoreInGrid;
std::vector< NodeID > path;
HashTable<std::string, std::string> keyVals;
};
struct _Relation {
_Relation() : type(unknown){}
struct ExtractorRelation {
ExtractorRelation() : type(unknown){}
enum {
unknown = 0, ferry, turnRestriction
} type;
HashTable<std::string, std::string> keyVals;
};
struct _Edge {
_Edge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false) {};
_Edge(NodeID s, NodeID t) : start(s), target(t), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false) { }
_Edge(NodeID s, NodeID t, short tp, short d, double sp): start(s), target(t), type(tp), direction(d), speed(sp), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false) { }
_Edge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar) {
assert(0 <= type);
}
NodeID start;
NodeID target;
short type;
short direction;
double speed;
unsigned nameID;
bool isRoundabout;
bool ignoreInGrid;
bool isDurationSet;
bool isAccessRestricted;
_Coordinate startCoord;
_Coordinate targetCoord;
static _Edge min_value() {
return _Edge(0,0);
}
static _Edge max_value() {
return _Edge((numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)());
}
};
struct _WayIDStartAndEndEdge {
unsigned wayID;
NodeID firstStart;
NodeID firstTarget;
NodeID lastStart;
NodeID lastTarget;
_WayIDStartAndEndEdge() : wayID(UINT_MAX), firstStart(UINT_MAX), firstTarget(UINT_MAX), lastStart(UINT_MAX), lastTarget(UINT_MAX) {}
_WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt) : wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt) {}
_WayIDStartAndEndEdge()
:
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() {
return _WayIDStartAndEndEdge((numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (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)());
}
static _WayIDStartAndEndEdge max_value() {
return _WayIDStartAndEndEdge((numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)());
return _WayIDStartAndEndEdge((std::numeric_limits<unsigned>::max)(), (std::numeric_limits<unsigned>::max)(), (std::numeric_limits<unsigned>::max)(), (std::numeric_limits<unsigned>::max)(), (std::numeric_limits<unsigned>::max)());
}
};
struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDStartAndEndEdge, bool> {
struct CmpWayByID {
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;
}
value_type max_value() {
@@ -145,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;
bool operator () (const NodeID & a, const NodeID & b) const {
bool operator ()(
const NodeID a,
const NodeID b
) const {
return a < b;
}
value_type max_value() {
@@ -158,62 +111,20 @@ struct Cmp : public std::binary_function<NodeID, NodeID, bool> {
}
};
struct CmpNodeByID : public std::binary_function<_Node, _Node, bool> {
typedef _Node value_type;
bool operator () (const _Node & a, const _Node & b) const {
struct CmpNodeByID {
typedef ExternalMemoryNode value_type;
bool operator () (
const ExternalMemoryNode & a,
const ExternalMemoryNode & b
) const {
return a.id < b.id;
}
value_type max_value() {
return _Node::max_value();
return ExternalMemoryNode::max_value();
}
value_type min_value() {
return _Node::min_value();
return ExternalMemoryNode::min_value();
}
};
struct CmpEdgeByStartID : public std::binary_function<_Edge, _Edge, bool>
{
typedef _Edge value_type;
bool operator () (const _Edge & a, const _Edge & b) const {
return a.start < b.start;
}
value_type max_value() {
return _Edge::max_value();
}
value_type min_value() {
return _Edge::min_value();
}
};
struct CmpEdgeByTargetID : public std::binary_function<_Edge, _Edge, bool>
{
typedef _Edge value_type;
bool operator () (const _Edge & a, const _Edge & b) const
{
return a.target < b.target;
}
value_type max_value()
{
return _Edge::max_value();
}
value_type min_value()
{
return _Edge::min_value();
}
};
inline string GetRandomString() {
char s[128];
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 127; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[127] = 0;
return string(s);
}
#endif /* EXTRACTORSTRUCTS_H_ */
+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
-35
View File
@@ -1,35 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef LUAUTIL_H_
#define LUAUTIL_H_
#include <iostream>
template<typename T>
void LUA_print(T number) {
std::cout << "[LUA] " << number << std::endl;
}
#endif /* LUAUTIL_H_ */
+535
View File
@@ -0,0 +1,535 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PBFParser.h"
#include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/Restriction.h"
#include "../Util/MachineInfo.h"
#include "../Util/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;
//TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
//NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
// Max 2500 items in queue, hardcoded.
threadDataQueue = boost::make_shared<ConcurrentQueue<_ThreadData*> >( 2500 );
input.open(fileName, std::ios::in | std::ios::binary);
if (!input) {
throw OSRMException("pbf file not found.");
}
blockCount = 0;
groupCount = 0;
}
PBFParser::~PBFParser() {
if(input.is_open()) {
input.close();
}
// Clean up any leftover ThreadData objects in the queue
_ThreadData* thread_data;
while (threadDataQueue->try_pop(thread_data))
{
delete thread_data;
}
google::protobuf::ShutdownProtobufLibrary();
SimpleLogger().Write(logDEBUG) <<
"parsed " << blockCount <<
" blocks from pbf with " << groupCount <<
" groups";
}
inline bool PBFParser::ReadHeader() {
_ThreadData initData;
/** read Header */
if(!readPBFBlobHeader(input, &initData)) {
return false;
}
if(readBlob(input, &initData)) {
if(!initData.PBFHeaderBlock.ParseFromArray(&(initData.charBuffer[0]), initData.charBuffer.size() ) ) {
std::cerr << "[error] Header not parseable!" << std::endl;
return false;
}
for(int i = 0, featureSize = initData.PBFHeaderBlock.required_features_size(); i < featureSize; ++i) {
const std::string& feature = initData.PBFHeaderBlock.required_features( i );
bool supported = false;
if ( "OsmSchema-V0.6" == feature ) {
supported = true;
}
else if ( "DenseNodes" == feature ) {
supported = true;
}
if ( !supported ) {
std::cerr << "[error] required feature not supported: " << feature.data() << std::endl;
return false;
}
}
} else {
std::cerr << "[error] blob not loaded!" << std::endl;
}
return true;
}
inline void PBFParser::ReadData() {
bool keepRunning = true;
do {
_ThreadData *threadData = new _ThreadData();
keepRunning = readNextBlock(input, threadData);
if (keepRunning) {
threadDataQueue->push(threadData);
} else {
threadDataQueue->push(NULL); // No more data to read, parse stops when NULL encountered
delete threadData;
}
} while(keepRunning);
}
inline void PBFParser::ParseData() {
while (true) {
_ThreadData *threadData;
threadDataQueue->wait_and_pop(threadData);
if( NULL==threadData ) {
SimpleLogger().Write() << "Parse Data Thread Finished";
threadDataQueue->push(NULL); // Signal end of data for other threads
break;
}
loadBlock(threadData);
for(int i = 0, groupSize = threadData->PBFprimitiveBlock.primitivegroup_size(); i < groupSize; ++i) {
threadData->currentGroupID = i;
loadGroup(threadData);
if(threadData->entityTypeIndicator == TypeNode) {
parseNode(threadData);
}
if(threadData->entityTypeIndicator == TypeWay) {
parseWay(threadData);
}
if(threadData->entityTypeIndicator == TypeRelation) {
parseRelation(threadData);
}
if(threadData->entityTypeIndicator == TypeDenseNode) {
parseDenseNode(threadData);
}
}
delete threadData;
threadData = NULL;
}
}
inline bool PBFParser::Parse() {
// Start the read and parse threads
boost::thread readThread(boost::bind(&PBFParser::ReadData, this));
//Open several parse threads that are synchronized before call to
boost::thread parseThread(boost::bind(&PBFParser::ParseData, this));
// Wait for the threads to finish
readThread.join();
parseThread.join();
return true;
}
inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
const OSMPBF::DenseNodes& dense = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).dense();
int denseTagIndex = 0;
int64_t m_lastDenseID = 0;
int64_t m_lastDenseLatitude = 0;
int64_t m_lastDenseLongitude = 0;
const int number_of_nodes = dense.id_size();
std::vector<ImportNode> extracted_nodes_vector(number_of_nodes);
for(int i = 0; i < number_of_nodes; ++i) {
m_lastDenseID += dense.id( i );
m_lastDenseLatitude += dense.lat( i );
m_lastDenseLongitude += dense.lon( i );
extracted_nodes_vector[i].id = m_lastDenseID;
extracted_nodes_vector[i].lat = COORDINATE_PRECISION*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lat_offset() ) / NANO;
extracted_nodes_vector[i].lon = COORDINATE_PRECISION*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO;
while (denseTagIndex < dense.keys_vals_size()) {
const int tagValue = dense.keys_vals( denseTagIndex );
if( 0 == tagValue ) {
++denseTagIndex;
break;
}
const int keyValue = dense.keys_vals ( denseTagIndex+1 );
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue);
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue);
extracted_nodes_vector[i].keyVals.emplace(key, value);
denseTagIndex += 2;
}
}
#pragma omp parallel
{
const int thread_num = omp_get_thread_num();
#pragma omp parallel for schedule ( guided )
for(int i = 0; i < number_of_nodes; ++i)
{
ImportNode & import_node = extracted_nodes_vector[i];
ParseNodeInLua(import_node, scripting_environment.getLuaStateForThreadID(thread_num));
}
}
BOOST_FOREACH(const ImportNode &import_node, extracted_nodes_vector)
{
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) {
//TODO: leave early, if relation is not a restriction
//TODO: reuse rawRestriction container
if( !use_turn_restrictions ) {
return;
}
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
for(int i = 0, relation_size = group.relations_size(); i < relation_size; ++i ) {
std::string except_tag_string;
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
bool isRestriction = false;
bool isOnlyRestriction = false;
for(int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
if ("type" == key) {
if( "restriction" == val) {
isRestriction = true;
} else {
break;
}
}
if ( ("restriction" == key) && (val.find("only_") == 0) )
{
isOnlyRestriction = true;
}
if ("except" == key)
{
except_tag_string = val;
}
}
if( isRestriction && ShouldIgnoreRestriction(except_tag_string) ) {
continue;
}
if(isRestriction) {
int64_t lastRef = 0;
InputRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
for(
int rolesIndex = 0, last_role = inputRelation.roles_sid_size();
rolesIndex < last_role;
++rolesIndex
) {
const std::string & role = threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) );
lastRef += inputRelation.memids(rolesIndex);
if(!("from" == role || "to" == role || "via" == role)) {
continue;
}
switch(inputRelation.types(rolesIndex)) {
case 0: //node
if("from" == role || "to" == role) { //Only via should be a node
continue;
}
assert("via" == role);
if(UINT_MAX != currentRestrictionContainer.viaNode) {
currentRestrictionContainer.viaNode = UINT_MAX;
}
assert(UINT_MAX == currentRestrictionContainer.viaNode);
currentRestrictionContainer.restriction.viaNode = lastRef;
break;
case 1: //way
assert("from" == role || "to" == role || "via" == role);
if("from" == role) {
currentRestrictionContainer.fromWay = lastRef;
}
if ("to" == role) {
currentRestrictionContainer.toWay = lastRef;
}
if ("via" == role) {
assert(currentRestrictionContainer.restriction.toNode == UINT_MAX);
currentRestrictionContainer.viaNode = lastRef;
}
break;
case 2: //relation, not used. relations relating to relations are evil.
continue;
assert(false);
break;
default: //should not happen
assert(false);
break;
}
}
if(!extractor_callbacks->restrictionFunction(currentRestrictionContainer)) {
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}
}
}
}
inline void PBFParser::parseWay(_ThreadData * threadData) {
const int number_of_ways = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size();
std::vector<ExtractionWay> parsed_way_vector(number_of_ways);
for(int i = 0; i < number_of_ways; ++i) {
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
parsed_way_vector[i].id = inputWay.id();
unsigned pathNode(0);
const int number_of_referenced_nodes = inputWay.refs_size();
for(int j = 0; j < number_of_referenced_nodes; ++j) {
pathNode += inputWay.refs(j);
parsed_way_vector[i].path.push_back(pathNode);
}
assert(inputWay.keys_size() == inputWay.vals_size());
const int number_of_keys = inputWay.keys_size();
for(int j = 0; j < number_of_keys; ++j) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(j));
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(j));
parsed_way_vector[i].keyVals.emplace(key, val);
}
}
#pragma omp parallel for schedule ( guided )
for(int i = 0; i < number_of_ways; ++i)
{
ExtractionWay & extraction_way = parsed_way_vector[i];
if (2 <= extraction_way.path.size())
{
ParseWayInLua(
extraction_way,
scripting_environment.getLuaStateForThreadID(omp_get_thread_num())
);
}
}
BOOST_FOREACH(ExtractionWay & extraction_way, parsed_way_vector)
{
if (2 <= extraction_way.path.size())
{
extractor_callbacks->wayFunction(extraction_way);
}
}
}
inline void PBFParser::loadGroup(_ThreadData * threadData) {
#ifndef NDEBUG
++groupCount;
#endif
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
threadData->entityTypeIndicator = TypeDummy;
if ( 0 != group.nodes_size() ) {
threadData->entityTypeIndicator = TypeNode;
}
if ( 0 != group.ways_size() ) {
threadData->entityTypeIndicator = TypeWay;
}
if ( 0 != group.relations_size() ) {
threadData->entityTypeIndicator = TypeRelation;
}
if ( group.has_dense() ) {
threadData->entityTypeIndicator = TypeDenseNode;
assert( 0 != group.dense().id_size() );
}
assert( threadData->entityTypeIndicator != TypeDummy );
}
inline void PBFParser::loadBlock(_ThreadData * threadData) {
++blockCount;
threadData->currentGroupID = 0;
threadData->currentEntityID = 0;
}
inline bool PBFParser::readPBFBlobHeader(std::fstream& stream, _ThreadData * threadData) {
int size(0);
stream.read((char *)&size, sizeof(int));
size = swapEndian(size);
if(stream.eof()) {
return false;
}
if ( size > MAX_BLOB_HEADER_SIZE || size < 0 ) {
return false;
}
char *data = new char[size];
stream.read(data, size*sizeof(data[0]));
bool dataSuccessfullyParsed = (threadData->PBFBlobHeader).ParseFromArray( data, size);
delete[] data;
return dataSuccessfullyParsed;
}
inline bool PBFParser::unpackZLIB(std::fstream &, _ThreadData * threadData) {
unsigned rawSize = threadData->PBFBlob.raw_size();
char* unpackedDataArray = new char[rawSize];
z_stream compressedDataStream;
compressedDataStream.next_in = ( unsigned char* ) threadData->PBFBlob.zlib_data().data();
compressedDataStream.avail_in = threadData->PBFBlob.zlib_data().size();
compressedDataStream.next_out = ( unsigned char* ) unpackedDataArray;
compressedDataStream.avail_out = rawSize;
compressedDataStream.zalloc = Z_NULL;
compressedDataStream.zfree = Z_NULL;
compressedDataStream.opaque = Z_NULL;
int ret = inflateInit( &compressedDataStream );
if ( ret != Z_OK ) {
std::cerr << "[error] failed to init zlib stream" << std::endl;
delete[] unpackedDataArray;
return false;
}
ret = inflate( &compressedDataStream, Z_FINISH );
if ( ret != Z_STREAM_END ) {
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
std::cerr << "[error] Error type: " << ret << std::endl;
delete[] unpackedDataArray;
return false;
}
ret = inflateEnd( &compressedDataStream );
if ( ret != Z_OK ) {
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
delete[] unpackedDataArray;
return false;
}
threadData->charBuffer.clear(); threadData->charBuffer.resize(rawSize);
std::copy(unpackedDataArray, unpackedDataArray + rawSize, threadData->charBuffer.begin());
delete[] unpackedDataArray;
return true;
}
inline bool PBFParser::unpackLZMA(std::fstream &, _ThreadData * ) {
return false;
}
inline bool PBFParser::readBlob(std::fstream& stream, _ThreadData * threadData) {
if(stream.eof()) {
return false;
}
const int size = threadData->PBFBlobHeader.datasize();
if ( size < 0 || size > MAX_BLOB_SIZE ) {
std::cerr << "[error] invalid Blob size:" << size << std::endl;
return false;
}
char* data = new char[size];
stream.read(data, sizeof(data[0])*size);
if ( !threadData->PBFBlob.ParseFromArray( data, size ) ) {
std::cerr << "[error] failed to parse blob" << std::endl;
delete[] data;
return false;
}
if ( threadData->PBFBlob.has_raw() ) {
const std::string& data = threadData->PBFBlob.raw();
threadData->charBuffer.clear();
threadData->charBuffer.resize( data.size() );
std::copy(data.begin(), data.end(), threadData->charBuffer.begin());
} else if ( threadData->PBFBlob.has_zlib_data() ) {
if ( !unpackZLIB(stream, threadData) ) {
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
delete[] data;
return false;
}
} else if ( threadData->PBFBlob.has_lzma_data() ) {
if ( !unpackLZMA(stream, threadData) ) {
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
}
delete[] data;
return false;
} else {
std::cerr << "[error] Blob contains no data" << std::endl;
delete[] data;
return false;
}
delete[] data;
return true;
}
bool PBFParser::readNextBlock(std::fstream& stream, _ThreadData * threadData) {
if(stream.eof()) {
return false;
}
if ( !readPBFBlobHeader(stream, threadData) ){
return false;
}
if ( threadData->PBFBlobHeader.type() != "OSMData" ) {
return false;
}
if ( !readBlob(stream, threadData) ) {
return false;
}
if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) {
std::cerr << "failed to parse PrimitiveBlock" << std::endl;
return false;
}
return true;
}
+54 -551
View File
@@ -1,64 +1,57 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PBFPARSER_H_
#define PBFPARSER_H_
#include <zlib.h>
#include <boost/make_shared.hpp>
#include <boost/ref.hpp>
#include "BaseParser.h"
#include "../DataStructures/ConcurrentQueue.h"
#include <boost/shared_ptr.hpp>
#include <osmpbf/fileformat.pb.h>
#include <osmpbf/osmformat.pb.h>
#include "../typedefs.h"
#include <fstream>
#include "BaseParser.h"
#include "ExtractorCallbacks.h"
#include "ExtractorStructs.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ConcurrentQueue.h"
#include "../Util/OpenMPWrapper.h"
class PBFParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, _Way> {
// typedef BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, _Way> super;
class PBFParser : public BaseParser {
enum EntityType {
TypeNode = 1,
TypeWay = 2,
TypeRelation = 4,
TypeDummy = 0,
TypeNode = 1,
TypeWay = 2,
TypeRelation = 4,
TypeDenseNode = 8
} ;
enum Endianness {
LittleEndian = 1,
BigEndian = 2
};
struct _ThreadData {
int currentGroupID;
int currentEntityID;
short entityTypeIndicator;
EntityType entityTypeIndicator;
OSMPBF::BlobHeader PBFBlobHeader;
OSMPBF::Blob PBFBlob;
@@ -70,531 +63,41 @@ class PBFParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionCo
};
public:
PBFParser(const char * fileName) : externalMemory(NULL){
GOOGLE_PROTOBUF_VERIFY_VERSION;
//TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
//NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
threadDataQueue = boost::make_shared<ConcurrentQueue<_ThreadData*> >( 2500 ); /* Max 2500 items in queue, hardcoded. */
input.open(fileName, std::ios::in | std::ios::binary);
PBFParser(
const char * fileName,
ExtractorCallbacks* ec,
ScriptingEnvironment& se
);
virtual ~PBFParser();
if (!input) {
std::cerr << fileName << ": File not found." << std::endl;
}
#ifndef NDEBUG
blockCount = 0;
groupCount = 0;
#endif
}
void RegisterCallbacks(ExtractorCallbacks * em) {
externalMemory = em;
}
//call by value, but who cares. It is done once.
void RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
scriptingEnvironment = _se;
}
~PBFParser() {
if(input.is_open())
input.close();
// Clean up any leftover ThreadData objects in the queue
_ThreadData* td;
while (threadDataQueue->try_pop(td)) {
delete td;
}
google::protobuf::ShutdownProtobufLibrary();
#ifndef NDEBUG
DEBUG("parsed " << blockCount << " blocks from pbf with " << groupCount << " groups");
#endif
}
inline bool Init() {
_ThreadData initData;
/** read Header */
if(!readPBFBlobHeader(input, &initData)) {
return false;
}
if(readBlob(input, &initData)) {
if(!initData.PBFHeaderBlock.ParseFromArray(&(initData.charBuffer[0]), initData.charBuffer.size() ) ) {
std::cerr << "[error] Header not parseable!" << std::endl;
return false;
}
for(int i = 0, featureSize = initData.PBFHeaderBlock.required_features_size(); i < featureSize; ++i) {
const std::string& feature = initData.PBFHeaderBlock.required_features( i );
bool supported = false;
if ( "OsmSchema-V0.6" == feature )
supported = true;
else if ( "DenseNodes" == feature )
supported = true;
if ( !supported ) {
std::cerr << "[error] required feature not supported: " << feature.data() << std::endl;
return false;
}
}
} else {
std::cerr << "[error] blob not loaded!" << std::endl;
}
return true;
}
inline void ReadData() {
bool keepRunning = true;
do {
_ThreadData *threadData = new _ThreadData();
keepRunning = readNextBlock(input, threadData);
if (keepRunning)
threadDataQueue->push(threadData);
else {
threadDataQueue->push(NULL); // No more data to read, parse stops when NULL encountered
delete threadData;
}
} while(keepRunning);
}
inline void ParseData() {
while (1) {
_ThreadData *threadData;
threadDataQueue->wait_and_pop(threadData);
if (threadData == NULL) {
INFO("Parse Data Thread Finished");
threadDataQueue->push(NULL); // Signal end of data for other threads
break;
}
loadBlock(threadData);
for(int i = 0, groupSize = threadData->PBFprimitiveBlock.primitivegroup_size(); i < groupSize; ++i) {
threadData->currentGroupID = i;
loadGroup(threadData);
if(threadData->entityTypeIndicator == TypeNode)
parseNode(threadData);
if(threadData->entityTypeIndicator == TypeWay)
parseWay(threadData);
if(threadData->entityTypeIndicator == TypeRelation)
parseRelation(threadData);
if(threadData->entityTypeIndicator == TypeDenseNode)
parseDenseNode(threadData);
}
delete threadData;
threadData = NULL;
}
}
inline bool Parse() {
// Start the read and parse threads
boost::thread readThread(boost::bind(&PBFParser::ReadData, this));
//Open several parse threads that are synchronized before call to
boost::thread parseThread(boost::bind(&PBFParser::ParseData, this));
// Wait for the threads to finish
readThread.join();
parseThread.join();
return true;
}
inline bool ReadHeader();
inline bool Parse();
private:
inline void ReadData();
inline void ParseData();
inline void parseDenseNode (_ThreadData * threadData);
inline void parseNode (_ThreadData * threadData);
inline void parseRelation (_ThreadData * threadData);
inline void parseWay (_ThreadData * threadData);
inline void parseDenseNode(_ThreadData * threadData) {
const OSMPBF::DenseNodes& dense = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).dense();
int denseTagIndex = 0;
int m_lastDenseID = 0;
int m_lastDenseLatitude = 0;
int m_lastDenseLongitude = 0;
ImportNode n;
std::vector<ImportNode> nodesToParse;
for(int i = 0, idSize = dense.id_size(); i < idSize; ++i) {
n.Clear();
m_lastDenseID += dense.id( i );
m_lastDenseLatitude += dense.lat( i );
m_lastDenseLongitude += dense.lon( i );
n.id = m_lastDenseID;
n.lat = 100000*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() +threadData-> PBFprimitiveBlock.lat_offset() ) / NANO;
n.lon = 100000*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO;
while (denseTagIndex < dense.keys_vals_size()) {
const int tagValue = dense.keys_vals( denseTagIndex );
if(tagValue == 0) {
++denseTagIndex;
break;
}
const int keyValue = dense.keys_vals ( denseTagIndex+1 );
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data();
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data();
n.keyVals.Add(key, value);
denseTagIndex += 2;
}
nodesToParse.push_back(n);
}
unsigned endi_nodes = nodesToParse.size();
#pragma omp parallel for schedule ( guided )
for(unsigned i = 0; i < endi_nodes; ++i) {
ImportNode &n = nodesToParse[i];
/** Pass the unpacked node to the LUA call back **/
try {
luabind::call_function<int>(
scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()),
"node_function",
boost::ref(n)
);
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
// catch (...) {
// ERR("Unknown error occurred during PBF dense node parsing!");
// }
}
BOOST_FOREACH(ImportNode &n, nodesToParse) {
if(!externalMemory->nodeFunction(n))
std::cerr << "[PBFParser] dense node not parsed" << std::endl;
}
}
inline void parseNode(_ThreadData * ) {
ERR("Parsing of simple nodes not supported. PBF should use dense nodes");
}
inline void parseRelation(_ThreadData * threadData) {
//TODO: leave early, if relatio is not a restriction
//TODO: reuse rawRestriction container
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
for(int i = 0; i < group.relations_size(); ++i ) {
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
bool isRestriction = false;
bool isOnlyRestriction = false;
for(int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
if ("type" == key) {
if( "restriction" == val)
isRestriction = true;
else
break;
}
if ("restriction" == key) {
if(val.find("only_") == 0)
isOnlyRestriction = true;
}
}
if(isRestriction) {
long long lastRef = 0;
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
for(int rolesIndex = 0; rolesIndex < inputRelation.roles_sid_size(); ++rolesIndex) {
std::string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data());
lastRef += inputRelation.memids(rolesIndex);
if(false == ("from" == role || "to" == role || "via" == role)) {
continue;
}
switch(inputRelation.types(rolesIndex)) {
case 0: //node
if("from" == role || "to" == role) //Only via should be a node
continue;
assert("via" == role);
if(UINT_MAX != currentRestrictionContainer.viaNode)
currentRestrictionContainer.viaNode = UINT_MAX;
assert(UINT_MAX == currentRestrictionContainer.viaNode);
currentRestrictionContainer.restriction.viaNode = lastRef;
break;
case 1: //way
assert("from" == role || "to" == role || "via" == role);
if("from" == role) {
currentRestrictionContainer.fromWay = lastRef;
}
if ("to" == role) {
currentRestrictionContainer.toWay = lastRef;
}
if ("via" == role) {
assert(currentRestrictionContainer.restriction.toNode == UINT_MAX);
currentRestrictionContainer.viaNode = lastRef;
}
break;
case 2: //relation, not used. relations relating to relations are evil.
continue;
assert(false);
break;
default: //should not happen
//cout << "unknown";
assert(false);
break;
}
}
// if(UINT_MAX != currentRestriction.viaNode) {
// cout << "restr from " << currentRestriction.from << " via ";
// cout << "node " << currentRestriction.viaNode;
// cout << " to " << currentRestriction.to << endl;
// }
if(!externalMemory->restrictionFunction(currentRestrictionContainer))
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}
}
}
inline void parseWay(_ThreadData * threadData) {
_Way w;
std::vector<_Way> waysToParse(threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size());
for(int i = 0, ways_size = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size(); i < ways_size; ++i) {
w.Clear();
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
w.id = inputWay.id();
unsigned pathNode(0);
for(int i = 0; i < inputWay.refs_size(); ++i) {
pathNode += inputWay.refs(i);
w.path.push_back(pathNode);
}
assert(inputWay.keys_size() == inputWay.vals_size());
for(int i = 0; i < inputWay.keys_size(); ++i) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(i));
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(i));
w.keyVals.Add(key, val);
}
waysToParse.push_back(w);
}
unsigned endi_ways = waysToParse.size();
#pragma omp parallel for schedule ( guided )
for(unsigned i = 0; i < endi_ways; ++i) {
_Way & w = waysToParse[i];
/** Pass the unpacked way to the LUA call back **/
try {
luabind::call_function<int>(
scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()),
"way_function",
boost::ref(w),
w.path.size()
);
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
// catch (...) {
// ERR("Unknown error!");
// }
}
BOOST_FOREACH(_Way & w, waysToParse) {
if(!externalMemory->wayFunction(w)) {
std::cerr << "[PBFParser] way not parsed" << std::endl;
}
}
}
inline void loadGroup(_ThreadData * threadData) {
#ifndef NDEBUG
++groupCount;
#endif
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
threadData->entityTypeIndicator = 0;
if ( group.nodes_size() != 0 ) {
threadData->entityTypeIndicator = TypeNode;
}
if ( group.ways_size() != 0 ) {
threadData->entityTypeIndicator = TypeWay;
}
if ( group.relations_size() != 0 ) {
threadData->entityTypeIndicator = TypeRelation;
}
if ( group.has_dense() ) {
threadData->entityTypeIndicator = TypeDenseNode;
assert( group.dense().id_size() != 0 );
}
assert( threadData->entityTypeIndicator != 0 );
}
inline void loadBlock(_ThreadData * threadData) {
#ifndef NDEBUG
++blockCount;
#endif
threadData->currentGroupID = 0;
threadData->currentEntityID = 0;
}
/* Reverses Network Byte Order into something usable, compiles down to a bswap-mov combination */
inline unsigned swapEndian(unsigned x) const {
if(getMachineEndianness() == LittleEndian)
return ( (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24) );
return x;
}
inline bool readPBFBlobHeader(std::fstream& stream, _ThreadData * threadData) {
int size(0);
stream.read((char *)&size, sizeof(int));
size = swapEndian(size);
if(stream.eof()) {
return false;
}
if ( size > MAX_BLOB_HEADER_SIZE || size < 0 ) {
return false;
}
char *data = new char[size];
stream.read(data, size*sizeof(data[0]));
bool dataSuccessfullyParsed = (threadData->PBFBlobHeader).ParseFromArray( data, size);
delete[] data;
return dataSuccessfullyParsed;
}
inline bool unpackZLIB(std::fstream &, _ThreadData * threadData) {
unsigned rawSize = threadData->PBFBlob.raw_size();
char* unpackedDataArray = new char[rawSize];
z_stream compressedDataStream;
compressedDataStream.next_in = ( unsigned char* ) threadData->PBFBlob.zlib_data().data();
compressedDataStream.avail_in = threadData->PBFBlob.zlib_data().size();
compressedDataStream.next_out = ( unsigned char* ) unpackedDataArray;
compressedDataStream.avail_out = rawSize;
compressedDataStream.zalloc = Z_NULL;
compressedDataStream.zfree = Z_NULL;
compressedDataStream.opaque = Z_NULL;
int ret = inflateInit( &compressedDataStream );
if ( ret != Z_OK ) {
std::cerr << "[error] failed to init zlib stream" << std::endl;
delete[] unpackedDataArray;
return false;
}
ret = inflate( &compressedDataStream, Z_FINISH );
if ( ret != Z_STREAM_END ) {
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
std::cerr << "[error] Error type: " << ret << std::endl;
delete[] unpackedDataArray;
return false;
}
ret = inflateEnd( &compressedDataStream );
if ( ret != Z_OK ) {
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
delete[] unpackedDataArray;
return false;
}
threadData->charBuffer.clear(); threadData->charBuffer.resize(rawSize);
std::copy(unpackedDataArray, unpackedDataArray + rawSize, threadData->charBuffer.begin());
delete[] unpackedDataArray;
return true;
}
inline bool unpackLZMA(std::fstream &, _ThreadData * ) const {
return false;
}
inline bool readBlob(std::fstream& stream, _ThreadData * threadData) {
if(stream.eof())
return false;
const int size = threadData->PBFBlobHeader.datasize();
if ( size < 0 || size > MAX_BLOB_SIZE ) {
std::cerr << "[error] invalid Blob size:" << size << std::endl;
return false;
}
char* data = new char[size];
stream.read(data, sizeof(data[0])*size);
if ( !threadData->PBFBlob.ParseFromArray( data, size ) ) {
std::cerr << "[error] failed to parse blob" << std::endl;
delete[] data;
return false;
}
if ( threadData->PBFBlob.has_raw() ) {
const std::string& data = threadData->PBFBlob.raw();
threadData->charBuffer.clear();
threadData->charBuffer.resize( data.size() );
std::copy(data.begin(), data.end(), threadData->charBuffer.begin());
} else if ( threadData->PBFBlob.has_zlib_data() ) {
if ( !unpackZLIB(stream, threadData) ) {
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
delete[] data;
return false;
}
} else if ( threadData->PBFBlob.has_lzma_data() ) {
if ( !unpackLZMA(stream, threadData) )
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
delete[] data;
return false;
} else {
std::cerr << "[error] Blob contains no data" << std::endl;
delete[] data;
return false;
}
delete[] data;
return true;
}
inline bool readNextBlock(std::fstream& stream, _ThreadData * threadData) {
if(stream.eof()) {
return false;
}
if ( !readPBFBlobHeader(stream, threadData) ){
return false;
}
if ( threadData->PBFBlobHeader.type() != "OSMData" ) {
return false;
}
if ( !readBlob(stream, threadData) ) {
return false;
}
if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) {
ERR("failed to parse PrimitiveBlock");
return false;
}
return true;
}
//Is optimized to a single 'mov eax,1' on GCC, clang and icc using -O3
inline Endianness getMachineEndianness() const {
int i(1);
char *p = (char *) &i;
if (1 == p[0])
return LittleEndian;
return BigEndian;
}
inline void loadGroup (_ThreadData * threadData);
inline void loadBlock (_ThreadData * threadData);
inline bool readPBFBlobHeader(std::fstream & stream, _ThreadData * threadData);
inline bool unpackZLIB (std::fstream & stream, _ThreadData * threadData);
inline bool unpackLZMA (std::fstream & stream, _ThreadData * threadData);
inline bool readBlob (std::fstream & stream, _ThreadData * threadData);
inline bool readNextBlock (std::fstream & stream, _ThreadData * threadData);
static const int NANO = 1000 * 1000 * 1000;
static const int MAX_BLOB_HEADER_SIZE = 64 * 1024;
static const int MAX_BLOB_SIZE = 32 * 1024 * 1024;
#ifndef NDEBUG
/* counting the number of read blocks and groups */
unsigned groupCount;
unsigned blockCount;
#endif
ExtractorCallbacks * externalMemory;
/* the input stream to parse */
std::fstream input;
/* ThreadData Queue */
std::fstream input; // the input stream to parse
boost::shared_ptr<ConcurrentQueue < _ThreadData* > > threadDataQueue;
ScriptingEnvironment scriptingEnvironment;
};
#endif /* PBFPARSER_H_ */
+85 -81
View File
@@ -1,40 +1,49 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ScriptingEnvironment.h"
#include "../typedefs.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(const char * fileName) {
INFO("Using script " << fileName);
SimpleLogger().Write() << "Using script " << fileName;
// Create a new lua state
for(int i = 0; i < omp_get_max_threads(); ++i)
for(int i = 0; i < omp_get_max_threads(); ++i) {
luaStateVector.push_back(luaL_newstate());
}
// Connect LuaBind to this lua state for all threads
#pragma omp parallel
@@ -44,69 +53,64 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
//open utility libraries string library;
luaL_openlibs(myLuaState);
luaAddScriptFolderToLoadPath( myLuaState, fileName );
// Add our function to the state's global scope
luabind::module(myLuaState) [
luabind::def("print", LUA_print<std::string>),
luabind::def("parseMaxspeed", parseMaxspeed),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration)
];
//#pragma omp critical
// {
// if(0 != luaL_dostring(
// myLuaState,
// "print('Initializing LUA engine')\n"
// )) {
// ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block");
// }
// }
luabind::module(myLuaState) [
luabind::class_<HashTable<std::string, std::string> >("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds)
];
luabind::module(myLuaState) [
luabind::class_<ImportNode>("Node")
.def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon)
.def_readwrite("id", &ImportNode::id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals)
];
luabind::module(myLuaState) [
luabind::class_<_Way>("Way")
.def(luabind::constructor<>())
.def_readwrite("name", &_Way::name)
.def_readwrite("speed", &_Way::speed)
.def_readwrite("type", &_Way::type)
.def_readwrite("access", &_Way::access)
.def_readwrite("roundabout", &_Way::roundabout)
.def_readwrite("is_duration_set", &_Way::isDurationSet)
.def_readwrite("is_access_restricted", &_Way::isAccessRestricted)
.def_readwrite("ignore_in_grid", &_Way::ignoreInGrid)
.def_readwrite("tags", &_Way::keyVals)
.def_readwrite("direction", &_Way::direction)
.enum_("constants")
[
luabind::value("notSure", 0),
luabind::value("oneway", 1),
luabind::value("bidirectional", 2),
luabind::value("opposite", 3)
]
luabind::def("print", LUA_print<std::string>),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration)
];
luabind::module(myLuaState) [
luabind::class_<HashTable<std::string, std::string> >("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds)
];
luabind::module(myLuaState) [
luabind::class_<ImportNode>("Node")
.def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon)
.def_readonly("id", &ImportNode::id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals)
];
luabind::module(myLuaState) [
luabind::class_<ExtractionWay>("Way")
.def(luabind::constructor<>())
.def_readonly("id", &ExtractionWay::id)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("speed", &ExtractionWay::speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("type", &ExtractionWay::type)
.def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.def_readwrite("tags", &ExtractionWay::keyVals)
.def_readwrite("direction", &ExtractionWay::direction)
.enum_("constants") [
luabind::value("notSure", 0),
luabind::value("oneway", 1),
luabind::value("bidirectional", 2),
luabind::value("opposite", 3)
]
];
// fails on c++11/OS X 10.9
luabind::module(myLuaState) [
luabind::class_<std::vector<std::string> >("vector")
.def("Add", static_cast<void (std::vector<std::string>::*)(const std::string&)>(&std::vector<std::string>::push_back))
];
// Now call our function in a lua script
//#pragma omp critical
// {
// INFO("Parsing speedprofile from " << fileName );
// }
if(0 != luaL_dofile(myLuaState, fileName) ) {
ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block");
throw OSRMException("ERROR occured in scripting block");
}
}
}
+25 -27
View File
@@ -1,43 +1,41 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SCRIPTINGENVIRONMENT_H_
#define SCRIPTINGENVIRONMENT_H_
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <luabind/luabind.hpp>
#include <vector>
#include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h"
#include "LuaUtil.h"
#include "../DataStructures/ImportNode.h"
struct lua_State;
class ScriptingEnvironment {
public:
ScriptingEnvironment();
ScriptingEnvironment(const char * fileName);
explicit ScriptingEnvironment(const char * fileName);
virtual ~ScriptingEnvironment();
lua_State * getLuaStateForThreadID(const int);
+348
View File
@@ -0,0 +1,348 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "XMLParser.h"
#include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/InputReaderFactory.h"
#include "../DataStructures/Restriction.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/ref.hpp>
XMLParser::XMLParser(const char *filename, ExtractorCallbacks *ec, ScriptingEnvironment &se)
: BaseParser(ec, se)
{
inputReader = inputReaderFactory(filename);
}
bool XMLParser::ReadHeader() { return (xmlTextReaderRead(inputReader) == 1); }
bool XMLParser::Parse()
{
while (xmlTextReaderRead(inputReader) == 1)
{
const int type = xmlTextReaderNodeType(inputReader);
// 1 is Element
if (type != 1)
{
continue;
}
xmlChar *currentName = xmlTextReaderName(inputReader);
if (currentName == NULL)
{
continue;
}
if (xmlStrEqual(currentName, (const xmlChar *)"node") == 1)
{
ImportNode n = ReadXMLNode();
ParseNodeInLua(n, lua_state);
extractor_callbacks->nodeFunction(n);
}
if (xmlStrEqual(currentName, (const xmlChar *)"way") == 1)
{
ExtractionWay way = ReadXMLWay();
ParseWayInLua(way, lua_state);
extractor_callbacks->wayFunction(way);
}
if (use_turn_restrictions && xmlStrEqual(currentName, (const xmlChar *)"relation") == 1)
{
InputRestrictionContainer r = ReadXMLRestriction();
if ((UINT_MAX != r.fromWay) && !extractor_callbacks->restrictionFunction(r))
{
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
}
}
xmlFree(currentName);
}
return true;
}
InputRestrictionContainer XMLParser::ReadXMLRestriction()
{
InputRestrictionContainer restriction;
std::string except_tag_string;
if (xmlTextReaderIsEmptyElement(inputReader) != 1)
{
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int childType = xmlTextReaderNodeType(inputReader);
if (childType != 1 && childType != 15)
{
continue;
}
const int childDepth = xmlTextReaderDepth(inputReader);
xmlChar *childName = xmlTextReaderName(inputReader);
if (childName == NULL)
{
continue;
}
if (depth == childDepth && childType == 15 &&
xmlStrEqual(childName, (const xmlChar *)"relation") == 1)
{
xmlFree(childName);
break;
}
if (childType != 1)
{
xmlFree(childName);
continue;
}
if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
{
xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (k != NULL && value != NULL)
{
if (xmlStrEqual(k, (const xmlChar *)"restriction") &&
(0 == std::string((const char *)value).find("only_")))
{
restriction.restriction.flags.isOnly = true;
}
if (xmlStrEqual(k, (const xmlChar *)"except"))
{
except_tag_string = (const char *)value;
}
}
if (k != NULL)
{
xmlFree(k);
}
if (value != NULL)
{
xmlFree(value);
}
}
else if (xmlStrEqual(childName, (const xmlChar *)"member") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != NULL)
{
xmlChar *role = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"role");
xmlChar *type = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"type");
if (xmlStrEqual(role, (const xmlChar *)"to") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.toWay = stringToUint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"from") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.fromWay = stringToUint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"via") &&
xmlStrEqual(type, (const xmlChar *)"node"))
{
restriction.restriction.viaNode = stringToUint((const char *)ref);
}
if (NULL != type)
{
xmlFree(type);
}
if (NULL != role)
{
xmlFree(role);
}
if (NULL != ref)
{
xmlFree(ref);
}
}
}
xmlFree(childName);
}
}
if (ShouldIgnoreRestriction(except_tag_string))
{
restriction.fromWay = UINT_MAX; // workaround to ignore the restriction
}
return restriction;
}
ExtractionWay XMLParser::ReadXMLWay()
{
ExtractionWay way;
if (xmlTextReaderIsEmptyElement(inputReader) != 1)
{
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int childType = xmlTextReaderNodeType(inputReader);
if (childType != 1 && childType != 15)
{
continue;
}
const int childDepth = xmlTextReaderDepth(inputReader);
xmlChar *childName = xmlTextReaderName(inputReader);
if (childName == NULL)
{
continue;
}
if (depth == childDepth && childType == 15 &&
xmlStrEqual(childName, (const xmlChar *)"way") == 1)
{
xmlChar *id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
way.id = stringToUint((char *)id);
xmlFree(id);
xmlFree(childName);
break;
}
if (childType != 1)
{
xmlFree(childName);
continue;
}
if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
{
xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (k != NULL && value != NULL)
{
way.keyVals.Add(std::string((char *)k), std::string((char *)value));
}
if (k != NULL)
{
xmlFree(k);
}
if (value != NULL)
{
xmlFree(value);
}
}
else if (xmlStrEqual(childName, (const xmlChar *)"nd") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != NULL)
{
way.path.push_back(stringToUint((const char *)ref));
xmlFree(ref);
}
}
xmlFree(childName);
}
}
return way;
}
ImportNode XMLParser::ReadXMLNode()
{
ImportNode node;
xmlChar *attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lat");
if (attribute != NULL)
{
node.lat = COORDINATE_PRECISION * StringToDouble((const char *)attribute);
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lon");
if (attribute != NULL)
{
node.lon = COORDINATE_PRECISION * StringToDouble((const char *)attribute);
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
if (attribute != NULL)
{
node.id = stringToUint((const char *)attribute);
xmlFree(attribute);
}
if (xmlTextReaderIsEmptyElement(inputReader) != 1)
{
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int childType = xmlTextReaderNodeType(inputReader);
// 1 = Element, 15 = EndElement
if (childType != 1 && childType != 15)
{
continue;
}
const int childDepth = xmlTextReaderDepth(inputReader);
xmlChar *childName = xmlTextReaderName(inputReader);
if (childName == NULL)
{
continue;
}
if (depth == childDepth && childType == 15 &&
xmlStrEqual(childName, (const xmlChar *)"node") == 1)
{
xmlFree(childName);
break;
}
if (childType != 1)
{
xmlFree(childName);
continue;
}
if (xmlStrEqual(childName, (const xmlChar *)"tag") == 1)
{
xmlChar *k = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (k != NULL && value != NULL)
{
node.keyVals.emplace(std::string((char *)(k)),
std::string((char *)(value)));
}
if (k != NULL)
{
xmlFree(k);
}
if (value != NULL)
{
xmlFree(value);
}
}
xmlFree(childName);
}
}
return node;
}
+35 -293
View File
@@ -1,308 +1,50 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef XMLPARSER_H_
#define XMLPARSER_H_
#include <boost/ref.hpp>
#include "ExtractorCallbacks.h"
#include "BaseParser.h"
#include <libxml/xmlreader.h>
#include "../typedefs.h"
#include "BaseParser.h"
#include "ExtractorStructs.h"
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/InputReaderFactory.h"
class XMLParser : public BaseParser
{
public:
XMLParser(const char *filename, ExtractorCallbacks *ec, ScriptingEnvironment &se);
bool ReadHeader();
bool Parse();
class XMLParser : public BaseParser<ExtractorCallbacks, _Node, _RawRestrictionContainer, _Way> {
public:
XMLParser(const char * filename) : externalMemory(NULL), myLuaState(NULL){
WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf");
inputReader = inputReaderFactory(filename);
}
virtual ~XMLParser() {}
void RegisterCallbacks(ExtractorCallbacks * em) {
externalMemory = em;
}
void RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
myLuaState = _se.getLuaStateForThreadID(0);
}
bool Init() {
return (xmlTextReaderRead( inputReader ) == 1);
}
bool Parse() {
while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int type = xmlTextReaderNodeType( inputReader );
//1 is Element
if ( type != 1 )
continue;
xmlChar* currentName = xmlTextReaderName( inputReader );
if ( currentName == NULL )
continue;
if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) {
ImportNode n = _ReadXMLNode( );
/** Pass the unpacked node to the LUA call back **/
try {
luabind::call_function<int>(
myLuaState,
"node_function",
boost::ref(n)
);
if(!externalMemory->nodeFunction(n))
std::cerr << "[XMLParser] dense node not parsed" << std::endl;
} catch (const luabind::error &er) {
cerr << er.what() << endl;
lua_State* Ler=er.state();
report_errors(Ler, -1);
} catch (std::exception & e) {
ERR(e.what());
} catch (...) {
ERR("Unknown error occurred during XML node parsing!");
}
}
if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) {
string name;
_Way way = _ReadXMLWay( );
/** Pass the unpacked way to the LUA call back **/
try {
luabind::call_function<int>(
myLuaState,
"way_function",
boost::ref(way),
way.path.size()
);
if(!externalMemory->wayFunction(way)) {
std::cerr << "[PBFParser] way not parsed" << std::endl;
}
} catch (const luabind::error &er) {
cerr << er.what() << endl;
lua_State* Ler=er.state();
report_errors(Ler, -1);
} catch (std::exception & e) {
ERR(e.what());
} catch (...) {
ERR("Unknown error occurred during XML way parsing!");
}
}
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
_RawRestrictionContainer r = _ReadXMLRestriction();
if(r.fromWay != UINT_MAX) {
if(!externalMemory->restrictionFunction(r)) {
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
}
}
}
xmlFree( currentName );
}
return true;
}
private:
_RawRestrictionContainer _ReadXMLRestriction ( ) {
_RawRestrictionContainer restriction;
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
const int depth = xmlTextReaderDepth( inputReader );while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int childType = xmlTextReaderNodeType( inputReader );
if ( childType != 1 && childType != 15 )
continue;
const int childDepth = xmlTextReaderDepth( inputReader );
xmlChar* childName = xmlTextReaderName( inputReader );
if ( childName == NULL )
continue;
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "relation" ) == 1 ) {
xmlFree( childName );
break;
}
if ( childType != 1 ) {
xmlFree( childName );
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
if ( k != NULL && value != NULL ) {
if(xmlStrEqual(k, ( const xmlChar* ) "restriction" )){
if(0 == std::string((const char *) value).find("only_"))
restriction.restriction.flags.isOnly = true;
}
}
if ( k != NULL )
xmlFree( k );
if ( value != NULL )
xmlFree( value );
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "member" ) == 1 ) {
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
if ( ref != NULL ) {
xmlChar * role = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "role" );
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" );
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) {
restriction.toWay = atoi((const char*) ref);
}
if(xmlStrEqual(role, (const xmlChar *) "from") && xmlStrEqual(type, (const xmlChar *) "way")) {
restriction.fromWay = atoi((const char*) ref);
}
if(xmlStrEqual(role, (const xmlChar *) "via") && xmlStrEqual(type, (const xmlChar *) "node")) {
restriction.restriction.viaNode = atoi((const char*) ref);
}
if(NULL != type)
xmlFree( type );
if(NULL != role)
xmlFree( role );
if(NULL != ref)
xmlFree( ref );
}
}
xmlFree( childName );
}
}
return restriction;
}
_Way _ReadXMLWay( ) {
_Way way;
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
const int depth = xmlTextReaderDepth( inputReader );
while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int childType = xmlTextReaderNodeType( inputReader );
if ( childType != 1 && childType != 15 )
continue;
const int childDepth = xmlTextReaderDepth( inputReader );
xmlChar* childName = xmlTextReaderName( inputReader );
if ( childName == NULL )
continue;
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
way.id = atoi((char*)id);
xmlFree(id);
xmlFree( childName );
break;
}
if ( childType != 1 ) {
xmlFree( childName );
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
// cout << "->k=" << k << ", v=" << value << endl;
if ( k != NULL && value != NULL ) {
way.keyVals.Add(std::string( (char *) k ), std::string( (char *) value));
}
if ( k != NULL )
xmlFree( k );
if ( value != NULL )
xmlFree( value );
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
if ( ref != NULL ) {
way.path.push_back( atoi(( const char* ) ref ) );
xmlFree( ref );
}
}
xmlFree( childName );
}
}
return way;
}
ImportNode _ReadXMLNode( ) {
ImportNode node;
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
if ( attribute != NULL ) {
node.lat = static_cast<NodeID>(100000.*atof(( const char* ) attribute ) );
xmlFree( attribute );
}
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
if ( attribute != NULL ) {
node.lon = static_cast<NodeID>(100000.*atof(( const char* ) attribute ));
xmlFree( attribute );
}
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
if ( attribute != NULL ) {
node.id = atoi(( const char* ) attribute );
xmlFree( attribute );
}
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
const int depth = xmlTextReaderDepth( inputReader );
while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int childType = xmlTextReaderNodeType( inputReader );
// 1 = Element, 15 = EndElement
if ( childType != 1 && childType != 15 )
continue;
const int childDepth = xmlTextReaderDepth( inputReader );
xmlChar* childName = xmlTextReaderName( inputReader );
if ( childName == NULL )
continue;
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) {
xmlFree( childName );
break;
}
if ( childType != 1 ) {
xmlFree( childName );
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
if ( k != NULL && value != NULL ) {
node.keyVals.Add(std::string( reinterpret_cast<char*>(k) ), std::string( reinterpret_cast<char*>(value)));
}
if ( k != NULL )
xmlFree( k );
if ( value != NULL )
xmlFree( value );
}
xmlFree( childName );
}
}
return node;
}
/* Input Reader */
private:
InputRestrictionContainer ReadXMLRestriction();
ExtractionWay ReadXMLWay();
ImportNode ReadXMLNode();
xmlTextReaderPtr inputReader;
//holds the callback functions and storage for our temporary data
ExtractorCallbacks * externalMemory;
lua_State *myLuaState;
};
#endif /* XMLPARSER_H_ */
+15 -15
View File
@@ -1,23 +1,23 @@
GEM
remote: http://rubygems.org/
specs:
builder (3.0.0)
cucumber (1.1.4)
builder (3.2.2)
cucumber (1.3.8)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
gherkin (~> 2.7.1)
json (>= 1.4.6)
term-ansicolor (>= 1.0.6)
diff-lcs (1.1.3)
gherkin (2.7.6)
json (>= 1.4.6)
json (1.6.5)
diff-lcs (>= 1.1.3)
gherkin (~> 2.12.1)
multi_json (>= 1.7.5, < 2.0)
multi_test (>= 0.0.2)
diff-lcs (1.2.4)
gherkin (2.12.1)
multi_json (~> 1.3)
multi_json (1.8.0)
multi_test (0.0.2)
osmlib-base (0.1.4)
rake (0.9.2.2)
rspec-expectations (2.11.3)
diff-lcs (~> 1.1.3)
sys-proctable (0.9.1)
term-ansicolor (1.0.7)
rake (10.1.0)
rspec-expectations (2.14.3)
diff-lcs (>= 1.1.3, < 2.0)
sys-proctable (0.9.3)
PLATFORMS
ruby
+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_ */
+45
View File
@@ -0,0 +1,45 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HTTP_HEADER_H
#define HTTP_HEADER_H
#include <string>
namespace http {
struct Header {
std::string name;
std::string value;
void Clear() {
name.clear();
value.clear();
}
};
}
#endif //HTTP_HEADER_H
+73
View File
@@ -0,0 +1,73 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef REPLY_H
#define REPLY_H
#include "Header.h"
#include <boost/asio.hpp>
#include <vector>
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;
std::vector<Header> headers;
std::vector<boost::asio::const_buffer> toBuffers();
std::vector<boost::asio::const_buffer> HeaderstoBuffers();
std::vector<std::string> content;
static Reply StockReply(status_type status);
void setSize(const unsigned size);
void SetUncompressedSize();
Reply();
private:
std::string ToString(Reply::status_type status);
boost::asio::const_buffer ToBuffer(Reply::status_type status);
};
}
#endif //REPLY_H
+125
View File
@@ -0,0 +1,125 @@
/*
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 ROUTE_PARAMETERS_H
#define ROUTE_PARAMETERS_H
#include <osrm/Coordinate.h>
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <string>
#include <vector>
struct RouteParameters {
RouteParameters() :
zoomLevel(18),
printInstructions(false),
alternateRoute(true),
geometry(true),
compression(true),
deprecatedAPI(false),
checkSum(-1)
{ }
short zoomLevel;
bool printInstructions;
bool alternateRoute;
bool geometry;
bool compression;
bool deprecatedAPI;
unsigned checkSum;
std::string service;
std::string outputFormat;
std::string jsonpParameter;
std::string language;
std::vector<std::string> hints;
std::vector<FixedPointCoordinate> coordinates;
void setZoomLevel(const short i) {
if (18 >= i && 0 <= i) {
zoomLevel = i;
}
}
void setAlternateRouteFlag(const bool b) {
alternateRoute = b;
}
void setDeprecatedAPIFlag(const std::string &) {
deprecatedAPI = true;
}
void setChecksum(const unsigned c) {
checkSum = c;
}
void setInstructionFlag(const bool b) {
printInstructions = b;
}
void setService( const std::string & s) {
service = s;
}
void setOutputFormat(const std::string & s) {
outputFormat = s;
}
void setJSONpParameter(const std::string & s) {
jsonpParameter = s;
}
void addHint(const std::string & s) {
hints.resize( coordinates.size() );
if( !hints.empty() ) {
hints.back() = s;
}
}
void setLanguage(const std::string & s) {
language = s;
}
void setGeometryFlag(const bool b) {
geometry = b;
}
void setCompressionFlag(const bool b) {
compression = b;
}
void addCoordinate(const boost::fusion::vector < double, double > & arg_) {
int lat = COORDINATE_PRECISION*boost::fusion::at_c < 0 > (arg_);
int lon = COORDINATE_PRECISION*boost::fusion::at_c < 1 > (arg_);
coordinates.push_back(FixedPointCoordinate(lat, lon));
}
};
#endif /*ROUTE_PARAMETERS_H*/
+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
+22 -661
View File
@@ -1,661 +1,22 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.
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.
+49
View File
@@ -0,0 +1,49 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OSRM_H
#define OSRM_H
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <osrm/ServerPaths.h>
class OSRM_impl;
class OSRM {
private:
OSRM_impl * OSRM_pimpl_;
public:
explicit OSRM(
const ServerPaths & paths,
const bool use_shared_memory = false
);
~OSRM();
void RunQuery(RouteParameters & route_parameters, http::Reply & reply);
};
#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
+43 -21
View File
@@ -1,41 +1,63 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BASEPLUGIN_H_
#define BASEPLUGIN_H_
#include <cassert>
#include "../Util/StringUtil.h"
#include <osrm/Coordinate.h>
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <boost/foreach.hpp>
#include <string>
#include <vector>
#include "RouteParameters.h"
#include "../Server/BasicDatastructures.h"
class BasePlugin {
public:
BasePlugin() { }
//Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BasePlugin() { }
virtual std::string GetDescriptor() const = 0;
virtual std::string GetVersionString() const = 0 ;
virtual const std::string & GetDescriptor() const = 0;
virtual void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) = 0;
inline bool checkCoord(const FixedPointCoordinate & c) {
if(
c.lat > 90*COORDINATE_PRECISION ||
c.lat < -90*COORDINATE_PRECISION ||
c.lon > 180*COORDINATE_PRECISION ||
c.lon < -180*COORDINATE_PRECISION
) {
return false;
}
return true;
}
};
#endif /* BASEPLUGIN_H_ */
+81 -30
View File
@@ -1,50 +1,101 @@
/*
* LocatePlugin.h
*
* Created on: 01.01.2011
* Author: dennis
*/
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 HELLOWORLDPLUGIN_H_
#define HELLOWORLDPLUGIN_H_
#include <sstream>
#include "BasePlugin.h"
#include "RouteParameters.h"
#include "../Util/StringUtil.h"
#include <string>
class HelloWorldPlugin : public BasePlugin {
private:
std::string temp_string;
public:
HelloWorldPlugin() {}
virtual ~HelloWorldPlugin() { /*std::cout << GetDescriptor() << " destructor" << std::endl;*/ }
std::string GetDescriptor() const { return std::string("hello"); }
std::string GetVersionString() const { return std::string("0.1a"); }
HelloWorldPlugin() : descriptor_string("hello"){}
virtual ~HelloWorldPlugin() { }
const std::string & GetDescriptor() const { return descriptor_string; }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
reply.status = http::Reply::ok;
reply.content.append("<html><head><title>Hello World Demonstration Document</title></head><body><h1>Hello, World!</h1>");
std::stringstream content;
content << "<pre>";
content << "zoom level: " << routeParameters.zoomLevel << "\n";
content << "checksum: " << routeParameters.checkSum << "\n";
content << "instructions: " << (routeParameters.printInstructions ? "yes" : "no") << "\n";
content << "geometry: " << (routeParameters.geometry ? "yes" : "no") << "\n";
content << "compression: " << (routeParameters.compression ? "yes" : "no") << "\n";
content << "output format: " << routeParameters.outputFormat << "\n";
content << "json parameter: " << routeParameters.jsonpParameter << "\n";
content << "language: " << routeParameters.language << "<br>";
content << "Number of locations: " << routeParameters.coordinates.size() << "\n";
reply.content.push_back("<html><head><title>Hello World Demonstration Document</title></head><body><h1>Hello, World!</h1>");
reply.content.push_back("<pre>");
reply.content.push_back("zoom level: ");
intToString(routeParameters.zoomLevel, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\nchecksum: ");
intToString(routeParameters.checkSum, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\ninstructions: ");
reply.content.push_back((routeParameters.printInstructions ? "yes" : "no"));
reply.content.push_back(temp_string);
reply.content.push_back("\ngeometry: ");
reply.content.push_back((routeParameters.geometry ? "yes" : "no"));
reply.content.push_back("\ncompression: ");
reply.content.push_back((routeParameters.compression ? "yes" : "no"));
reply.content.push_back("\noutput format: ");
reply.content.push_back(routeParameters.outputFormat);
reply.content.push_back("\njson parameter: ");
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("\nlanguage: ");
reply.content.push_back(routeParameters.language);
reply.content.push_back("\nNumber of locations: ");
intToString(routeParameters.coordinates.size(), temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\n");
for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) {
content << " [" << i << "] " << routeParameters.coordinates[i].lat/100000. << "," << routeParameters.coordinates[i].lon/100000. << "\n";
reply.content.push_back( " [");
intToString(i, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("] ");
doubleToString(routeParameters.coordinates[i].lat/COORDINATE_PRECISION, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back(",");
doubleToString(routeParameters.coordinates[i].lon/COORDINATE_PRECISION, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\n");
}
content << "Number of hints: " << routeParameters.hints.size() << "\n";
reply.content.push_back( "Number of hints: ");
intToString(routeParameters.hints.size(), temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("\n");
for(unsigned i = 0; i < routeParameters.hints.size(); ++i) {
content << " [" << i << "] " << routeParameters.hints[i] << "\n";
reply.content.push_back( " [");
intToString(i, temp_string);
reply.content.push_back(temp_string);
reply.content.push_back("] ");
reply.content.push_back(routeParameters.hints[i]);
reply.content.push_back("\n");
}
content << "</pre>";
reply.content.append(content.str());
reply.content.append("</body></html>");
reply.content.push_back( "</pre></body></html>");
}
private:
std::string descriptor_string;
};
#endif /* HELLOWORLDPLUGIN_H_ */
+72 -64
View File
@@ -1,89 +1,98 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LOCATEPLUGIN_H_
#define LOCATEPLUGIN_H_
#include <fstream>
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "BasePlugin.h"
#include "RouteParameters.h"
#include "../Util/StringUtil.h"
#include "../DataStructures/NodeInformationHelpDesk.h"
/*
* This Plugin locates the nearest node in the road network for a given coordinate.
*/
//locates the nearest node in the road network for a given coordinate.
template<class DataFacadeT>
class LocatePlugin : public BasePlugin {
public:
LocatePlugin(QueryObjectsStorage * objects) {
nodeHelpDesk = objects->nodeHelpDesk;
}
std::string GetDescriptor() const { return std::string("locate"); }
std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
explicit LocatePlugin(DataFacadeT * facade)
:
descriptor_string("locate"),
facade(facade)
{ }
const std::string & GetDescriptor() const { return descriptor_string; }
void HandleRequest(
const RouteParameters & routeParameters,
http::Reply& reply
) {
//check number of parameters
if(!routeParameters.coordinates.size()) {
reply = http::Reply::stockReply(http::Reply::badRequest);
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
if(false == checkCoord(routeParameters.coordinates[0])) {
reply = http::Reply::stockReply(http::Reply::badRequest);
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
//query to helpdesk
_Coordinate result;
std::string JSONParameter, tmp;
FixedPointCoordinate result;
std::string tmp;
//json
// JSONParameter = routeParameters.options.Find("jsonp");
if("" != routeParameters.jsonpParameter) {
reply.content += JSONParameter;
reply.content += "(";
if(!routeParameters.jsonpParameter.empty()) {
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
reply.status = http::Reply::ok;
reply.content += ("{");
reply.content += ("\"version\":0.3,");
if(!nodeHelpDesk->FindNearestNodeCoordForLatLon(routeParameters.coordinates[0], result)) {
reply.content += ("\"status\":207,");
reply.content += ("\"mapped_coordinate\":[]");
reply.content.push_back ("{");
if(
!facade->LocateClosestEndPointForCoordinate(
routeParameters.coordinates[0],
result
)
) {
reply.content.push_back ("\"status\":207,");
reply.content.push_back ("\"mapped_coordinate\":[]");
} else {
//Write coordinate to stream
reply.status = http::Reply::ok;
reply.content += ("\"status\":0,");
reply.content += ("\"mapped_coordinate\":");
convertInternalLatLonToString(result.lat, tmp);
reply.content += "[";
reply.content += tmp;
convertInternalLatLonToString(result.lon, tmp);
reply.content += ",";
reply.content += tmp;
reply.content += "]";
reply.content.push_back ("\"status\":0,");
reply.content.push_back ("\"mapped_coordinate\":");
FixedPointCoordinate::convertInternalLatLonToString(result.lat, tmp);
reply.content.push_back("[");
reply.content.push_back(tmp);
FixedPointCoordinate::convertInternalLatLonToString(result.lon, tmp);
reply.content.push_back(",");
reply.content.push_back(tmp);
reply.content.push_back("]");
}
reply.content += ",\"transactionId\": \"OSRM Routing Engine JSON Locate (v0.3)\"";
reply.content += ("}");
reply.content.push_back("}");
reply.headers.resize(3);
if("" != JSONParameter) {
reply.content += ")";
if(!routeParameters.jsonpParameter.empty()) {
reply.content.push_back( ")");
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
@@ -95,19 +104,18 @@ public:
reply.headers[2].value = "attachment; filename=\"location.json\"";
}
reply.headers[0].name = "Content-Length";
intToString(reply.content.size(), tmp);
unsigned content_length = 0;
BOOST_FOREACH(const std::string & snippet, reply.content) {
content_length += snippet.length();
}
intToString(content_length, tmp);
reply.headers[0].value = tmp;
return;
}
private:
inline bool checkCoord(const _Coordinate & c) {
if(c.lat > 90*100000 || c.lat < -90*100000 || c.lon > 180*100000 || c.lon <-180*100000) {
return false;
}
return true;
}
NodeInformationHelpDesk * nodeHelpDesk;
private:
std::string descriptor_string;
DataFacadeT * facade;
};
#endif /* LOCATEPLUGIN_H_ */

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