Compare commits

...

172 Commits

Author SHA1 Message Date
Dennis Luxen 7b0b378abc fix a performance regression 2014-05-07 10:35:56 +02:00
Dennis Luxen a1ecab2f95 refactor xml parser, uses faster string to double conversion 2014-04-29 16:05:34 +02:00
Dennis Luxen b7704f0c7f fix regression that seg faults if path not found 2014-04-29 11:46:05 +02:00
Dennis Luxen d6962f3a09 fix geometry load on shared memory 2014-04-29 09:50:29 +02:00
Dennis Luxen e44ebe0743 minor refactoring of code layout 2014-04-28 19:37:42 +02:00
Dennis Luxen f02ec41fbc move raw pointer to smart ptrs 2014-04-28 19:37:23 +02:00
Dennis Luxen d0b4ffd154 fix openmp woes on linux 2014-04-28 18:23:56 +02:00
Dennis Luxen 265af1f790 minor refactoring 2014-04-28 17:27:15 +02:00
Dennis Luxen 241d6b482e reenable traffic signal penalty in car profile 2014-04-28 17:26:31 +02:00
Dennis Luxen 45f0af2afc remove unnecessary else statements 2014-04-28 15:08:54 +02:00
Dennis Luxen 7955066d5c remove bitwise operator in conditional 2014-04-28 15:06:26 +02:00
Dennis Luxen ec3f9695cd remove redundant local variable 2014-04-28 13:26:20 +02:00
Dennis Luxen 018c144c76 minor refactoring 2014-04-28 13:19:35 +02:00
Dennis Luxen 56e88b2a56 minor refactoring 2014-04-28 13:19:26 +02:00
Dennis Luxen a2bdc5d8d9 minor refactoring 2014-04-28 13:08:25 +02:00
Dennis Luxen 1b257f7547 fix inverted logic 2014-04-28 13:03:20 +02:00
Dennis Luxen 5d6b05979d remove unused variable 2014-04-28 12:59:24 +02:00
Dennis Luxen 538f8d040a avoid short variable name 2014-04-28 12:58:40 +02:00
Dennis Luxen 7d52aa1272 avoid short variable name 2014-04-28 12:58:00 +02:00
Dennis Luxen d316202834 avoid private static function 2014-04-28 12:56:32 +02:00
Dennis Luxen 0167dfc3c9 shorten line 2014-04-28 12:54:11 +02:00
Dennis Luxen 02dc3dee04 shorten line 2014-04-28 12:52:55 +02:00
Dennis Luxen a5d3bc9578 make function call more legible 2014-04-28 12:52:06 +02:00
Dennis Luxen cfbc6b0441 remove useless parantheses 2014-04-28 12:50:44 +02:00
Dennis Luxen 8c5f8e995e stream-lined error messages: partially implements #986 2014-04-28 11:55:46 +02:00
Dennis Luxen b77dd6699d Merge pull request #992 from DennisOSRM/feature/remove_geometry
Feature/remove geometry
2014-04-28 11:34:49 +02:00
Dennis Luxen 9a153708e6 minor reformatting / shaping up 2014-04-25 16:00:39 +02:00
Dennis Luxen e0027a78e1 fix signed unsigned comparison 2014-04-25 15:48:10 +02:00
Dennis Luxen 51e8113a69 make tests use fuzzy matching instead of tweaked expectations 2014-04-25 15:24:18 +02:00
Dennis Luxen 78f5753a3a fix signed/unsigned comparison 2014-04-25 14:42:06 +02:00
Dennis Luxen 16ca8da438 remove deactivated debug out for good 2014-04-25 13:31:08 +02:00
Dennis Luxen ca6515c58a fix tests to reflect proper rounding of travel times 2014-04-25 13:23:27 +02:00
Dennis Luxen 2ec952032a fix rounding of travel times 2014-04-25 13:22:58 +02:00
Dennis Luxen b0b67a0cdc fix typo setting potentially wrong flags in debug build 2014-04-24 18:14:35 +02:00
Dennis Luxen 0eed39cdf1 rebase branch onto develop 2014-04-24 18:13:50 +02:00
Dennis Luxen ace59411cb fix and/or remove unused variables 2014-04-24 13:31:04 +02:00
Dennis Luxen ef7619d664 fix signed/unsigned comparison 2014-04-24 13:31:04 +02:00
Dennis Luxen 0f8a32f38c shape up code 2014-04-24 13:31:04 +02:00
Dennis Luxen c6a58ff1b4 remove debug lint again 2014-04-24 13:31:04 +02:00
Dennis Luxen 45f751720a fix unpacking of geometry for shared memory 2014-04-24 13:31:04 +02:00
Dennis Luxen ca016e2818 fix unpacking of geometry for shared memory 2014-04-24 13:31:04 +02:00
Dennis Luxen 5da01946b8 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen 8b3002a685 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen ede5cca2e7 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen d0e158ca07 fix unpacking of geometry for shared memory 2014-04-24 13:17:11 +02:00
Dennis Luxen 09dc21af31 remove debug lint 2014-04-24 13:17:11 +02:00
Dennis Luxen 2435fadfbd use boost filesystem specialization instead of the ones from std 2014-04-24 13:15:26 +02:00
Dennis Luxen edef9c11f7 add default clause to switch statement albeit technically superflous 2014-04-24 13:06:57 +02:00
Dennis Luxen 2c9edcaf23 remove debug code 2014-04-24 13:06:57 +02:00
Dennis Luxen 18861d58b5 compile fix for linux / wrong include 2014-04-24 13:06:57 +02:00
Dennis Luxen 9b3dab8055 implement loading of compressed geometries 2014-04-24 13:06:56 +02:00
Dennis Luxen 7a6a5f6612 implement population of shared vector<bool> overload (manually, yikes) 2014-04-24 13:06:56 +02:00
Dennis Luxen f468fcc2b6 implement more details of shared memory store 2014-04-24 13:06:56 +02:00
Dennis Luxen 5d93c68790 remove further debug things 2014-04-24 13:06:56 +02:00
Dennis Luxen fa04706484 remove debug code, add C++11 todo 2014-04-24 13:06:56 +02:00
Dennis Luxen d09be5a80e remove debug code, make variables const 2014-04-24 13:06:56 +02:00
Dennis Luxen a4d6e5c9cc reformat geometry compressor according to new guidelines 2014-04-24 13:06:56 +02:00
Dennis Luxen 4f85fd28cf add todo for the switch to C++11 2014-04-24 13:06:56 +02:00
Dennis Luxen 39914cd933 remove some debug code 2014-04-24 13:06:56 +02:00
Dennis Luxen 038e8cc8b8 remove unneeded edge-offset during query 2014-04-24 13:06:55 +02:00
Dennis Luxen db5fd5506d partial implementation of new datastore functions 2014-04-24 13:06:55 +02:00
Dennis Luxen f2be495e95 implement shared data facade geometry loader and getter functions 2014-04-24 13:06:55 +02:00
Dennis Luxen 6d8465a04d implement geometry uncompressing using STL 2014-04-24 13:06:55 +02:00
Dennis Luxen 4bb5270f25 cut back debug verbosity 2014-04-24 13:06:55 +02:00
Dennis Luxen 0f06c71796 remove debug output 2014-04-24 13:06:55 +02:00
Dennis Luxen 5b8d8a83dd fix mangled offsets and edge weights on compressed edges (all tests passing) 2014-04-24 13:06:55 +02:00
Dennis Luxen 8ec3d549a6 further fixes but forward/reverse edge weights are reversed 2014-04-24 13:06:55 +02:00
Dennis Luxen 394e369b54 fix edge-expanded offsets 2014-04-24 13:06:55 +02:00
Dennis Luxen 899ab9ddc0 remove some uncommented code 2014-04-24 13:06:54 +02:00
Dennis Luxen 8ae467985f turn off colored logging if output is redirected to file 2014-04-24 13:06:54 +02:00
Dennis Luxen 9ccc8a7404 remove first segment if distance is 0 (down to 7 failed) 2014-04-24 12:55:53 +02:00
Dennis Luxen 0b89a9d554 ignore last edge-expanded segment if it spans over to undistinguishable node-based nodes (down to 9 failed) 2014-04-24 12:55:53 +02:00
Dennis Luxen 752fb880be switch edge-expanded street name indexes to be first segment names (18 failed tests left) 2014-04-24 12:55:53 +02:00
Dennis Luxen 549bcb502b minor renaming efforts 2014-04-24 12:55:53 +02:00
Dennis Luxen 44077cb007 refactor and streamline use of TurnInstructionsClass members 2014-04-24 12:55:53 +02:00
Dennis Luxen 7b5902a580 rename phantom nodes members 2014-04-24 12:55:53 +02:00
Dennis Luxen 2861bacd2a fix check for invalid phantom nodes (20 failed left) 2014-04-24 12:55:53 +02:00
Dennis Luxen 776ac3bb2a remove superflous include 2014-04-24 12:55:52 +02:00
Dennis Luxen b429d9f509 remove unreachable code 2014-04-24 12:55:52 +02:00
Dennis Luxen 26397e4692 remove debug output 2014-04-24 12:55:52 +02:00
Dennis Luxen 48d23194af fix traffic signal penalty in compressed graph 2014-04-24 12:55:52 +02:00
Dennis Luxen bcaea1a617 remove debug output 2014-04-24 12:54:25 +02:00
Dennis Luxen 12b43d206c unpack properly when source and target are reversed on same edge 2014-04-24 12:54:24 +02:00
Dennis Luxen 9cc49f6ff3 remove debug output 2014-04-24 12:54:24 +02:00
Dennis Luxen 87f036e538 fixing sentinel nodes in adjacency list graph data structure 2014-04-24 12:54:24 +02:00
Dennis Luxen fdebec6448 correct partial distances 2014-04-24 12:51:18 +02:00
Dennis Luxen ba37836e24 allow graphs with zero edges to load 2014-04-24 12:51:18 +02:00
Dennis Luxen b60cfd9294 last segment gets it proper name now 2014-04-24 12:51:17 +02:00
Dennis Luxen bc0665cd9f fix offsets for start and end 2014-04-24 12:51:17 +02:00
Dennis Luxen 0dbe5e6593 fix shortest ch query for certain cases 2014-04-24 12:51:17 +02:00
Dennis Luxen 9b33aaa11a fix test for borked lat/lons 2014-04-24 12:51:17 +02:00
Dennis Luxen 024b78da7c Forward decl to cut compile times 2014-04-24 12:51:17 +02:00
Dennis Luxen 2a64297506 Forward decl to cut compile times 2014-04-24 12:51:17 +02:00
Dennis Luxen 09c76939f1 minor code beauty issue 2014-04-24 12:51:17 +02:00
Dennis Luxen 0b3f3bdf92 fix test for borked lat/lons 2014-04-24 12:51:17 +02:00
Dennis Luxen 3b29eeb6b6 unpacking start and target edge fixes plus some refactoring 2014-04-24 12:51:16 +02:00
Dennis Luxen 985270bb02 parse maxspeed in LUA 2014-04-24 12:51:16 +02:00
Dennis Luxen 6b91d6692f unpacking target correctly, also partial unpacking origin and destination are on the very same packed edge 2014-04-24 12:47:36 +02:00
Dennis Luxen eca09e6c81 unpacking of target segment works 2014-04-24 12:47:00 +02:00
Dennis Luxen 874c579f86 correctly unpacking the first segment 2014-04-24 12:15:48 +02:00
Dennis Luxen a0bddab169 3/4 unpack cases working 2014-04-24 12:15:04 +02:00
Dennis Luxen b679a94930 first segment needs to be properly cut 2014-04-24 12:15:04 +02:00
Dennis Luxen 5bde545ce3 All good, but needs unpacking of start and end 2014-04-24 12:07:46 +02:00
Dennis Luxen e68c750389 remove boost typedefs 2014-04-24 12:05:43 +02:00
Dennis Luxen f16cb3c52d compressed geometries get serialized in R-tree 2014-04-24 12:05:43 +02:00
Dennis Luxen f7d5b0db9c uncompressed edges get serialized correctly'ish 2014-04-24 12:05:43 +02:00
Dennis Luxen ba0b664e3f further copy edits 2014-04-24 12:05:43 +02:00
Dennis Luxen 149d037824 further copy edits 2014-04-24 12:05:43 +02:00
Dennis Luxen d0349d9b0d further copy edits 2014-04-24 12:05:42 +02:00
Dennis Luxen c71c8b0047 Unpacking of intermediate paths 2014-04-24 12:03:19 +02:00
Dennis Luxen 3be644265b remove remnants of C-Style includes 2014-04-24 11:38:54 +02:00
Dennis Luxen cd6874ca60 remove remnants of C-Style includes 2014-04-24 11:28:12 +02:00
Dennis Luxen 7083978f9d remove remnants of C-Style includes 2014-04-24 11:28:12 +02:00
Dennis Luxen 4d132489c1 remove remnants of C-Style includes 2014-04-24 11:28:11 +02:00
Dennis Luxen b5170ed1fd remove trivial geometry nodes 2014-04-24 11:28:11 +02:00
Dennis Luxen cc915dbef2 take 2: workaround platform dependend outputs, discussed in #986 2014-04-21 19:25:24 +02:00
Dennis Luxen 9a5bf1ee95 workaround platform dependend outputs, discussed in #986 2014-04-21 18:31:45 +02:00
Dennis Luxen a14b6af5c0 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2014-04-21 17:41:54 +02:00
Dennis Luxen ec372ad01d implement tests marked todo, implements #986 2014-04-21 17:40:08 +02:00
Dennis Luxen 8a412ef69e implementing option tests marked @todo 2014-04-21 17:40:08 +02:00
Dennis Luxen c978364f49 implementing option tests marked @todo 2014-04-21 17:40:07 +02:00
Emil Tin 61d2a99dd4 remove left-over feature file 2014-04-21 17:40:07 +02:00
Emil Tin fdba916d83 cuke: fix options test, should use osrm file, not osm 2014-04-21 17:40:07 +02:00
Emil Tin a12209e61d cuke: test options for osrm-extract and osrm-prepare 2014-04-21 17:40:07 +02:00
Patrick Niklaus fc6607ce9e better error messages for extractor
Previously extractor would just crash because of unhandled exceptions.
Now it displays meaningful error messages.
2014-04-21 17:40:07 +02:00
Dennis Luxen 62ccbc7490 use insert(.) on unordered map instead of access operator, potential resource leak 2014-04-21 17:40:07 +02:00
Dennis Luxen b2b36984e1 make single parameter c'tor explicit 2014-04-21 17:40:07 +02:00
Dennis Luxen c10208407d Revert "fix resource leak, coverity issue 1198844"
This reverts commit 3a1a51ac46.
2014-04-21 17:40:07 +02:00
Dennis Luxen 64720c2d2e several lints fixed that were detected by facebook's flint 2014-04-21 17:40:07 +02:00
Dennis Luxen da81e4839a reverse include order 2014-04-21 17:40:07 +02:00
Dennis Luxen 25013afdd2 make single argument c'tor explicit (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen 678829ab28 fix include order (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen d8dffa9d71 make single paramter c'tors explicit (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen be8810077a make single paramter c'tors explicit (thx flint) 2014-04-21 17:40:06 +02:00
Dennis Luxen ee4ecb9783 fix inverted logic 2014-04-21 17:40:06 +02:00
Dennis Luxen eaed8572f0 make all error messages JSON 2014-04-21 17:40:06 +02:00
Dennis Luxen e91e6fb068 check for invalid parameter, coverity issue 1198843, also reformat source 2014-04-21 17:40:06 +02:00
Dennis Luxen cb17a0a49b fix resource leak, coverity issue 1198844 2014-04-21 17:40:06 +02:00
Dennis Luxen 248df9ca2d catch exceptions that may occur, coverity issue 1198845 2014-04-21 17:40:06 +02:00
Dennis Luxen fa615ed9f4 don't binpack parameters on 100 column width 2014-04-21 17:40:05 +02:00
Dennis Luxen 65aa4af6d9 allow 120 char wide columns 2014-04-21 17:40:05 +02:00
Dennis Luxen df56ad476e add clang format style file (to change) 2014-04-21 17:40:05 +02:00
Dennis Luxen 8e20fa89e8 catch exceptions that may occur, coverity issue 1198846 2014-04-21 17:40:05 +02:00
Dennis Luxen 76058729e0 dont reset coloring when it wasn't set in the first place, partially fixes Windows woes. See #979 2014-04-21 17:40:05 +02:00
Dennis Luxen 88a0cc8c9c dont reset coloring when it wasn't set in the first place 2014-04-21 17:40:05 +02:00
Dennis Luxen 2ea45c0c58 implement tests marked todo, implements #986 2014-04-21 17:29:48 +02:00
Dennis Luxen bf27f41f52 implementing option tests marked @todo 2014-04-21 17:21:02 +02:00
Dennis Luxen 853f6012d5 implementing option tests marked @todo 2014-04-21 17:20:15 +02:00
Emil Tin 14ad02777f remove left-over feature file 2014-04-21 17:18:30 +02:00
Emil Tin c1eb00f6d5 cuke: fix options test, should use osrm file, not osm 2014-04-21 16:07:03 +02:00
Emil Tin e5adaf974d cuke: test options for osrm-extract and osrm-prepare 2014-04-21 15:24:42 +02:00
Patrick Niklaus 727a29600d better error messages for extractor
Previously extractor would just crash because of unhandled exceptions.
Now it displays meaningful error messages.
2014-04-19 13:19:48 +02:00
Dennis Luxen a5ebdb9243 use insert(.) on unordered map instead of access operator, potential resource leak 2014-04-17 11:05:26 +02:00
Dennis Luxen 2ef37ee798 make single parameter c'tor explicit 2014-04-17 10:30:15 +02:00
Dennis Luxen c23575786c Revert "fix resource leak, coverity issue 1198844"
This reverts commit 3a1a51ac46.
2014-04-16 18:13:59 +02:00
Dennis Luxen 5a0d693c93 several lints fixed that were detected by facebook's flint 2014-04-16 16:59:40 +02:00
Dennis Luxen c6902528b3 reverse include order 2014-04-16 16:22:13 +02:00
Dennis Luxen f90993be86 make single argument c'tor explicit (thx flint) 2014-04-16 16:21:16 +02:00
Dennis Luxen e7db076648 fix include order (thx flint) 2014-04-16 16:16:42 +02:00
Dennis Luxen 6d52a7d3d4 make single paramter c'tors explicit (thx flint) 2014-04-16 16:15:49 +02:00
Dennis Luxen 3368b492b9 make single paramter c'tors explicit (thx flint) 2014-04-16 16:13:48 +02:00
Dennis Luxen 1222aa6d25 fix inverted logic 2014-04-09 23:10:58 -04:00
Dennis Luxen 67efd150d4 make all error messages JSON 2014-04-09 18:12:45 -04:00
Dennis Luxen 9894f2e053 check for invalid parameter, coverity issue 1198843, also reformat source 2014-04-09 12:03:19 -04:00
Dennis Luxen 3a1a51ac46 fix resource leak, coverity issue 1198844 2014-04-09 11:59:48 -04:00
Dennis Luxen a1b5429f4e catch exceptions that may occur, coverity issue 1198845 2014-04-09 11:57:15 -04:00
Dennis Luxen b11e39554f don't binpack parameters on 100 column width 2014-04-09 11:55:59 -04:00
Dennis Luxen a92c764945 allow 120 char wide columns 2014-04-09 11:48:48 -04:00
Dennis Luxen f581396f1d add clang format style file (to change) 2014-04-09 11:44:56 -04:00
Dennis Luxen 6814926f05 catch exceptions that may occur, coverity issue 1198846 2014-04-09 11:34:15 -04:00
Dennis Luxen b8f882dba4 dont reset coloring when it wasn't set in the first place, partially fixes Windows woes. See #979 2014-04-07 15:11:04 -04:00
Dennis Luxen 783e8edf71 dont reset coloring when it wasn't set in the first place 2014-04-07 15:07:07 -04:00
113 changed files with 4452 additions and 2646 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
...
+3 -2
View File
@@ -96,7 +96,7 @@ private:
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 boost::unordered_map<RestrictionSource, unsigned> RestrictionMap;
std::vector<NodeInfo> m_coordinate_list;
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
@@ -145,7 +145,7 @@ public:
if(restriction_iterator == m_restriction_map.end()) {
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index+1);
m_restriction_map[restrictionSource] = index;
m_restriction_map.insert(std::make_pair(restrictionSource, index));
} else {
index = restriction_iterator->second;
//Map already contains an is_only_*-restriction
@@ -358,6 +358,7 @@ public:
"identified: " << component_size_vector.size() <<
" many components, marking small components";
// 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]) {
+2 -2
View File
@@ -81,7 +81,7 @@ 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_C_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
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()
@@ -92,7 +92,7 @@ endif()
# Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas -Wno-unneeded-internal-declaration -pedantic -fPIC")
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
+1 -1
View File
@@ -126,7 +126,6 @@ public:
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());
BOOST_ASSERT_MSG( newEdge.data.distance > 0, "edge distance < 1" );
#ifndef NDEBUG
if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) {
@@ -737,6 +736,7 @@ private:
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 );
}
+557 -154
View File
@@ -33,13 +33,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
//TODO: CompressionWorker
//TODO: EdgeBasedEdgeGenerator
// template<class Work>
// inline static void TraverseGraph(NodeBasedDynamicGraph & graph, Work & work) {
// }
#include <fstream>
#include <iomanip>
#include <numeric>
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
int number_of_nodes,
@@ -48,12 +44,14 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speed_profile
SpeedProfileProperties & speed_profile
) : speed_profile(speed_profile),
m_turn_restrictions_count(0),
m_node_info_list(m_node_info_list)
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
m_node_info_list(m_node_info_list),
max_id(0)
{
BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) {
BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) {
std::pair<NodeID, NodeID> restriction_source =
std::make_pair(restriction.fromNode, restriction.viaNode);
unsigned index;
@@ -80,7 +78,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
);
}
m_barrier_nodes.insert(
m_barrier_nodes.insert(
barrier_node_list.begin(),
barrier_node_list.end()
);
@@ -90,10 +88,15 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
traffic_light_node_list.end()
);
DeallocatingVector< NodeBasedEdge > edges_list;
std::sort( input_edge_list.begin(), input_edge_list.end() );
//TODO: remove duplicate edges
DeallocatingVector<NodeBasedEdge> edges_list;
NodeBasedEdge edge;
BOOST_FOREACH(const ImportEdge & import_edge, input_edge_list) {
if(!import_edge.isForward()) {
if( !import_edge.isForward() ) {
edge.source = import_edge.target();
edge.target = import_edge.source();
edge.data.backward = import_edge.isForward();
@@ -104,33 +107,101 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
edge.data.forward = import_edge.isForward();
edge.data.backward = import_edge.isBackward();
}
if(edge.source == edge.target) {
continue;
if( edge.source == edge.target ) {
continue;
}
edge.data.distance = (std::max)((int)import_edge.weight(), 1 );
BOOST_ASSERT( edge.data.distance > 0 );
edge.data.shortcut = false;
edge.data.roundabout = import_edge.isRoundabout();
edge.data.ignoreInGrid = import_edge.ignoreInGrid();
edge.data.ignore_in_grid = import_edge.ignoreInGrid();
edge.data.nameID = import_edge.name();
edge.data.type = import_edge.type();
edge.data.isAccessRestricted = import_edge.isAccessRestricted();
edge.data.edgeBasedNodeID = edges_list.size();
edge.data.contraFlow = import_edge.isContraFlow();
edges_list.push_back( edge );
if( edge.data.backward ) {
std::swap( edge.source, edge.target );
edge.data.forward = import_edge.isBackward();
edge.data.backward = import_edge.isForward();
edge.data.edgeBasedNodeID = edges_list.size();
if( !import_edge.IsSplit() ) {
using std::swap; //enable ADL
swap( edge.source, edge.target );
edge.data.SwapDirectionFlags();
edges_list.push_back( edge );
}
}
std::vector<ImportEdge>().swap(input_edge_list);
std::sort( edges_list.begin(), edges_list.end() );
m_node_based_graph = boost::make_shared<NodeBasedDynamicGraph>(
number_of_nodes, edges_list
number_of_nodes,
edges_list
);
DeallocatingVector<NodeBasedEdge>().swap(edges_list);
BOOST_ASSERT(0 == edges_list.size() );
}
void EdgeBasedGraphFactory::FixupArrivingTurnRestriction(
const NodeID u,
const NodeID v,
const NodeID w
) {
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( w != std::numeric_limits<unsigned>::max() );
std::vector<NodeID> predecessors;
for(
EdgeID current_edge_id = m_node_based_graph->BeginEdges(u);
current_edge_id < m_node_based_graph->EndEdges(u);
++current_edge_id
) {
const EdgeData & edge_data = m_node_based_graph->GetEdgeData(current_edge_id);
const NodeID target = m_node_based_graph->GetTarget(current_edge_id);
if( edge_data.backward && ( v != target) ) {
predecessors.push_back(target);
}
}
BOOST_FOREACH( const NodeID x, predecessors ) {
const std::pair<NodeID, NodeID> restr_start = std::make_pair(x,u);
RestrictionMap::const_iterator restriction_iterator;
restriction_iterator = m_restriction_map.find( restr_start );
if( restriction_iterator != m_restriction_map.end() ) {
const unsigned index = restriction_iterator->second;
BOOST_FOREACH(
RestrictionTarget & restriction_target,
m_restriction_bucket_list.at(index)
) {
if( v == restriction_target.first ) {
restriction_target.first = w;
}
}
}
}
}
void EdgeBasedGraphFactory::FixupStartingTurnRestriction(
const NodeID u,
const NodeID v,
const NodeID w
) {
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( w != std::numeric_limits<unsigned>::max() );
const std::pair<NodeID, NodeID> old_start = std::make_pair(v,w);
RestrictionMap::const_iterator restriction_iterator;
restriction_iterator = m_restriction_map.find( old_start );
if( restriction_iterator != m_restriction_map.end() ) {
const unsigned index = restriction_iterator->second;
// remove old restriction start (v,w)
m_restriction_map.erase( restriction_iterator );
// insert new restriction start (u,w) (point to index)
const std::pair<NodeID, NodeID> new_start = std::make_pair(u,w);
m_restriction_map.insert( std::make_pair(new_start, index) );
}
}
void EdgeBasedGraphFactory::GetEdgeBasedEdges(
@@ -146,8 +217,11 @@ void EdgeBasedGraphFactory::GetEdgeBasedEdges(
void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) {
#ifndef NDEBUG
BOOST_FOREACH(const EdgeBasedNode & node, m_edge_based_node_list){
BOOST_ASSERT(node.lat1 != INT_MAX); BOOST_ASSERT(node.lon1 != INT_MAX);
BOOST_ASSERT(node.lat2 != INT_MAX); BOOST_ASSERT(node.lon2 != INT_MAX);
BOOST_ASSERT( m_node_info_list.at(node.u).lat != INT_MAX );
BOOST_ASSERT( m_node_info_list.at(node.u).lon != INT_MAX );
BOOST_ASSERT( m_node_info_list.at(node.v).lon != INT_MAX );
BOOST_ASSERT( m_node_info_list.at(node.v).lat != INT_MAX );
}
#endif
nodes.swap(m_edge_based_node_list);
@@ -157,7 +231,9 @@ NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
const NodeID u,
const NodeID v
) const {
const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iter;
restriction_iter = m_restriction_map.find(restriction_source);
if (restriction_iter != m_restriction_map.end()) {
@@ -171,7 +247,7 @@ NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
}
}
}
return UINT_MAX;
return std::numeric_limits<unsigned>::max();
}
bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
@@ -179,8 +255,11 @@ bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
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.
const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( v != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( w != std::numeric_limits<unsigned>::max() );
const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iter;
restriction_iter = m_restriction_map.find(restriction_source);
if (restriction_iter != m_restriction_map.end()) {
@@ -189,7 +268,10 @@ bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
const RestrictionTarget & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(w == restriction_target.first) {
if(
( w == restriction_target.first ) && // target found
( !restriction_target.second ) // and not an only_-restr.
) {
return true;
}
}
@@ -198,22 +280,175 @@ bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
}
void EdgeBasedGraphFactory::InsertEdgeBasedNode(
EdgeIterator e1,
NodeIterator u,
NodeIterator v,
bool belongsToTinyComponent) {
EdgeData & data = m_node_based_graph->GetEdgeData(e1);
EdgeBasedNode currentNode;
currentNode.nameID = data.nameID;
currentNode.lat1 = m_node_info_list[u].lat;
currentNode.lon1 = m_node_info_list[u].lon;
currentNode.lat2 = m_node_info_list[v].lat;
currentNode.lon2 = m_node_info_list[v].lon;
currentNode.belongsToTinyComponent = belongsToTinyComponent;
currentNode.id = data.edgeBasedNodeID;
currentNode.ignoreInGrid = data.ignoreInGrid;
currentNode.weight = data.distance;
m_edge_based_node_list.push_back(currentNode);
NodeIterator u,
NodeIterator v,
EdgeIterator e1,
bool belongs_to_tiny_cc
) {
// merge edges together into one EdgeBasedNode
BOOST_ASSERT( u != SPECIAL_NODEID );
BOOST_ASSERT( v != SPECIAL_NODEID );
BOOST_ASSERT( e1 != SPECIAL_EDGEID );
#ifndef NDEBUG
// find forward edge id and
const EdgeID e1b = m_node_based_graph->FindEdge(u, v);
BOOST_ASSERT( e1 == e1b );
#endif
BOOST_ASSERT( e1 != SPECIAL_EDGEID );
const EdgeData & forward_data = m_node_based_graph->GetEdgeData(e1);
// find reverse edge id and
const EdgeID e2 = m_node_based_graph->FindEdge(v, u);
#ifndef NDEBUG
if ( e2 == m_node_based_graph->EndEdges(v) ) {
SimpleLogger().Write(logWARNING) << "Did not find edge (" << v << "," << u << ")";
}
#endif
BOOST_ASSERT( e2 != SPECIAL_EDGEID );
BOOST_ASSERT( e2 < m_node_based_graph->EndEdges(v) );
const EdgeData & reverse_data = m_node_based_graph->GetEdgeData(e2);
if(
forward_data.edgeBasedNodeID == SPECIAL_NODEID &&
reverse_data.edgeBasedNodeID == SPECIAL_NODEID
) {
return;
}
BOOST_ASSERT( m_geometry_compressor.HasEntryForID(e1) == m_geometry_compressor.HasEntryForID(e2) );
if( m_geometry_compressor.HasEntryForID(e1) ) {
BOOST_ASSERT( m_geometry_compressor.HasEntryForID(e2) );
// reconstruct geometry and put in each individual edge with its offset
const std::vector<GeometryCompressor::CompressedNode> & forward_geometry = m_geometry_compressor.GetBucketReference(e1);
const std::vector<GeometryCompressor::CompressedNode> & reverse_geometry = m_geometry_compressor.GetBucketReference(e2);
BOOST_ASSERT( forward_geometry.size() == reverse_geometry.size() );
BOOST_ASSERT( 0 != forward_geometry.size() );
// reconstruct bidirectional edge with individual weights and put each into the NN index
std::vector<int> forward_dist_prefix_sum(forward_geometry.size(), 0);
std::vector<int> reverse_dist_prefix_sum(reverse_geometry.size(), 0);
// quick'n'dirty prefix sum as std::partial_sum needs addtional casts
// TODO: move to lambda function with C++11
int temp_sum = 0;
for (unsigned i = 0; i < forward_geometry.size(); ++i)
{
forward_dist_prefix_sum[i] = temp_sum;
temp_sum += forward_geometry[i].second;
BOOST_ASSERT( forward_data.distance >= temp_sum );
}
temp_sum = 0;
for( unsigned i = 0; i < reverse_geometry.size(); ++i ) {
temp_sum += reverse_geometry[reverse_geometry.size()-1-i].second;
reverse_dist_prefix_sum[i] = reverse_data.distance - temp_sum;
BOOST_ASSERT( reverse_data.distance >= temp_sum );
}
BOOST_ASSERT( forward_geometry.size() == reverse_geometry.size() );
const unsigned geometry_size = forward_geometry.size();
BOOST_ASSERT( geometry_size > 1 );
NodeID current_edge_start_coordinate_id = u;
if (forward_data.edgeBasedNodeID != SPECIAL_NODEID)
{
max_id = std::max(forward_data.edgeBasedNodeID, max_id);
}
if (SPECIAL_NODEID != reverse_data.edgeBasedNodeID)
{
max_id = std::max(reverse_data.edgeBasedNodeID, max_id);
}
// traverse arrays from start and end respectively
for( unsigned i = 0; i < geometry_size; ++i ) {
BOOST_ASSERT( current_edge_start_coordinate_id == reverse_geometry[geometry_size-1-i].first );
const NodeID current_edge_target_coordinate_id = forward_geometry[i].first;
BOOST_ASSERT( current_edge_target_coordinate_id != current_edge_start_coordinate_id);
// build edges
m_edge_based_node_list.push_back(
EdgeBasedNode(
forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
current_edge_start_coordinate_id,
current_edge_target_coordinate_id,
forward_data.nameID,
forward_geometry[i].second,
reverse_geometry[i].second,
forward_dist_prefix_sum[i],
reverse_dist_prefix_sum[i],
m_geometry_compressor.GetPositionForID(e1),
i,
belongs_to_tiny_cc
)
);
current_edge_start_coordinate_id = current_edge_target_coordinate_id;
BOOST_ASSERT( m_edge_based_node_list.back().IsCompressed() );
BOOST_ASSERT(
u != m_edge_based_node_list.back().u ||
v != m_edge_based_node_list.back().v
);
BOOST_ASSERT(
u != m_edge_based_node_list.back().v ||
v != m_edge_based_node_list.back().u
);
}
BOOST_ASSERT( current_edge_start_coordinate_id == v );
BOOST_ASSERT( m_edge_based_node_list.back().IsCompressed() );
} else {
BOOST_ASSERT( !m_geometry_compressor.HasEntryForID(e2) );
if( forward_data.edgeBasedNodeID != std::numeric_limits<unsigned>::max() ) {
BOOST_ASSERT( forward_data.forward );
}
if( reverse_data.edgeBasedNodeID != std::numeric_limits<unsigned>::max() ) {
BOOST_ASSERT( reverse_data.forward );
}
if( forward_data.edgeBasedNodeID == std::numeric_limits<unsigned>::max() ) {
BOOST_ASSERT( !forward_data.forward );
}
if( reverse_data.edgeBasedNodeID == std::numeric_limits<unsigned>::max() ) {
BOOST_ASSERT( !reverse_data.forward );
}
BOOST_ASSERT(
forward_data.edgeBasedNodeID != SPECIAL_NODEID ||
reverse_data.edgeBasedNodeID != SPECIAL_NODEID
);
//TODO C++11: emplace_back with
m_edge_based_node_list.push_back(
EdgeBasedNode(
forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
u,
v,
forward_data.nameID,
forward_data.distance,
reverse_data.distance,
0,
0,
SPECIAL_EDGEID,
0,
belongs_to_tiny_cc
)
);
BOOST_ASSERT( !m_edge_based_node_list.back().IsCompressed() );
}
}
@@ -229,27 +464,173 @@ void EdgeBasedGraphFactory::FlushVectorToStream(
}
void EdgeBasedGraphFactory::Run(
const char * original_edge_data_filename,
const std::string & original_edge_data_filename,
const std::string & geometry_filename,
lua_State *lua_state
) {
SimpleLogger().Write() << "Compressing geometry of input graph";
//TODO: iterate over all turns
SimpleLogger().Write() << "Removing graph geometry while preserving topology";
//TODO: compress geometries
const unsigned original_number_of_nodes = m_node_based_graph->GetNumberOfNodes();
const unsigned original_number_of_edges = m_node_based_graph->GetNumberOfEdges();
//TODO: update turn restrictions if concerned by compression
Percent p(original_number_of_nodes);
unsigned removed_node_count = 0;
//TODO: do some compression statistics
for( NodeID v = 0; v < original_number_of_nodes; ++v ) {
p.printStatus(v);
// only contract degree 2 vertices
if( 2 != m_node_based_graph->GetOutDegree(v) ) {
continue;
}
// don't contract barrier node
if( m_barrier_nodes.end() != m_barrier_nodes.find(v) ) {
continue;
}
const bool reverse_edge_order = !(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(v)).forward);
const EdgeIterator forward_e2 = m_node_based_graph->BeginEdges(v) + reverse_edge_order;
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != forward_e2 );
const EdgeIterator reverse_e2 = m_node_based_graph->BeginEdges(v) + 1 - reverse_edge_order;
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != reverse_e2 );
const EdgeData & fwd_edge_data2 = m_node_based_graph->GetEdgeData(forward_e2);
const EdgeData & rev_edge_data2 = m_node_based_graph->GetEdgeData(reverse_e2);
const NodeIterator w = m_node_based_graph->GetTarget(forward_e2);
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != w );
BOOST_ASSERT( v != w );
const NodeIterator u = m_node_based_graph->GetTarget(reverse_e2);
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != u );
BOOST_ASSERT( u != v );
const EdgeIterator forward_e1 = m_node_based_graph->FindEdge(u, v);
BOOST_ASSERT( m_node_based_graph->EndEdges(u) != forward_e1 );
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != forward_e1 );
BOOST_ASSERT( v == m_node_based_graph->GetTarget(forward_e1));
const EdgeIterator reverse_e1 = m_node_based_graph->FindEdge(w, v);
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != reverse_e1 );
BOOST_ASSERT( v == m_node_based_graph->GetTarget(reverse_e1));
const EdgeData & fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1);
const EdgeData & rev_edge_data1 = m_node_based_graph->GetEdgeData(reverse_e1);
if(
( m_node_based_graph->FindEdge(u, w) != m_node_based_graph->EndEdges(u) ) ||
( m_node_based_graph->FindEdge(w, u) != m_node_based_graph->EndEdges(w) )
) {
continue;
}
if ( //TODO: rename to IsCompatibleTo
fwd_edge_data1.IsEqualTo(fwd_edge_data2) &&
rev_edge_data1.IsEqualTo(rev_edge_data2)
) {
//Get distances before graph is modified
const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance;
const int forward_weight2 = m_node_based_graph->GetEdgeData(forward_e2).distance;
BOOST_ASSERT( 0 != forward_weight1 );
BOOST_ASSERT( 0 != forward_weight2 );
const int reverse_weight1 = m_node_based_graph->GetEdgeData(reverse_e1).distance;
const int reverse_weight2 = m_node_based_graph->GetEdgeData(reverse_e2).distance;
BOOST_ASSERT( 0 != reverse_weight1 );
BOOST_ASSERT( 0 != forward_weight2 );
const bool add_traffic_signal_penalty = (m_traffic_lights.find(v) != m_traffic_lights.end());
// add weight of e2's to e1
m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
m_node_based_graph->GetEdgeData(reverse_e1).distance += rev_edge_data2.distance;
if (add_traffic_signal_penalty)
{
m_node_based_graph->GetEdgeData(forward_e1).distance += speed_profile.trafficSignalPenalty;
m_node_based_graph->GetEdgeData(reverse_e1).distance += speed_profile.trafficSignalPenalty;
}
// extend e1's to targets of e2's
m_node_based_graph->SetTarget(forward_e1, w);
m_node_based_graph->SetTarget(reverse_e1, u);
// remove e2's (if bidir, otherwise only one)
m_node_based_graph->DeleteEdge(v, forward_e2);
m_node_based_graph->DeleteEdge(v, reverse_e2);
// update any involved turn restrictions
FixupStartingTurnRestriction( u, v, w );
FixupArrivingTurnRestriction( u, v, w );
FixupStartingTurnRestriction( w, v, u );
FixupArrivingTurnRestriction( w, v, u );
// store compressed geometry in container
m_geometry_compressor.CompressEdge(
forward_e1,
forward_e2,
v,
w,
forward_weight1 + (add_traffic_signal_penalty ? speed_profile.trafficSignalPenalty :0),
forward_weight2
);
m_geometry_compressor.CompressEdge(
reverse_e1,
reverse_e2,
v,
u,
reverse_weight1 ,
reverse_weight2 + (add_traffic_signal_penalty ? speed_profile.trafficSignalPenalty :0)
);
++removed_node_count;
BOOST_ASSERT
(
m_node_based_graph->GetEdgeData(forward_e1).nameID ==
m_node_based_graph->GetEdgeData(reverse_e1).nameID
);
}
}
SimpleLogger().Write() << "removed " << removed_node_count << " nodes";
m_geometry_compressor.PrintStatistics();
unsigned new_node_count = 0;
unsigned new_edge_count = 0;
for( unsigned i = 0; i < m_node_based_graph->GetNumberOfNodes(); ++i ) {
if( m_node_based_graph->GetOutDegree(i) > 0 ) {
++new_node_count;
new_edge_count += (m_node_based_graph->EndEdges(i) - m_node_based_graph->BeginEdges(i));
}
}
SimpleLogger().Write() << "new nodes: " << new_node_count << ", edges " << new_edge_count;
SimpleLogger().Write() << "Node compression ratio: " << new_node_count/(double)original_number_of_nodes;
SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count/(double)original_number_of_edges;
// renumber edge based node IDs
unsigned numbered_edges_count = 0;
for(NodeID current_node = 0; current_node < m_node_based_graph->GetNumberOfNodes(); ++current_node) {
for(EdgeIterator current_edge = m_node_based_graph->BeginEdges(current_node); current_edge < m_node_based_graph->EndEdges(current_node); ++current_edge) {
EdgeData & edge_data = m_node_based_graph->GetEdgeData(current_edge);
if( !edge_data.forward ) {
continue;
}
BOOST_ASSERT( numbered_edges_count < m_node_based_graph->GetNumberOfEdges() );
edge_data.edgeBasedNodeID = numbered_edges_count;
++numbered_edges_count;
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != edge_data.edgeBasedNodeID);
}
}
SimpleLogger().Write() << "Identifying components of the road network";
unsigned skipped_turns_counter = 0;
unsigned node_based_edge_counter = 0;
unsigned original_edges_counter = 0;
std::ofstream edge_data_file(
original_edge_data_filename,
original_edge_data_filename.c_str(),
std::ios::binary
);
@@ -261,49 +642,62 @@ void EdgeBasedGraphFactory::Run(
//Run a BFS on the undirected graph and identify small components
std::vector<unsigned> component_index_list;
std::vector<NodeID> component_index_size;
BFSCompentExplorer( component_index_list, component_index_size);
std::vector<NodeID > component_index_size;
BFSCompentExplorer( component_index_list, component_index_size );
SimpleLogger().Write() <<
"identified: " << component_index_size.size() << " many components";
SimpleLogger().Write() <<
"generating edge-expanded nodes";
SimpleLogger().Write() << "generating edge-expanded nodes";
Percent p(m_node_based_graph->GetNumberOfNodes());
//loop over all edges and generate new set of nodes.
p.reinit(m_node_based_graph->GetNumberOfNodes());
//loop over all edges and generate new set of nodes
for(
NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes();
u < end;
++u
) {
BOOST_ASSERT( u != std::numeric_limits<unsigned>::max() );
BOOST_ASSERT( u < m_node_based_graph->GetNumberOfNodes() );
p.printIncrement();
for(
EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
EdgeID e1 = m_node_based_graph->BeginEdges(u),
last_edge = m_node_based_graph->EndEdges(u);
e1 < last_edge;
++e1
) {
NodeIterator v = m_node_based_graph->GetTarget(e1);
const EdgeData & edge_data = m_node_based_graph->GetEdgeData(e1);
if( edge_data.edgeBasedNodeID == SPECIAL_NODEID ) {
// continue;
}
BOOST_ASSERT( e1 != SPECIAL_EDGEID );
const NodeID v = m_node_based_graph->GetTarget(e1);
BOOST_ASSERT( SPECIAL_NODEID != v );
// pick only every other edge
if( u > v ) {
continue;
}
BOOST_ASSERT( u < v );
BOOST_ASSERT( edge_data.type != SHRT_MAX );
if(m_node_based_graph->GetEdgeData(e1).type != SHRT_MAX) {
BOOST_ASSERT_MSG(e1 != UINT_MAX, "edge id invalid");
BOOST_ASSERT_MSG(u != UINT_MAX, "souce node invalid");
BOOST_ASSERT_MSG(v != UINT_MAX, "target node invalid");
//Note: edges that end on barrier nodes or on a turn restriction
//may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min(
component_index_size[component_index_list[u]],
component_index_size[component_index_list[v]]
);
const unsigned size_of_component = std::min(
component_index_size[component_index_list[u]],
component_index_size[component_index_list[v]]
);
InsertEdgeBasedNode( e1, u, v, size_of_component < 1000 );
}
const bool component_is_tiny = ( size_of_component < 1000 );
InsertEdgeBasedNode( u, v, e1, component_is_tiny );
}
}
SimpleLogger().Write()
<< "Generated " << m_edge_based_node_list.size() << " nodes in " <<
"edge-expanded graph";
m_number_of_edge_based_nodes = numbered_edges_count;
SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size() <<
" nodes in edge-expanded graph";
SimpleLogger().Write() << "generating edge-expanded edges";
std::vector<NodeID>().swap(component_index_size);
@@ -322,18 +716,19 @@ void EdgeBasedGraphFactory::Run(
//Loop over all turns and generate new set of edges.
//Three nested loop look super-linear, but we are dealing with a (kind of)
//linear number of turns only.
unsigned restricted_turns_counter = 0;
unsigned skipped_uturns_counter = 0;
unsigned skipped_barrier_turns_counter = 0;
unsigned compressed = 0;
p.reinit(m_node_based_graph->GetNumberOfNodes());
for(
NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes();
u < end;
++u
) {
for(
EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
last_edge_u = m_node_based_graph->EndEdges(u);
e1 < last_edge_u;
++e1
) {
for (NodeIterator u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
{
for (EdgeIterator e1 = m_node_based_graph->BeginEdges(u), last_edge_u = m_node_based_graph->EndEdges(u); e1 < last_edge_u; ++e1)
{
if( !m_node_based_graph->GetEdgeData(e1).forward ) {
continue;
}
++node_based_edge_counter;
const NodeIterator v = m_node_based_graph->GetTarget(e1);
const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
@@ -345,83 +740,92 @@ void EdgeBasedGraphFactory::Run(
e2 < last_edge_v;
++e2
) {
if (!m_node_based_graph->GetEdgeData(e2).forward)
{
continue;
}
const NodeIterator w = m_node_based_graph->GetTarget(e2);
if(
to_node_of_only_restriction != UINT_MAX &&
w != to_node_of_only_restriction
) {
if ((to_node_of_only_restriction != SPECIAL_NODEID) && (w != to_node_of_only_restriction))
{
//We are at an only_-restriction but not at the right turn.
++skipped_turns_counter;
++restricted_turns_counter;
continue;
}
if( is_barrier_node) {
if(u != w) {
++skipped_turns_counter;
if (is_barrier_node)
{
if (u != w)
{
++skipped_barrier_turns_counter;
continue;
}
} else {
if ( (u == w) && (m_node_based_graph->GetOutDegree(v) > 1) ) {
++skipped_turns_counter;
}
else
{
if ((u == w) && (m_node_based_graph->GetOutDegree(v) > 1))
{
++skipped_uturns_counter;
continue;
}
}
//only add an edge if turn is not a U-turn except when it is
//at the end of a dead-end street
if (
CheckIfTurnIsRestricted(u, v, w) &&
(to_node_of_only_restriction == UINT_MAX) &&
(w != to_node_of_only_restriction)
) {
++skipped_turns_counter;
if (CheckIfTurnIsRestricted(u, v, w) && (to_node_of_only_restriction == SPECIAL_NODEID) && (w != to_node_of_only_restriction))
{
++restricted_turns_counter;
continue;
}
//only add an edge if turn is not prohibited
const EdgeData edge_data1 = m_node_based_graph->GetEdgeData(e1);
const EdgeData edge_data2 = m_node_based_graph->GetEdgeData(e2);
const EdgeData & edge_data1 = m_node_based_graph->GetEdgeData(e1);
const EdgeData & edge_data2 = m_node_based_graph->GetEdgeData(e2);
BOOST_ASSERT(
edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()
);
BOOST_ASSERT(
edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges()
);
BOOST_ASSERT(
edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID
);
BOOST_ASSERT( edge_data1.forward );
BOOST_ASSERT( edge_data2.forward );
BOOST_ASSERT(edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID);
BOOST_ASSERT(edge_data1.forward);
BOOST_ASSERT(edge_data2.forward);
// the following is the core of the loop.
unsigned distance = edge_data1.distance;
if( m_traffic_lights.find(v) != m_traffic_lights.end() ) {
if (m_traffic_lights.find(v) != m_traffic_lights.end())
{
distance += speed_profile.trafficSignalPenalty;
}
const int turn_penalty = GetTurnPenalty(u, v, w, lua_state);
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w);
if(turnInstruction == TurnInstructions.UTurn){
TurnInstruction turn_instruction = AnalyzeTurn(u, v, w);
if (turn_instruction == TurnInstructionsClass::UTurn)
{
distance += speed_profile.uTurnPenalty;
}
distance += turn_penalty;
const bool edge_is_compressed = m_geometry_compressor.HasEntryForID(e1);
if (edge_is_compressed)
{
++compressed;
}
original_edge_data_vector.push_back(
OriginalEdgeData(
v,
edge_data2.nameID,
turnInstruction
(edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v),
edge_data1.nameID,
turn_instruction,
edge_is_compressed
)
);
++original_edges_counter;
if(original_edge_data_vector.size() > 100000) {
FlushVectorToStream(
edge_data_file,
original_edge_data_vector
);
if (original_edge_data_vector.size() > 100000)
{
FlushVectorToStream(edge_data_file, original_edge_data_vector);
}
BOOST_ASSERT( SPECIAL_NODEID != edge_data1.edgeBasedNodeID );
BOOST_ASSERT( SPECIAL_NODEID != edge_data2.edgeBasedNodeID );
m_edge_based_edge_list.push_back(
EdgeBasedEdge(
edge_data1.edgeBasedNodeID,
@@ -442,17 +846,16 @@ void EdgeBasedGraphFactory::Run(
edge_data_file.write( (char*)&original_edges_counter, sizeof(unsigned) );
edge_data_file.close();
SimpleLogger().Write() <<
"Generated " << m_edge_based_node_list.size() << " edge based nodes";
SimpleLogger().Write() <<
"Node-based graph contains " << node_based_edge_counter << " edges";
SimpleLogger().Write() <<
"Edge-expanded graph ...";
SimpleLogger().Write() <<
" contains " << m_edge_based_edge_list.size() << " edges";
SimpleLogger().Write() <<
" skips " << skipped_turns_counter << " turns, "
"defined by " << m_turn_restrictions_count << " restrictions";
m_geometry_compressor.SerializeInternalVector( geometry_filename );
SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size() << " edge based nodes";
SimpleLogger().Write() << "Node-based graph contains " << node_based_edge_counter << " edges";
SimpleLogger().Write() << "Edge-expanded graph ...";
SimpleLogger().Write() << " contains " << m_edge_based_edge_list.size() << " edges";
SimpleLogger().Write() << " skips " << restricted_turns_counter << " turns, "
"defined by " << m_turn_restrictions_count << " restrictions";
SimpleLogger().Write() << " skips " << skipped_uturns_counter << " U turns";
SimpleLogger().Write() << " skips " << skipped_barrier_turns_counter << " turns over barriers";
}
int EdgeBasedGraphFactory::GetTurnPenalty(
@@ -488,7 +891,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
const NodeID w
) const {
if(u == w) {
return TurnInstructions.UTurn;
return TurnInstructionsClass::UTurn;
}
const EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v);
@@ -498,10 +901,10 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
const EdgeData & data2 = m_node_based_graph->GetEdgeData(edge2);
if(!data1.contraFlow && data2.contraFlow) {
return TurnInstructions.EnterAgainstAllowedDirection;
return TurnInstructionsClass::EnterAgainstAllowedDirection;
}
if(data1.contraFlow && !data2.contraFlow) {
return TurnInstructions.LeaveAgainstAllowedDirection;
return TurnInstructionsClass::LeaveAgainstAllowedDirection;
}
//roundabouts need to be handled explicitely
@@ -509,19 +912,19 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
//Is a turn possible? If yes, we stay on the roundabout!
if( 1 == m_node_based_graph->GetOutDegree(v) ) {
//No turn possible.
return TurnInstructions.NoTurn;
return TurnInstructionsClass::NoTurn;
}
return TurnInstructions.StayOnRoundAbout;
return TurnInstructionsClass::StayOnRoundAbout;
}
//Does turn start or end on roundabout?
if(data1.roundabout || data2.roundabout) {
//We are entering the roundabout
if( (!data1.roundabout) && data2.roundabout) {
return TurnInstructions.EnterRoundAbout;
return TurnInstructionsClass::EnterRoundAbout;
}
//We are leaving the roundabout
if(data1.roundabout && (!data2.roundabout) ) {
return TurnInstructions.LeaveRoundAbout;
return TurnInstructionsClass::LeaveRoundAbout;
}
}
@@ -531,9 +934,9 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
//TODO: Here we should also do a small graph exploration to check for
// more complex situations
if( 0 != data1.nameID ) {
return TurnInstructions.NoTurn;
return TurnInstructionsClass::NoTurn;
} else if (m_node_based_graph->GetOutDegree(v) <= 2) {
return TurnInstructions.NoTurn;
return TurnInstructionsClass::NoTurn;
}
}
@@ -542,11 +945,11 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
m_node_info_list[v],
m_node_info_list[w]
);
return TurnInstructions.GetTurnDirectionOfInstruction(angle);
return TurnInstructionsClass::GetTurnDirectionOfInstruction(angle);
}
unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const {
return m_node_based_graph->GetNumberOfEdges();
unsigned EdgeBasedGraphFactory::GetNumberOfEdgeBasedNodes() const {
return m_number_of_edge_based_nodes;
}
void EdgeBasedGraphFactory::BFSCompentExplorer(
@@ -563,12 +966,12 @@ void EdgeBasedGraphFactory::BFSCompentExplorer(
component_index_list.resize(
m_node_based_graph->GetNumberOfNodes(),
UINT_MAX
std::numeric_limits<unsigned>::max()
);
//put unexplorered node with parent pointer into queue
for( NodeID node = 0, end = m_node_based_graph->GetNumberOfNodes(); node < end; ++node) {
if(UINT_MAX == component_index_list[node]) {
if(std::numeric_limits<unsigned>::max() == component_index_list[node]) {
bfs_queue.push(std::make_pair(node, node));
//mark node as read
component_index_list[node] = current_component;
@@ -594,7 +997,7 @@ void EdgeBasedGraphFactory::BFSCompentExplorer(
NodeIterator w = m_node_based_graph->GetTarget(e2);
if(
to_node_of_only_restriction != UINT_MAX &&
to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction
) {
// At an only_-restriction but not at the right turn
@@ -605,7 +1008,7 @@ void EdgeBasedGraphFactory::BFSCompentExplorer(
//when it is at the end of a dead-end street.
if (!CheckIfTurnIsRestricted(u, v, w) ) {
//only add an edge if turn is not prohibited
if(UINT_MAX == component_index_list[w]) {
if(std::numeric_limits<unsigned>::max() == component_index_list[w]) {
//insert next (node, parent) only if w has
//not yet been explored
//mark node as read
+58 -17
View File
@@ -53,23 +53,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/unordered_set.hpp>
#include <algorithm>
#include <fstream>
#include <iosfwd>
#include <queue>
#include <vector>
class EdgeBasedGraphFactory : boost::noncopyable {
public:
struct SpeedProfileProperties{
SpeedProfileProperties() :
trafficSignalPenalty(0),
uTurnPenalty(0),
has_turn_penalty_function(false)
{ }
int trafficSignalPenalty;
int uTurnPenalty;
bool has_turn_penalty_function;
} speed_profile;
struct SpeedProfileProperties;
explicit EdgeBasedGraphFactory(
int number_of_nodes,
@@ -78,10 +68,14 @@ public:
std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speed_profile
SpeedProfileProperties & speed_profile
);
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
void Run(
const std::string & original_edge_data_filename,
const std::string & geometry_filename,
lua_State *myLuaState
);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
@@ -100,10 +94,27 @@ public:
lua_State *myLuaState
) const;
unsigned GetNumberOfNodes() 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;
private:
struct NodeBasedEdgeData {
NodeBasedEdgeData() {
//TODO: proper c'tor
edgeBasedNodeID = UINT_MAX;
}
int distance;
unsigned edgeBasedNodeID;
unsigned nameID;
@@ -113,11 +124,26 @@ private:
bool forward:1;
bool backward:1;
bool roundabout:1;
bool ignoreInGrid:1;
bool ignore_in_grid:1;
bool contraFlow:1;
void SwapDirectionFlags() {
bool temp_flag = forward;
forward = backward;
backward = temp_flag;
}
bool IsEqualTo( const NodeBasedEdgeData & other ) const {
return (forward == other.forward) &&
(backward == other.backward) &&
(nameID == other.nameID) &&
(ignore_in_grid == other.ignore_in_grid) &&
(contraFlow == other.contraFlow);
}
};
unsigned m_turn_restrictions_count;
unsigned m_number_of_edge_based_nodes;
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
@@ -139,6 +165,7 @@ private:
boost::unordered_set<NodeID> m_traffic_lights;
RestrictionMap m_restriction_map;
GeometryCompressor m_geometry_compressor;
NodeID CheckForEmanatingIsOnlyTurn(
const NodeID u,
@@ -152,9 +179,9 @@ private:
) const;
void InsertEdgeBasedNode(
NodeBasedDynamicGraph::EdgeIterator e1,
NodeBasedDynamicGraph::NodeIterator u,
NodeBasedDynamicGraph::NodeIterator v,
NodeBasedDynamicGraph::EdgeIterator e1,
bool belongsToTinyComponent
);
@@ -167,6 +194,20 @@ private:
std::ofstream & edge_data_file,
std::vector<OriginalEdgeData> & original_edge_data_vector
) const;
void FixupArrivingTurnRestriction(
const NodeID u,
const NodeID v,
const NodeID w
);
void FixupStartingTurnRestriction(
const NodeID u,
const NodeID v,
const NodeID w
);
unsigned max_id;
};
#endif /* EDGEBASEDGRAPHFACTORY_H_ */
+172 -42
View File
@@ -26,69 +26,199 @@ 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; }
int UniqueNumber() { return ++current_free_list_maximum; }
GeometryCompressor::GeometryCompressor() {
m_free_list.resize(100);
GeometryCompressor::GeometryCompressor()
{
m_free_list.reserve(100);
IncreaseFreeList();
}
void GeometryCompressor::IncreaseFreeList() {
void GeometryCompressor::IncreaseFreeList()
{
m_compressed_geometries.resize(m_compressed_geometries.size() + 100);
std::generate_n (m_free_list.rend(), 100, UniqueNumber);
for (unsigned i = 100; i > 0; --i)
{
m_free_list.push_back(current_free_list_maximum);
++current_free_list_maximum;
}
}
void GeometryCompressor::AppendNodeIDsToGeomtry( NodeID node_id, NodeID contracted_node_id ) {
//check if node_id already has a list
boost::unordered_map<unsigned, unsigned>::const_iterator map_iterator;
map_iterator = m_node_id_to_index_map.find( node_id );
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 geometry_bucket_index = std::numeric_limits<unsigned>::max();
if( m_node_id_to_index_map.end() == map_iterator ) {
//if not, create one
if( m_free_list.empty() ) {
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();
}
geometry_bucket_index = m_free_list.back();
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();
} else {
geometry_bucket_index = map_iterator->second;
}
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != geometry_bucket_index );
BOOST_ASSERT( geometry_bucket_index < m_compressed_geometries.size() );
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());
//append contracted_node_id to m_compressed_geometries[node_id]
m_compressed_geometries[geometry_bucket_index].push_back(contracted_node_id);
std::vector<CompressedNode> &edge_bucket_list1 = m_compressed_geometries[edge_bucket_id1];
//append m_compressed_geometries[contracted_node_id] to m_compressed_geometries[node_id]
map_iterator = m_node_id_to_index_map.find(contracted_node_id);
if ( m_node_id_to_index_map.end() != map_iterator) {
const unsigned bucket_index_to_remove = map_iterator->second;
BOOST_ASSERT( bucket_index_to_remove < m_compressed_geometries.size() );
if (edge_bucket_list1.empty())
{
edge_bucket_list1.push_back(std::make_pair(via_node_id, weight1));
}
m_compressed_geometries[geometry_bucket_index].insert(
m_compressed_geometries[geometry_bucket_index].end(),
m_compressed_geometries[bucket_index_to_remove].begin(),
m_compressed_geometries[bucket_index_to_remove].end()
);
//remove m_compressed_geometries[contracted_node_id], add to free list
m_compressed_geometries[bucket_index_to_remove].clear();
m_free_list.push_back(bucket_index_to_remove);
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 {
unsigned compressed_node_count = 0;
const unsigned surviving_node_count = m_compressed_geometries.size();
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);
BOOST_FOREACH(const std::vector<unsigned> & current_vector, m_compressed_geometries) {
compressed_node_count += current_vector.size();
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() <<
"surv: " << surviving_node_count <<
", comp: " << compressed_node_count <<
", comp ratio: " << ((float)surviving_node_count/std::max(compressed_node_count, 1u) );
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);
}
+21 -15
View File
@@ -25,34 +25,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include <algorithm>
#include <limits>
#include <vector>
#ifndef GEOMETRY_COMPRESSOR_H
#define GEOMETRY_COMPRESSOR_H
class GeometryCompressor {
public:
class GeometryCompressor
{
public:
typedef std::pair<NodeID, EdgeWeight> CompressedNode;
GeometryCompressor();
void AppendNodeIDsToGeomtry( NodeID node_id, NodeID contracted_node_id );
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:
private:
void IncreaseFreeList();
std::vector<std::vector<unsigned> > m_compressed_geometries;
std::vector<std::vector<CompressedNode> > m_compressed_geometries;
std::vector<unsigned> m_free_list;
boost::unordered_map<unsigned, unsigned> m_node_id_to_index_map;
boost::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
};
#endif //GEOMETRY_COMPRESSOR_H
#endif // GEOMETRY_COMPRESSOR_H
+14 -4
View File
@@ -43,7 +43,7 @@ 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));
}
@@ -65,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];
@@ -87,7 +87,7 @@ class UnorderedMapStorage {
typedef typename UnorderedMapType::const_iterator UnorderedMapConstIterator;
public:
UnorderedMapStorage( size_t ) {
explicit UnorderedMapStorage( size_t ) {
//hash table gets 1000 Buckets
nodes.rehash(1000);
}
@@ -96,6 +96,11 @@ public:
return nodes[node];
}
Key const & operator[]( const NodeID node ) const {
UnorderedMapConstIterator iter = nodes.find(node);
return iter->second;
}
void Clear() {
nodes.clear();
}
@@ -119,7 +124,7 @@ public:
typedef Weight WeightType;
typedef Data DataType;
BinaryHeap( size_t maxID )
explicit BinaryHeap( size_t maxID )
:
nodeIndex( maxID )
{
@@ -158,6 +163,11 @@ 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;
+1 -1
View File
@@ -40,7 +40,7 @@ template<typename Data>
class ConcurrentQueue {
public:
ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { }
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { }
inline void push(const Data & data) {
boost::mutex::scoped_lock lock(m_mutex);
+46 -25
View File
@@ -26,36 +26,54 @@ 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>
#include <cmath>
#include <climits>
#ifndef NDEBUG
#include <bitset>
#endif
#include <iostream>
#include <limits>
FixedPointCoordinate::FixedPointCoordinate()
: lat(INT_MIN),
lon(INT_MIN)
: 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 = INT_MIN;
lon = INT_MIN;
lat = std::numeric_limits<int>::min();
lon = std::numeric_limits<int>::min();
}
bool FixedPointCoordinate::isSet() const {
return (INT_MIN != lat) && (INT_MIN != lon);
return (std::numeric_limits<int>::min() != lat) &&
(std::numeric_limits<int>::min() != lon);
}
bool FixedPointCoordinate::isValid() const {
if(
lat > 90*COORDINATE_PRECISION ||
if (lat > 90*COORDINATE_PRECISION ||
lat < -90*COORDINATE_PRECISION ||
lon > 180*COORDINATE_PRECISION ||
lon < -180*COORDINATE_PRECISION
) {
lon < -180*COORDINATE_PRECISION)
{
return false;
}
return true;
@@ -70,10 +88,10 @@ double FixedPointCoordinate::ApproximateDistance(
const int lat2,
const int lon2
) {
BOOST_ASSERT(lat1 != INT_MIN);
BOOST_ASSERT(lon1 != INT_MIN);
BOOST_ASSERT(lat2 != INT_MIN);
BOOST_ASSERT(lon2 != INT_MIN);
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;
@@ -93,25 +111,24 @@ double FixedPointCoordinate::ApproximateDistance(
//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;
double distance=earth*cHarv;
return distance;
return earth*cHarv;
}
double FixedPointCoordinate::ApproximateDistance(
const FixedPointCoordinate &c1,
const FixedPointCoordinate &c2
) {
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
return ApproximateDistance(c1.lat, c1.lon, c2.lat, c2.lon);
}
double FixedPointCoordinate::ApproximateEuclideanDistance(
const FixedPointCoordinate &c1,
const FixedPointCoordinate &c2
) {
BOOST_ASSERT(c1.lat != INT_MIN);
BOOST_ASSERT(c1.lon != INT_MIN);
BOOST_ASSERT(c2.lat != INT_MIN);
BOOST_ASSERT(c2.lon != INT_MIN);
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;
@@ -121,8 +138,7 @@ double FixedPointCoordinate::ApproximateEuclideanDistance(
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;
return sqrt(x*x + y*y) * earthRadius;
}
void FixedPointCoordinate::convertInternalLatLonToString(
@@ -160,3 +176,8 @@ void FixedPointCoordinate::convertInternalReversedCoordinateToString(
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
}
void FixedPointCoordinate::Output(std::ostream & out) const
{
out << "(" << lat/COORDINATE_PRECISION << "," << lon/COORDINATE_PRECISION << ")";
}
+2 -2
View File
@@ -96,10 +96,10 @@ public:
DeallocatingVectorIterator() {}
template<typename T2>
DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> & r) : mState(r.mState) {}
explicit DeallocatingVectorIterator(const DeallocatingVectorIterator<T2> & r) : mState(r.mState) {}
DeallocatingVectorIterator(std::size_t idx, std::vector<ElementT *> & input_list) : mState(idx, input_list) {}
DeallocatingVectorIterator(const DeallocatingVectorIteratorState & r) : mState(r) {}
explicit DeallocatingVectorIterator(const DeallocatingVectorIteratorState & r) : mState(r) {}
template<typename T2>
DeallocatingVectorIterator& operator=(const DeallocatingVectorIterator<T2> &r) {
+1 -1
View File
@@ -57,7 +57,7 @@ class DynamicGraph {
};
//Constructs an empty graph with a given number of nodes.
DynamicGraph( int32_t nodes ) : m_numNodes(nodes), m_numEdges(0) {
explicit DynamicGraph( int32_t nodes ) : m_numNodes(nodes), m_numEdges(0) {
m_nodes.reserve( m_numNodes );
m_nodes.resize( m_numNodes );
+127 -143
View File
@@ -1,176 +1,160 @@
#ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H
#include <cmath>
#include <boost/assert.hpp>
#include "../Util/MercatorUtil.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
// An EdgeBasedNode represents a node in the edge-expanded graph.
#include <boost/assert.hpp>
#include <limits>
struct EdgeBasedNode {
EdgeBasedNode() :
id(INT_MAX),
lat1(INT_MAX),
lat2(INT_MAX),
lon1(INT_MAX),
lon2(INT_MAX >> 1),
belongsToTinyComponent(false),
nameID(UINT_MAX),
weight(UINT_MAX >> 1),
ignoreInGrid(false)
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)
{ }
// Computes:
// - the distance from the given query location to nearest point on this edge (and returns it)
// - the location on this edge which is nearest to the query location
// - the ratio ps:pq, where p and q are the end points of this edge, and s is the perpendicular foot of
// the query location on the line defined by p and q.
double ComputePerpendicularDistance(
const FixedPointCoordinate& query_location,
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 & ratio,
double precision = COORDINATE_PRECISION
) const {
double & r
) {
BOOST_ASSERT( query_location.isValid() );
const double epsilon = 1.0/precision;
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);
if( ignoreInGrid ) {
return std::numeric_limits<double>::max();
//discretize the result to coordinate precision. it's a hack!
if( std::abs(nY) < (1./COORDINATE_PRECISION) ) {
nY = 0.;
}
// p, q : the end points of the underlying edge
const Point p(lat2y(lat1/COORDINATE_PRECISION), lon1/COORDINATE_PRECISION);
const Point q(lat2y(lat2/COORDINATE_PRECISION), lon2/COORDINATE_PRECISION);
// r : query location
const Point r(lat2y(query_location.lat/COORDINATE_PRECISION),
query_location.lon/COORDINATE_PRECISION);
const Point foot = ComputePerpendicularFoot(p, q, r, epsilon);
ratio = ComputeRatio(p, q, foot, epsilon);
BOOST_ASSERT( !std::isnan(ratio) );
nearest_location = ComputeNearestPointOnSegment(foot, ratio);
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.0 <= approximated_distance );
const double approximated_distance = FixedPointCoordinate::ApproximateDistance(
query_location,
nearest_location
);
BOOST_ASSERT( 0. <= approximated_distance );
return approximated_distance;
}
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
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 operator==(const EdgeBasedNode & other) const {
return id == other.id;
}
// Returns the midpoint of the underlying edge.
inline FixedPointCoordinate Centroid() const {
return FixedPointCoordinate((lat1+lat2)/2, (lon1+lon2)/2);
}
NodeID id;
// The coordinates of the end-points of the underlying edge.
int lat1;
int lat2;
int lon1;
int lon2:31;
bool belongsToTinyComponent:1;
NodeID nameID;
// The weight of the underlying edge.
unsigned weight:31;
bool ignoreInGrid:1;
private:
typedef std::pair<double,double> Point;
// Compute the perpendicular foot of point r on the line defined by p and q.
Point ComputePerpendicularFoot(const Point &p, const Point &q, const Point &r, double epsilon) const {
// the projection of r onto the line pq
double foot_x, foot_y;
const bool is_parallel_to_y_axis = std::abs(q.first - p.first) < epsilon;
if( is_parallel_to_y_axis ) {
foot_x = q.first;
foot_y = r.second;
} else {
// the slope of the line through (a|b) and (c|d)
const double m = (q.second - p.second) / (q.first - p.first);
// Projection of (x|y) onto the line joining (a|b) and (c|d).
foot_x = ((r.first + (m*r.second)) + (m*m*p.first - m*p.second))/(1.0 + m*m);
foot_y = p.second + m*(foot_x - p.first);
}
return Point(foot_x, foot_y);
}
// Compute the ratio of the line segment pr to line segment pq.
double ComputeRatio(const Point & p, const Point & q, const Point & r, double epsilon) const {
const bool is_parallel_to_x_axis = std::abs(q.second-p.second) < epsilon;
const bool is_parallel_to_y_axis = std::abs(q.first -p.first ) < epsilon;
double ratio;
if( !is_parallel_to_y_axis ) {
ratio = (r.first - p.first)/(q.first - p.first);
} else if( !is_parallel_to_x_axis ) {
ratio = (r.second - p.second)/(q.second - p.second);
} else {
// (a|b) and (c|d) are essentially the same point
// by convention, we set the ratio to 0 in this case
//ratio = ((lat2 == query_location.lat) && (lon2 == query_location.lon)) ? 1. : 0.;
ratio = 0.0;
}
// Round to integer if the ratio is close to 0 or 1.
if( std::abs(ratio) <= epsilon ) {
ratio = 0.0;
} else if( std::abs(ratio-1.0) <= epsilon ) {
ratio = 1.0;
}
return ratio;
}
// Computes the point on the segment pq which is nearest to a point r = p + lambda * (q-p).
// p and q are the end points of the underlying edge.
FixedPointCoordinate ComputeNearestPointOnSegment(const Point & r, double lambda) const {
if( lambda <= 0.0 ) {
return FixedPointCoordinate(lat1, lon1);
} else if( lambda >= 1.0 ) {
return FixedPointCoordinate(lat2, lon2);
}
// r lies between p and q
return FixedPointCoordinate(
y2lat(r.first)*COORDINATE_PRECISION,
r.second*COORDINATE_PRECISION
);
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
+17 -12
View File
@@ -28,41 +28,46 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#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 : public boost::unordered_map<KeyT, ValueT> {
template<typename Key, typename Value, typename Hash = boost::hash<Key> >
class HashTable : public boost::unordered_map<Key, Value> {
private:
typedef boost::unordered_map<KeyT, ValueT> super;
typedef boost::unordered_map<Key, Value, Hash> super;
public:
static ValueT default_value;
static Value default_value;
HashTable() : super() { }
HashTable(const unsigned size) : super(size) { }
explicit HashTable(const unsigned size) : super(size) { }
inline void Add( KeyT const & key, ValueT const & value) {
inline void Add( Key const & key, Value const & value) {
super::emplace(std::make_pair(key, value));
}
inline const ValueT Find(KeyT const & key) const {
inline const Value Find(Key const & key) const
{
typename super::const_iterator iter = super::find(key);
if( iter == super::end() ) {
if (iter == super::end())
{
return boost::cref(default_value);
}
return boost::cref(iter->second);
}
inline bool Holds( KeyT const & key) const {
if( super::find(key) == super::end() ) {
inline const bool Holds( Key const & key) const
{
if(super::find(key) == super::end())
{
return false;
}
return true;
}
};
template<typename KeyT, typename ValueT>
ValueT HashTable<KeyT, ValueT>::default_value;
template<typename Key, typename Value, typename Hash>
Value HashTable<Key, Value, Hash>::default_value;
#endif /* HASH_TABLE_H */
+8 -4
View File
@@ -61,7 +61,8 @@ public:
bool ra,
bool ig,
bool ar,
bool cf
bool cf,
bool is_split
) : _source(s),
_target(t),
_name(n),
@@ -72,7 +73,8 @@ public:
_roundabout(ra),
_ignoreInGrid(ig),
_accessRestricted(ar),
_contraFlow(cf)
_contraFlow(cf),
is_split(is_split)
{
if(ty < 0) {
throw OSRMException("negative edge type");
@@ -93,6 +95,7 @@ public:
bool ignoreInGrid() const { return _ignoreInGrid; }
bool isAccessRestricted() const { return _accessRestricted; }
bool isContraFlow() const { return _contraFlow; }
bool IsSplit() const { return is_split; }
//TODO: names need to be fixed.
NodeID _source;
@@ -106,6 +109,7 @@ public:
bool _ignoreInGrid:1;
bool _accessRestricted:1;
bool _contraFlow:1;
bool is_split:1;
private:
NodeBasedEdge() { }
@@ -129,7 +133,7 @@ public:
}
template<class EdgeT>
EdgeBasedEdge(const EdgeT & myEdge ) :
explicit EdgeBasedEdge(const EdgeT & myEdge ) :
m_source(myEdge.source),
m_target(myEdge.target),
m_edgeID(myEdge.data.via),
@@ -162,7 +166,7 @@ public:
m_weight(w),
m_forward(f),
m_backward(b)
{}
{ }
NodeID target() const { return m_target; }
NodeID source() const { return m_source; }
+9 -1
View File
@@ -44,11 +44,17 @@ struct ExternalMemoryNode : NodeInfo {
bollard(bollard),
trafficLight(traffic_light)
{ }
ExternalMemoryNode() : bollard(false), trafficLight(false) {}
ExternalMemoryNode()
:
bollard(false),
trafficLight(false)
{ }
static ExternalMemoryNode min_value() {
return ExternalMemoryNode(0,0,0, false, false);
}
static ExternalMemoryNode max_value() {
return ExternalMemoryNode(
std::numeric_limits<int>::max(),
@@ -58,9 +64,11 @@ struct ExternalMemoryNode : NodeInfo {
false
);
}
NodeID key() const {
return id;
}
bool bollard;
bool trafficLight;
};
+6 -4
View File
@@ -29,6 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INPUTREADERFACTORY_H
#define INPUTREADERFACTORY_H
#include <boost/assert.hpp>
#include <bzlib.h>
#include <libxml/xmlreader.h>
@@ -51,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) {std::cerr << "Could not BZ2_bzReadGetUnused" <<std::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) {std::cerr << "Could not BZ2_bzReadClose" <<std::endl; exit(-1);};
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose");
context->error = BZ_STREAM_END; // set to the stream end for next call to this function
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){std::cerr << "Could not open file" <<std::endl; exit(-1);};
BOOST_ASSERT_MSG(NULL != context->bz2, "Could not open file");
}
} else { std::cerr << "Could not read bz2 file" << std::endl; exit(-1); }
} else { BOOST_ASSERT_MSG(false, "Could not read bz2 file"); }
}
return read;
}
+1 -1
View File
@@ -43,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()) {
+12 -8
View File
@@ -31,28 +31,32 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "TurnInstructions.h"
#include "../typedefs.h"
#include <climits>
#include <limits>
struct OriginalEdgeData{
explicit OriginalEdgeData(
NodeID via_node,
unsigned name_id,
TurnInstruction turn_instruction
TurnInstruction turn_instruction,
bool compressed_geometry
) :
via_node(via_node),
name_id(name_id),
turn_instruction(turn_instruction)
via_node( via_node ),
name_id( name_id ),
turn_instruction( turn_instruction ),
compressed_geometry( compressed_geometry )
{ }
OriginalEdgeData() :
via_node(UINT_MAX),
name_id(UINT_MAX),
turn_instruction(UCHAR_MAX)
via_node( std::numeric_limits<unsigned>::max() ),
name_id( std::numeric_limits<unsigned>::max() ),
turn_instruction( std::numeric_limits<unsigned char>::max() ),
compressed_geometry( false )
{ }
NodeID via_node;
unsigned name_id;
TurnInstruction turn_instruction;
bool compressed_geometry;
};
#endif //ORIGINAL_EDGE_DATA_H
+1 -1
View File
@@ -38,7 +38,7 @@ public:
* @param maxValue the value that corresponds to 100%
* @param 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);
}
+115 -45
View File
@@ -29,75 +29,145 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define PHANTOMNODES_H_
#include <osrm/Coordinate.h>
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
struct PhantomNode {
struct PhantomNode
{
PhantomNode() :
edgeBasedNode(UINT_MAX),
nodeBasedEdgeNameID(UINT_MAX),
weight1(INT_MAX),
weight2(INT_MAX),
ratio(0.)
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 edgeBasedNode;
unsigned nodeBasedEdgeNameID;
int weight1;
int weight2;
double ratio;
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;
void Reset() {
edgeBasedNode = UINT_MAX;
nodeBasedEdgeNameID = UINT_MAX;
weight1 = INT_MAX;
weight2 = INT_MAX;
ratio = 0.;
location.Reset();
}
bool isBidirected() const {
return weight2 != INT_MAX;
}
bool isValid(const unsigned numberOfNodes) const {
return location.isValid() && (edgeBasedNode < numberOfNodes) && (weight1 != INT_MAX) && (ratio >= 0.) && (ratio <= 1.) && (nodeBasedEdgeNameID != UINT_MAX);
unsigned short fwd_segment_position;
int GetForwardWeightPlusOffset() const
{
if (SPECIAL_NODEID == forward_node_id)
{
return 0;
}
const int result = (forward_offset + forward_weight);
return result;
}
bool operator==(const PhantomNode & other) const {
int GetReverseWeightPlusOffset() const
{
if (SPECIAL_NODEID == reverse_node_id)
{
return 0;
}
const int result = (reverse_offset + reverse_weight);
return result;
}
void Reset()
{
forward_node_id = SPECIAL_NODEID;
name_id = SPECIAL_NODEID;
forward_weight = INVALID_EDGE_WEIGHT;
reverse_weight = INVALID_EDGE_WEIGHT;
forward_offset = 0;
reverse_offset = 0;
location.Reset();
}
bool isBidirected() const
{
return (forward_node_id != SPECIAL_NODEID) &&
(reverse_node_id != SPECIAL_NODEID);
}
bool IsCompressed() const
{
return (forward_offset != 0) || (reverse_offset != 0);
}
bool isValid(const unsigned numberOfNodes) const
{
return
location.isValid() &&
(
(forward_node_id < numberOfNodes) ||
(reverse_node_id < numberOfNodes)
) &&
(
(forward_weight != INVALID_EDGE_WEIGHT) ||
(reverse_weight != INVALID_EDGE_WEIGHT)
) &&
(name_id != std::numeric_limits<unsigned>::max()
);
}
bool operator==(const PhantomNode & other) const
{
return location == other.location;
}
};
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;
}
-2
View File
@@ -30,8 +30,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h"
#include <climits>
struct QueryEdge {
NodeID source;
NodeID target;
+14 -13
View File
@@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _NODE_COORDS_H
#define _NODE_COORDS_H
#ifndef QUERY_NODE_H
#define QUERY_NODE_H
#include "../typedefs.h"
@@ -34,17 +34,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/assert.hpp>
#include <cstddef>
#include <climits>
#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(INT_MAX), lon(INT_MAX), id(UINT_MAX) {}
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;
@@ -69,18 +72,16 @@ struct NodeInfo {
switch(n) {
case 1:
return lat;
break;
// break;
case 0:
return lon;
break;
// break;
default:
BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX;
break;
}
BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX;
return std::numeric_limits<unsigned>::max();
}
};
#endif //_NODE_COORDS_H
#endif //QUERY_NODE_H
+10 -1
View File
@@ -70,10 +70,19 @@ struct RawRouteData {
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)
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)
{ }
};
+14 -14
View File
@@ -29,7 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define RESTRICTION_H_
#include "../typedefs.h"
#include <climits>
#include <limits>
struct TurnRestriction {
NodeID viaNode;
@@ -58,14 +59,13 @@ struct TurnRestriction {
bool unused7:1;
} flags;
TurnRestriction(NodeID viaNode) :
explicit TurnRestriction(NodeID viaNode) :
viaNode(viaNode),
fromNode(UINT_MAX),
toNode(UINT_MAX) {
fromNode(std::numeric_limits<unsigned>::max()),
toNode(std::numeric_limits<unsigned>::max()) {
}
TurnRestriction(const bool isOnly = false) :
explicit TurnRestriction(const bool isOnly = false) :
viaNode(UINT_MAX),
fromNode(UINT_MAX),
toNode(UINT_MAX) {
@@ -91,12 +91,12 @@ struct InputRestrictionContainer {
{
restriction.viaNode = vn;
}
InputRestrictionContainer(
explicit InputRestrictionContainer(
bool isOnly = false
) :
fromWay(UINT_MAX),
toWay(UINT_MAX),
viaNode(UINT_MAX)
fromWay(std::numeric_limits<unsigned>::max()),
toWay(std::numeric_limits<unsigned>::max()),
viaNode(std::numeric_limits<unsigned>::max())
{
restriction.flags.isOnly = isOnly;
}
@@ -106,10 +106,10 @@ struct InputRestrictionContainer {
}
static InputRestrictionContainer max_value() {
return InputRestrictionContainer(
UINT_MAX,
UINT_MAX,
UINT_MAX,
UINT_MAX
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max(),
std::numeric_limits<unsigned>::max()
);
}
};
+1 -1
View File
@@ -54,7 +54,7 @@ public:
ShortestPathRouting<DataFacadeT> shortest_path;
AlternativeRouting <DataFacadeT> alternative_path;
SearchEngine( DataFacadeT * facade )
explicit SearchEngine( DataFacadeT * facade )
:
facade (facade),
shortest_path (facade, engine_working_data),
+1 -1
View File
@@ -41,7 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct _HeapData {
NodeID parent;
_HeapData( NodeID p ) : parent(p) { }
/* explicit */ _HeapData( NodeID p ) : parent(p) { }
};
// typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
+60 -2
View File
@@ -41,7 +41,7 @@ template<typename DataT>
class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT> {
DataT * p;
public:
ShMemIterator(DataT * x) : p(x) {}
explicit ShMemIterator(DataT * x) : p(x) {}
ShMemIterator(const ShMemIterator & mit) : p(mit.p) {}
ShMemIterator& operator++() {
++p;
@@ -115,6 +115,8 @@ public:
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];
@@ -126,6 +128,63 @@ public:
}
};
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<
@@ -135,5 +194,4 @@ struct ShM {
>::type vector;
};
#endif //SHARED_MEMORY_VECTOR_WRAPPER_H
+7 -5
View File
@@ -112,16 +112,18 @@ public:
if(eid2 == UINT_MAX) {
SimpleLogger().Write(logWARNING) <<
"cannot find first segment of edge (" <<
u << "," << data.id << "," << v << ")";
u << "," << data.id << "," << v << "), eid: " << eid;
data.shortcut = false;
BOOST_ASSERT(false);
}
eid2 = FindEdgeInEitherDirection(data.id, v);
if(eid2 == UINT_MAX) {
SimpleLogger().Write(logWARNING) <<
"cannot find second segment of edge (" <<
u << "," << data.id << "," << v << ")";
u << "," << data.id << "," << v << "), eid2: " << eid2;
data.shortcut = false;
BOOST_ASSERT(false);
}
}
}
@@ -155,17 +157,17 @@ public:
}
EdgeIterator BeginEdges( const NodeIterator n ) const {
return EdgeIterator( _nodes[n].firstEdge );
return EdgeIterator( _nodes.at(n).firstEdge );
}
EdgeIterator EndEdges( const NodeIterator n ) const {
return EdgeIterator( _nodes[n+1].firstEdge );
return EdgeIterator( _nodes.at(n+1).firstEdge );
}
//searches for a specific edge
EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const {
EdgeIterator smallestEdge = SPECIAL_EDGEID;
EdgeWeight smallestWeight = UINT_MAX;
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;
+2 -2
View File
@@ -99,7 +99,7 @@ public:
}
};
StaticKDTree( std::vector< InputPoint > * points ){
explicit StaticKDTree( std::vector< InputPoint > * points ){
BOOST_ASSERT( k > 0 );
BOOST_ASSERT ( points->size() > 0 );
size = points->size();
@@ -207,7 +207,7 @@ private:
};
class Less {
public:
Less( unsigned d ) {
explicit Less( unsigned d ) {
dimension = d;
BOOST_ASSERT( dimension < k );
}
+101 -210
View File
@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "DeallocatingVector.h"
#include "HilbertValue.h"
#include "PhantomNodes.h"
#include "QueryNode.h"
#include "SharedMemoryFactory.h"
#include "SharedMemoryVectorWrapper.h"
@@ -51,6 +52,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#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>
@@ -68,7 +70,7 @@ const static uint32_t RTREE_LEAF_NODE_SIZE = 1170;
static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtree_stream;
template<class DataT, bool UseSharedMemory = false>
template<class DataT, class CoordinateListT = std::vector<FixedPointCoordinate>, bool UseSharedMemory = false>
class StaticRTree : boost::noncopyable {
public:
struct RectangleInt2D {
@@ -82,22 +84,35 @@ public:
int32_t min_lat, max_lat;
inline void InitializeMBRectangle(
const DataT * objects,
const uint32_t element_count
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(objects[i].lon1, objects[i].lon2)
min_lon, std::min(
coordinate_list.at(objects[i].u).lon,
coordinate_list.at(objects[i].v).lon
)
);
max_lon = std::max(
max_lon, std::max(objects[i].lon1, objects[i].lon2)
max_lon, std::max(
coordinate_list.at(objects[i].u).lon,
coordinate_list.at(objects[i].v).lon
)
);
min_lat = std::min(
min_lat, std::min(objects[i].lat1, objects[i].lat2)
min_lat, std::min(
coordinate_list.at(objects[i].u).lat,
coordinate_list.at(objects[i].v).lat
)
);
max_lat = std::max(
max_lat, std::max(objects[i].lat1, objects[i].lat2)
max_lat, std::max(
coordinate_list.at(objects[i].u).lat,
coordinate_list.at(objects[i].v).lat
)
);
}
}
@@ -221,9 +236,9 @@ public:
}
inline bool Contains(const FixedPointCoordinate & location) const {
bool lats_contained =
const bool lats_contained =
(location.lat > min_lat) && (location.lat < max_lat);
bool lons_contained =
const bool lons_contained =
(location.lon > min_lon) && (location.lon < max_lon);
return lats_contained && lons_contained;
}
@@ -289,21 +304,23 @@ private:
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::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 <<
" elements";
" edge elements build on-top of " << coordinate_list.size() << " coordinates";
double time1 = get_timestamp();
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
@@ -315,8 +332,17 @@ public:
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 & current_element = input_data_vector[element_counter];
FixedPointCoordinate current_centroid = current_element.Centroid();
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);
@@ -347,7 +373,11 @@ public:
}
//generate tree node that resemble the objects in leaf and store it for next level
current_node.minimum_bounding_rectangle.InitializeMBRectangle(current_leaf.objects, current_leaf.object_count);
current_node.minimum_bounding_rectangle.InitializeMBRectangle(
current_leaf.objects,
current_leaf.object_count,
coordinate_list
);
current_node.child_is_on_disk = true;
current_node.children[0] = tree_nodes_in_level.size();
tree_nodes_in_level.push_back(current_node);
@@ -426,9 +456,11 @@ public:
//Read-only operation for queries
explicit StaticRTree(
const boost::filesystem::path & node_file,
const boost::filesystem::path & leaf_file
) : m_leaf_node_filename(leaf_file.string()) {
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");
@@ -463,9 +495,11 @@ public:
explicit StaticRTree(
TreeNode * tree_node_ptr,
const uint32_t number_of_nodes,
const boost::filesystem::path & leaf_file
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_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 ) ) {
@@ -487,152 +521,7 @@ public:
//SimpleLogger().Write() << m_element_count << " elements in leafs";
}
//Read-only operation for queries
/*
inline void FindKNearestPhantomNodesForCoordinate(
const FixedPointCoordinate & location,
const unsigned zoom_level,
const unsigned candidate_count,
std::vector<std::pair<PhantomNode, double> > & result_vector
) const {
bool ignore_tiny_components = (zoom_level <= 14);
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;
traversal_queue.push(QueryCandidate(0, m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate)));
BOOST_ASSERT_MSG(std::numberic_limits<double>::epsilon() > (0. - traversal_queue.top().min_dist), "Root element in NN Search has min dist != 0.");
while(!traversal_queue.empty()) {
const QueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop();
++explored_tree_nodes_count;
bool prune_downward = (current_query_node.min_dist >= min_max_dist);
bool prune_upward = (current_query_node.min_dist >= min_dist);
if( !prune_downward && !prune_upward ) { //downward pruning
TreeNode & current_tree_node = m_search_tree[current_query_node.node_id];
if (current_tree_node.child_is_on_disk) {
LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
++io_count;
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
DataT & current_edge = current_leaf_node.objects[i];
if(ignore_tiny_components && current_edge.belongsToTinyComponent) {
continue;
}
double current_ratio = 0.;
double current_perpendicular_distance = current_edge.ComputePerpendicularDistance(
input_coordinate,
nearest,
current_ratio
);
if(
current_perpendicular_distance < min_dist
&& !DoubleEpsilonCompare(
current_perpendicular_distance,
min_dist
)
) { //found a new minimum
min_dist = current_perpendicular_distance;
result_phantom_node.edgeBasedNode = current_edge.id;
result_phantom_node.nodeBasedEdgeNameID = current_edge.nameID;
result_phantom_node.weight1 = current_edge.weight;
result_phantom_node.weight2 = INT_MAX;
result_phantom_node.location = nearest;
current_start_coordinate.lat = current_edge.lat1;
current_start_coordinate.lon = current_edge.lon1;
current_end_coordinate.lat = current_edge.lat2;
current_end_coordinate.lon = current_edge.lon2;
nearest_edge = current_edge;
found_a_nearest_edge = true;
} else if(
DoubleEpsilonCompare(current_perpendicular_distance, min_dist) &&
1 == abs(current_edge.id - result_phantom_node.edgeBasedNode )
&& EdgesAreEquivalent(
current_start_coordinate,
FixedPointCoordinate(
current_edge.lat1,
current_edge.lon1
),
FixedPointCoordinate(
current_edge.lat2,
current_edge.lon2
),
current_end_coordinate
)
) {
result_phantom_node.edgeBasedNode = std::min(current_edge.id, result_phantom_node.edgeBasedNode);
result_phantom_node.weight2 = current_edge.weight;
}
}
} else {
//traverse children, prune if global mindist is smaller than local one
for (uint32_t i = 0; i < current_tree_node.child_count; ++i) {
const int32_t child_id = current_tree_node.children[i];
TreeNode & child_tree_node = m_search_tree[child_id];
RectangleT & child_rectangle = child_tree_node.minimum_bounding_rectangle;
const double current_min_dist = child_rectangle.GetMinDist(input_coordinate);
const double current_min_max_dist = child_rectangle.GetMinMaxDist(input_coordinate);
if( current_min_max_dist < min_max_dist ) {
min_max_dist = current_min_max_dist;
}
if (current_min_dist > min_max_dist) {
continue;
}
if (current_min_dist > min_dist) { //upward pruning
continue;
}
traversal_queue.push(QueryCandidate(child_id, current_min_dist));
}
}
}
}
const double distance_to_edge =
ApproximateDistance (
FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1),
result_phantom_node.location
);
const double length_of_edge =
ApproximateDistance(
FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1),
FixedPointCoordinate(nearest_edge.lat2, nearest_edge.lon2)
);
const double ratio = (found_a_nearest_edge ?
std::min(1., distance_to_edge/ length_of_edge ) : 0 );
result_phantom_node.weight1 *= ratio;
if(INT_MAX != result_phantom_node.weight2) {
result_phantom_node.weight2 *= (1.-ratio);
}
result_phantom_node.ratio = ratio;
//Hack to fix rounding errors and wandering via nodes.
if(std::abs(input_coordinate.lon - result_phantom_node.location.lon) == 1) {
result_phantom_node.location.lon = input_coordinate.lon;
}
if(std::abs(input_coordinate.lat - result_phantom_node.location.lat) == 1) {
result_phantom_node.location.lat = input_coordinate.lat;
}
SimpleLogger().Write() << "mindist: " << min_distphantom_node.isBidirected() ? "yes" : "no");
return found_a_nearest_edge;
}
*/
bool LocateClosestEndPointForCoordinate(
const FixedPointCoordinate & input_coordinate,
FixedPointCoordinate & result_coordinate,
@@ -671,7 +560,7 @@ public:
current_leaf_node
);
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
const DataT & current_edge = current_leaf_node.objects[i];
DataT const & current_edge = current_leaf_node.objects[i];
if(
ignore_tiny_components &&
current_edge.belongsToTinyComponent
@@ -682,29 +571,29 @@ public:
double current_minimum_distance = FixedPointCoordinate::ApproximateDistance(
input_coordinate.lat,
input_coordinate.lon,
current_edge.lat1,
current_edge.lon1
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 = current_edge.lat1;
result_coordinate.lon = current_edge.lon1;
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,
current_edge.lat2,
current_edge.lon2
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 = current_edge.lat2;
result_coordinate.lon = current_edge.lon2;
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;
}
}
@@ -783,7 +672,9 @@ public:
}
double current_ratio = 0.;
double current_perpendicular_distance = current_edge.ComputePerpendicularDistance(
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
@@ -799,41 +690,24 @@ public:
)
) { //found a new minimum
min_dist = current_perpendicular_distance;
result_phantom_node.edgeBasedNode = current_edge.id;
result_phantom_node.nodeBasedEdgeNameID = current_edge.nameID;
result_phantom_node.weight1 = current_edge.weight;
result_phantom_node.weight2 = INT_MAX;
//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 = current_edge.lat1;
current_start_coordinate.lon = current_edge.lon1;
current_end_coordinate.lat = current_edge.lat2;
current_end_coordinate.lon = current_edge.lon2;
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
if( DoubleEpsilonCompare(current_perpendicular_distance, min_dist) &&
( 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) ) &&
EdgesAreEquivalent(
current_start_coordinate,
FixedPointCoordinate(
current_edge.lat1,
current_edge.lon1
),
FixedPointCoordinate(
current_edge.lat2,
current_edge.lon2
),
current_end_coordinate
)
) {
BOOST_ASSERT_MSG(current_edge.id != result_phantom_node.edgeBasedNode, "IDs not different");
result_phantom_node.weight2 = current_edge.weight;
if(current_edge.id < result_phantom_node.edgeBasedNode) {
result_phantom_node.edgeBasedNode = current_edge.id;
std::swap(result_phantom_node.weight1, result_phantom_node.weight2);
std::swap(current_end_coordinate, current_start_coordinate);
}
}
}
} else {
@@ -884,11 +758,28 @@ public:
ratio = std::min(1., ratio);
}
result_phantom_node.weight1 *= ratio;
if(INT_MAX != result_phantom_node.weight2) {
result_phantom_node.weight2 *= (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;
}
result_phantom_node.ratio = 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;
}
-2
View File
@@ -92,6 +92,4 @@ struct TurnInstructionsClass : boost::noncopyable {
};
static TurnInstructionsClass TurnInstructions;
#endif /* TURNINSTRUCTIONS_H_ */
+1 -1
View File
@@ -54,7 +54,7 @@ public:
}
};
XORFastHashStorage( size_t ) : positions(2<<16), currentTimestamp(0) { }
explicit XORFastHashStorage( size_t ) : positions(2<<16), currentTimestamp(0) { }
inline HashCell& operator[]( const NodeID node ) {
unsigned short position = fastHash(node);
+33 -36
View File
@@ -31,18 +31,18 @@ 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 FixedPointCoordinate & A,
const FixedPointCoordinate & B
) const {
double DescriptionFactory::GetBearing(const FixedPointCoordinate & A, const FixedPointCoordinate & B) const
{
double delta_long = DegreeToRadian(B.lon/COORDINATE_PRECISION - A.lon/COORDINATE_PRECISION);
const double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION);
@@ -51,55 +51,52 @@ double DescriptionFactory::GetBearing(
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.) {
while (result >= 360.)
{
result -= 360.;
}
return result;
}
void DescriptionFactory::SetStartSegment(const PhantomNode & start) {
start_phantom = start;
void DescriptionFactory::SetStartSegment(const PhantomNode & source, const bool source_traversed_in_reverse)
{
start_phantom = source;
AppendSegment(
start.location,
PathData(0, start.nodeBasedEdgeNameID, 10, start.weight1)
source.location,
PathData(0, source.name_id, 10, source.forward_weight)
);
}
void DescriptionFactory::SetEndSegment(const PhantomNode & target) {
void DescriptionFactory::SetEndSegment(const PhantomNode & target, const bool target_traversed_in_reverse)
{
target_phantom = target;
pathDescription.push_back(
SegmentInformation(
target.location,
target.nodeBasedEdgeNameID,
target.name_id,
0,
target.weight1,
target.reverse_weight,
0,
true
)
);
}
void DescriptionFactory::AppendSegment(
const FixedPointCoordinate & coordinate,
const PathData & data
) {
if(
( 1 == pathDescription.size()) &&
( pathDescription.back().location == coordinate)
) {
pathDescription.back().name_id = data.name_id;
} else {
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;
}
else
{
pathDescription.push_back(
SegmentInformation(
coordinate,
data.name_id,
data.durationOfSegment,
0,
data.turnInstruction
)
SegmentInformation(coordinate, path_point.name_id, path_point.durationOfSegment, 0, path_point.turnInstruction)
);
}
}
@@ -137,7 +134,7 @@ void DescriptionFactory::BuildRouteSummary(
const double distance,
const unsigned time
) {
summary.startName = start_phantom.nodeBasedEdgeNameID;
summary.destName = target_phantom.nodeBasedEdgeNameID;
summary.startName = start_phantom.name_id;
summary.destName = target_phantom.name_id;
summary.BuildDurationAndLengthStrings(distance, time);
}
+21 -26
View File
@@ -71,7 +71,7 @@ public:
) {
//compute distance/duration for route summary
intToString(round(distance), lengthString);
int travel_time = time/10;
int travel_time = round(time/10.);
intToString(std::max(travel_time, 1), durationString);
}
} summary;
@@ -87,8 +87,8 @@ public:
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 & start_phantom);
void SetEndSegment(const PhantomNode & start_phantom);
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
@@ -105,14 +105,13 @@ public:
/** starts at index 1 */
pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
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);
}
// std::string string0 = facade->GetEscapedNameForNameID(pathDescription[0].name_id);
// std::string string1;
/*Simplify turn instructions
Input :
10. Turn left on B 36 for 20 km
@@ -154,23 +153,23 @@ public:
// string0 = string1;
// }
double lengthOfSegment = 0;
unsigned durationOfSegment = 0;
unsigned indexOfSegmentBegin = 0;
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;
lengthOfSegment += pathDescription[i].length;
durationOfSegment += pathDescription[i].duration;
pathDescription[indexOfSegmentBegin].length = lengthOfSegment;
pathDescription[indexOfSegmentBegin].duration = durationOfSegment;
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);
lengthOfSegment = 0;
durationOfSegment = 0;
indexOfSegmentBegin = i;
segment_length = 0;
segment_duration = 0;
segment_start_index = i;
}
}
@@ -179,21 +178,17 @@ public:
if(pathDescription.size() > 2){
pathDescription.pop_back();
pathDescription.back().necessary = true;
pathDescription.back().turn_instruction = TurnInstructions.NoTurn;
target_phantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->name_id;
pathDescription.back().turn_instruction = TurnInstructionsClass::NoTurn;
target_phantom.name_id = (pathDescription.end()-2)->name_id;
}
} else {
pathDescription[indexOfSegmentBegin].duration *= (1.-target_phantom.ratio);
}
if(std::numeric_limits<double>::epsilon() > pathDescription[0].length) {
if(pathDescription.size() > 2) {
pathDescription.erase(pathDescription.begin());
pathDescription[0].turn_instruction = TurnInstructions.HeadOn;
pathDescription[0].turn_instruction = TurnInstructionsClass::HeadOn;
pathDescription[0].necessary = true;
start_phantom.nodeBasedEdgeNameID = pathDescription[0].name_id;
start_phantom.name_id = pathDescription[0].name_id;
}
} else {
pathDescription[0].duration *= start_phantom.ratio;
}
//Generalize poly line
+4 -4
View File
@@ -65,12 +65,12 @@ public:
(raw_route.unpacked_path_segments[0].size());
if( found_route ) {
FixedPointCoordinate::convertInternalLatLonToString(
phantom_node_list.startPhantom.location.lat,
phantom_node_list.source_phantom.location.lat,
tmp
);
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
FixedPointCoordinate::convertInternalLatLonToString(
phantom_node_list.startPhantom.location.lon,
phantom_node_list.source_phantom.location.lon,
tmp
);
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
@@ -90,12 +90,12 @@ public:
}
// Add the via point or the end coordinate
FixedPointCoordinate::convertInternalLatLonToString(
phantom_node_list.targetPhantom.location.lat,
phantom_node_list.target_phantom.location.lat,
tmp
);
reply.content.push_back("<rtept lat=\"" + tmp + "\" ");
FixedPointCoordinate::convertInternalLatLonToString(
phantom_node_list.targetPhantom.location.lon,
phantom_node_list.target_phantom.location.lon,
tmp
);
reply.content.push_back("lon=\"" + tmp + "\"></rtept>");
+84 -52
View File
@@ -44,6 +44,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
template<class DataFacadeT>
class JSONDescriptor : public BaseDescriptor<DataFacadeT> {
private:
// TODO: initalize in c'tor
DataFacadeT * facade;
DescriptorConfig config;
DescriptionFactory description_factory;
@@ -59,7 +60,7 @@ private:
int start_index;
int name_id;
int leave_at_exit;
} roundAbout;
} round_about;
struct Segment {
Segment() : name_id(-1), length(-1), position(-1) {}
@@ -90,7 +91,7 @@ public:
void SetConfig(const DescriptorConfig & c) { config = c; }
int DescribeLeg(
const std::vector<PathData> & route_leg,
const std::vector<PathData> route_leg,
const PhantomNodes & leg_phantoms
) {
int added_element_count = 0;
@@ -98,10 +99,10 @@ public:
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 );
description_factory.AppendSegment(current_coordinate, path_data);
++added_element_count;
}
// description_factory.SetEndSegment( leg_phantoms.targetPhantom );
// description_factory.SetEndSegment( leg_phantoms.target_phantom );
++added_element_count;
BOOST_ASSERT( (int)(route_leg.size() + 1) == added_element_count );
return added_element_count;
@@ -119,7 +120,8 @@ public:
"{\"status\":"
);
if(INT_MAX == raw_route.lengthOfShortestPath) {
if (INVALID_EDGE_WEIGHT == raw_route.lengthOfShortestPath)
{
//We do not need to do much, if there is no route ;-)
reply.content.push_back(
"207,\"status_message\": \"Cannot find route between points\"}"
@@ -127,12 +129,36 @@ public:
return;
}
description_factory.SetStartSegment(phantom_nodes.startPhantom);
SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.lengthOfShortestPath;
//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);
}
}
//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 ) {
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]
@@ -142,7 +168,7 @@ public:
added_segments + shortest_leg_end_indices.back()
);
}
description_factory.SetEndSegment(phantom_nodes.targetPhantom);
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\": ");
@@ -194,14 +220,15 @@ public:
//only one alternative route is computed at this time, so this is hardcoded
if(raw_route.lengthOfAlternativePath != INT_MAX) {
alternate_descriptionFactory.SetStartSegment(phantom_nodes.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 & path_data, raw_route.unpacked_alternative) {
current = facade->GetCoordinateOfNode(path_data.node);
alternate_descriptionFactory.AppendSegment(current, path_data );
}
alternate_descriptionFactory.SetEndSegment(phantom_nodes.targetPhantom);
alternate_descriptionFactory.SetEndSegment(phantom_nodes.target_phantom, raw_route.alt_target_traversed_in_reverse);
}
alternate_descriptionFactory.Run(facade, config.zoom_level);
@@ -286,7 +313,7 @@ public:
std::string tmp;
FixedPointCoordinate::convertInternalReversedCoordinateToString(
raw_route.segmentEndCoordinates.front().startPhantom.location,
raw_route.segmentEndCoordinates.front().source_phantom.location,
tmp
);
reply.content.push_back("[");
@@ -296,7 +323,7 @@ public:
BOOST_FOREACH(const PhantomNodes & nodes, raw_route.segmentEndCoordinates) {
tmp.clear();
FixedPointCoordinate::convertInternalReversedCoordinateToString(
nodes.targetPhantom.location,
nodes.target_phantom.location,
tmp
);
reply.content.push_back(",[");
@@ -332,11 +359,11 @@ public:
std::string hint;
for(unsigned i = 0; i < raw_route.segmentEndCoordinates.size(); ++i) {
reply.content.push_back("\"");
EncodeObjectToBase64(raw_route.segmentEndCoordinates[i].startPhantom, hint);
EncodeObjectToBase64(raw_route.segmentEndCoordinates[i].source_phantom, hint);
reply.content.push_back(hint);
reply.content.push_back("\", ");
}
EncodeObjectToBase64(raw_route.segmentEndCoordinates.back().targetPhantom, hint);
EncodeObjectToBase64(raw_route.segmentEndCoordinates.back().target_phantom, hint);
reply.content.push_back("\"");
reply.content.push_back(hint);
reply.content.push_back("\"]");
@@ -419,56 +446,61 @@ public:
//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.leave_at_exit = 0;
roundAbout.name_id = 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, description_factory.pathDescription) {
TurnInstruction current_instruction = segment.turn_instruction & TurnInstructions.InverseAccessRestrictionFlag;
TurnInstruction current_instruction = segment.turn_instruction & TurnInstructionsClass::InverseAccessRestrictionFlag;
entered_restricted_area_count += (current_instruction != segment.turn_instruction);
if(TurnInstructions.TurnIsNecessary( current_instruction) ) {
if(TurnInstructions.EnterRoundAbout == current_instruction) {
roundAbout.name_id = segment.name_id;
roundAbout.start_index = prefixSumOfNecessarySegments;
} else {
if(0 != prefixSumOfNecessarySegments){
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 (0 != necessary_segments_running_index)
{
reply.content.push_back(",");
}
reply.content.push_back("[\"");
if(TurnInstructions.LeaveRoundAbout == current_instruction) {
intToString(TurnInstructions.EnterRoundAbout, tmpInstruction);
reply.content.push_back(tmpInstruction);
if(TurnInstructionsClass::LeaveRoundAbout == current_instruction) {
intToString(TurnInstructionsClass::EnterRoundAbout, temp_instruction);
reply.content.push_back(temp_instruction);
reply.content.push_back("-");
intToString(roundAbout.leave_at_exit+1, tmpInstruction);
reply.content.push_back(tmpInstruction);
roundAbout.leave_at_exit = 0;
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, tmpInstruction);
reply.content.push_back(tmpInstruction);
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, tmpDist);
reply.content.push_back(tmpDist);
intToString(segment.length, temp_dist);
reply.content.push_back(temp_dist);
reply.content.push_back(",");
intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content.push_back(tmpLength);
intToString(necessary_segments_running_index, temp_length);
reply.content.push_back(temp_length);
reply.content.push_back(",");
intToString(segment.duration/10, tmpDuration);
reply.content.push_back(tmpDuration);
intToString(round(segment.duration/10.), temp_duration);
reply.content.push_back(temp_duration);
reply.content.push_back(",\"");
intToString(segment.length, tmpLength);
reply.content.push_back(tmpLength);
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, tmpBearing);
reply.content.push_back(tmpBearing);
intToString(bearing_value, temp_bearing);
reply.content.push_back(temp_bearing);
reply.content.push_back("]");
route_segments_list.push_back(
@@ -479,22 +511,22 @@ public:
)
);
}
} else if(TurnInstructions.StayOnRoundAbout == current_instruction) {
++roundAbout.leave_at_exit;
} else if(TurnInstructionsClass::StayOnRoundAbout == current_instruction) {
++round_about.leave_at_exit;
}
if(segment.necessary)
++prefixSumOfNecessarySegments;
++necessary_segments_running_index;
}
if(INT_MAX != route_length) {
reply.content.push_back(",[\"");
intToString(TurnInstructions.ReachedYourDestination, tmpInstruction);
reply.content.push_back(tmpInstruction);
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(prefixSumOfNecessarySegments-1, tmpLength);
reply.content.push_back(tmpLength);
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(",\"");
+9 -6
View File
@@ -362,7 +362,6 @@ void ExtractionContainers::PrepareData(
break;
default:
throw OSRMException("edge has broken direction");
break;
}
file_out_stream.write(
(char*)&integer_weight, sizeof(int)
@@ -373,23 +372,27 @@ void ExtractionContainers::PrepareData(
sizeof(short)
);
file_out_stream.write(
(char*)&edge_iterator->nameID,
(char *) &edge_iterator->nameID,
sizeof(unsigned)
);
file_out_stream.write(
(char*)&edge_iterator->isRoundabout,
(char *) &edge_iterator->isRoundabout,
sizeof(bool)
);
file_out_stream.write(
(char*)&edge_iterator->ignoreInGrid,
(char *) &edge_iterator->ignoreInGrid,
sizeof(bool)
);
file_out_stream.write(
(char*)&edge_iterator->isAccessRestricted,
(char *) &edge_iterator->isAccessRestricted,
sizeof(bool)
);
file_out_stream.write(
(char*)&edge_iterator->isContraFlow,
(char *) &edge_iterator->isContraFlow,
sizeof(bool)
);
file_out_stream.write(
(char *) &edge_iterator->is_split,
sizeof(bool)
);
++number_of_used_edges;
+8 -8
View File
@@ -75,13 +75,13 @@ inline unsigned parseDuration(const std::string &s) {
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_ */
+35 -36
View File
@@ -25,36 +25,30 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ExtractionContainers.h"
#include "ExtractionHelperFunctions.h"
#include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "ExtractionContainers.h"
#include "ExtractionWay.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/SimpleLogger.h"
#include <osrm/Coordinate.h>
#include <cfloat>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include <string>
#include <vector>
ExtractorCallbacks::ExtractorCallbacks()
:
stringMap(NULL),
string_map(NULL),
externalMemory(NULL)
{ }
ExtractorCallbacks::ExtractorCallbacks(
ExtractionContainers * ext,
StringMap * strMap
boost::unordered_map<std::string, NodeID> * string_map
) :
stringMap(strMap),
string_map(string_map),
externalMemory(ext)
{ }
@@ -94,11 +88,11 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
}
//Get the unique identifier for the street name
const StringMap::const_iterator & string_map_iterator = stringMap->find(parsed_way.name);
if(stringMap->end() == string_map_iterator) {
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);
stringMap->insert(std::make_pair(parsed_way.name, parsed_way.nameID));
string_map->insert(std::make_pair(parsed_way.name, parsed_way.nameID));
} else {
parsed_way.nameID = string_map_iterator->second;
}
@@ -112,16 +106,19 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
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
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]);
@@ -135,17 +132,19 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
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)
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
)
);
}
+3 -5
View File
@@ -28,29 +28,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef EXTRACTORCALLBACKS_H_
#define EXTRACTORCALLBACKS_H_
#include "ExtractorStructs.h"
#include "../typedefs.h"
#include <boost/unordered_map.hpp>
#include <string>
struct ExternalMemoryNode;
class ExtractionContainers;
struct ExtractionWay;
struct InputRestrictionContainer;
typedef boost::unordered_map<std::string, NodeID> StringMap;
class ExtractorCallbacks{
private:
StringMap * stringMap;
boost::unordered_map<std::string, NodeID> * string_map;
ExtractionContainers * externalMemory;
ExtractorCallbacks();
public:
explicit ExtractorCallbacks(
ExtractionContainers * ext,
StringMap * strMap
boost::unordered_map<std::string, NodeID> * string_map
);
~ExtractorCallbacks();
+33 -67
View File
@@ -28,9 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INTERNAL_EXTRACTOR_EDGE_H
#define INTERNAL_EXTRACTOR_EDGE_H
#include <osrm/Coordinate.h>
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
@@ -47,70 +47,10 @@ struct InternalExtractorEdge {
ignoreInGrid(false),
isDurationSet(false),
isAccessRestricted(false),
isContraFlow(false)
isContraFlow(false),
is_split(false)
{ }
explicit InternalExtractorEdge(NodeID start, NodeID target)
:
start(start),
target(target),
type(0),
direction(0),
speed(0),
nameID(0),
isRoundabout(false),
ignoreInGrid(false),
isDurationSet(false),
isAccessRestricted(false),
isContraFlow(false)
{ }
explicit InternalExtractorEdge(
NodeID start,
NodeID target,
short type,
short d,
double speed
) :
start(start),
target(target),
type(type),
direction(d),
speed(speed),
nameID(0),
isRoundabout(false),
ignoreInGrid(false),
isDurationSet(false),
isAccessRestricted(false),
isContraFlow(false)
{ }
explicit InternalExtractorEdge(
NodeID start,
NodeID target,
short type,
short direction,
double speed,
unsigned nameID,
bool isRoundabout,
bool ignoreInGrid,
bool isDurationSet,
bool isAccressRestricted
) :
start(start),
target(target),
type(type),
direction(direction),
speed(speed),
nameID(nameID),
isRoundabout(isRoundabout),
ignoreInGrid(ignoreInGrid),
isDurationSet(isDurationSet),
isAccessRestricted(isAccressRestricted),
isContraFlow(false)
{
BOOST_ASSERT(0 <= type);
}
explicit InternalExtractorEdge(
NodeID start,
@@ -123,7 +63,8 @@ struct InternalExtractorEdge {
bool ignoreInGrid,
bool isDurationSet,
bool isAccressRestricted,
bool isContraFlow
bool isContraFlow,
bool is_split
) :
start(start),
target(target),
@@ -135,19 +76,43 @@ struct InternalExtractorEdge {
ignoreInGrid(ignoreInGrid),
isDurationSet(isDurationSet),
isAccessRestricted(isAccressRestricted),
isContraFlow(isContraFlow)
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);
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()
std::numeric_limits<unsigned>::max(),
0,
0,
0,
0,
false,
false,
false,
false,
false,
false
);
}
@@ -162,6 +127,7 @@ struct InternalExtractorEdge {
bool isDurationSet;
bool isAccessRestricted;
bool isContraFlow;
bool is_split;
FixedPointCoordinate startCoord;
FixedPointCoordinate targetCoord;
+24 -22
View File
@@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/Restriction.h"
#include "../Util/MachineInfo.h"
#include "../Util/OpenMPWrapper.h"
@@ -214,25 +215,26 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
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) {
for(int i = 0; i < number_of_nodes; ++i)
{
ImportNode & import_node = extracted_nodes_vector[i];
ParseNodeInLua(
import_node,
scripting_environment.getLuaStateForThreadID(omp_get_thread_num())
);
ParseNodeInLua(import_node, scripting_environment.getLuaStateForThreadID(thread_num));
}
}
BOOST_FOREACH(const ImportNode &import_node, extracted_nodes_vector) {
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::parseNode(_ThreadData * )
{
throw OSRMException("Parsing of simple nodes not supported. PBF should use dense nodes");
}
inline void PBFParser::parseRelation(_ThreadData * threadData) {
@@ -351,24 +353,24 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
}
#pragma omp parallel for schedule ( guided )
for(int i = 0; i < number_of_ways; ++i) {
for(int i = 0; i < number_of_ways; ++i)
{
ExtractionWay & extraction_way = parsed_way_vector[i];
if (2 > extraction_way.path.size())
if (2 <= extraction_way.path.size())
{
continue;
ParseWayInLua(
extraction_way,
scripting_environment.getLuaStateForThreadID(omp_get_thread_num())
);
}
ParseWayInLua(
extraction_way,
scripting_environment.getLuaStateForThreadID( omp_get_thread_num())
);
}
BOOST_FOREACH(ExtractionWay & extraction_way, parsed_way_vector) {
if (2 > extraction_way.path.size())
BOOST_FOREACH(ExtractionWay & extraction_way, parsed_way_vector)
{
if (2 <= extraction_way.path.size())
{
continue;
extractor_callbacks->wayFunction(extraction_way);
}
extractor_callbacks->wayFunction(extraction_way);
}
}
+6 -6
View File
@@ -76,13 +76,13 @@ public:
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);
inline void parseNode (_ThreadData * threadData);
inline void parseRelation (_ThreadData * threadData);
inline void parseWay (_ThreadData * threadData);
inline void loadGroup (_ThreadData * threadData);
inline void loadBlock (_ThreadData * threadData);
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);
+2 -4
View File
@@ -58,7 +58,6 @@ ScriptingEnvironment::ScriptingEnvironment(const char * 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)
];
@@ -106,9 +105,8 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
// fails on c++11/OS X 10.9
luabind::module(myLuaState) [
luabind::class_<std::vector<std::string> >("vector")
.def("Add", static_cast<void (std::vector<std::string>::*)(const std::string&)>(&std::vector<std::string>::push_back)
)
luabind::class_<std::vector<std::string> >("vector")
.def("Add", static_cast<void (std::vector<std::string>::*)(const std::string&)>(&std::vector<std::string>::push_back))
];
if(0 != luaL_dofile(myLuaState, fileName) ) {
+1 -1
View File
@@ -35,7 +35,7 @@ struct lua_State;
class ScriptingEnvironment {
public:
ScriptingEnvironment();
ScriptingEnvironment(const char * fileName);
explicit ScriptingEnvironment(const char * fileName);
virtual ~ScriptingEnvironment();
lua_State * getLuaStateForThreadID(const int);
+278 -218
View File
@@ -28,6 +28,8 @@ 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"
@@ -40,249 +42,307 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/ref.hpp>
XMLParser::XMLParser(const char * filename, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser(ec, se) {
inputReader = inputReaderFactory(filename);
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 );
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;
}
// 1 is Element
if (type != 1)
{
continue;
}
xmlChar* currentName = xmlTextReaderName( inputReader );
if ( currentName == NULL ) {
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(!extractor_callbacks->nodeFunction(n))
// std::cerr << "[XMLParser] dense node not parsed" << std::endl;
}
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(!extractor_callbacks->wayFunction(way))
// std::cerr << "[PBFParser] way not parsed" << std::endl;
}
if( use_turn_restrictions ) {
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
InputRestrictionContainer r = _ReadXMLRestriction();
if(r.fromWay != UINT_MAX) {
if(!extractor_callbacks->restrictionFunction(r)) {
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
}
}
}
}
xmlFree( currentName );
}
return true;
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 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 (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 ( xmlStrEqual(k, (const xmlChar *) "except") ) {
except_tag_string = (const char*) value;
}
}
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 (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 (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 (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;
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;
}
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 (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" );
// 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( stringToUint(( const char* ) ref ) );
xmlFree( ref );
}
}
xmlFree( childName );
}
}
return way;
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;
ImportNode XMLParser::ReadXMLNode()
{
ImportNode node;
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
if ( attribute != NULL ) {
node.lat = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute ) );
xmlFree( attribute );
}
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
if ( attribute != NULL ) {
node.lon = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute ));
xmlFree( attribute );
}
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
if ( attribute != NULL ) {
node.id = stringToUint(( const char* ) attribute );
xmlFree( attribute );
}
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 (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 (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 );
}
}
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;
xmlFree(childName);
}
}
return node;
}
+8 -12
View File
@@ -33,21 +33,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <libxml/xmlreader.h>
class XMLParser : public BaseParser {
public:
XMLParser(
const char* filename,
ExtractorCallbacks* ec,
ScriptingEnvironment& se
);
class XMLParser : public BaseParser
{
public:
XMLParser(const char *filename, ExtractorCallbacks *ec, ScriptingEnvironment &se);
bool ReadHeader();
bool Parse();
private:
InputRestrictionContainer _ReadXMLRestriction();
ExtractionWay _ReadXMLWay();
ImportNode _ReadXMLNode();
private:
InputRestrictionContainer ReadXMLRestriction();
ExtractionWay ReadXMLWay();
ImportNode ReadXMLNode();
xmlTextReaderPtr inputReader;
};
+7 -5
View File
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef FIXED_POINT_COORDINATE_H_
#define FIXED_POINT_COORDINATE_H_
#include <iostream>
#include <iosfwd> //for std::ostream
static const double COORDINATE_PRECISION = 1000000.;
@@ -37,7 +37,7 @@ struct FixedPointCoordinate {
int lon;
FixedPointCoordinate();
explicit FixedPointCoordinate (int lat, int lon);
explicit FixedPointCoordinate( int lat, int lon);
void Reset();
bool isSet() const;
bool isValid() const;
@@ -74,11 +74,13 @@ struct FixedPointCoordinate {
const FixedPointCoordinate & coord,
std::string & output
);
void Output(std::ostream & out) const;
};
inline std::ostream & operator<<(std::ostream & out, const FixedPointCoordinate & c){
out << "(" << c.lat << "," << c.lon << ")";
return out;
inline std::ostream& operator<<(std::ostream& o, FixedPointCoordinate const & c){
c.Output(o);
return o;
}
#endif /* FIXED_POINT_COORDINATE_H_ */
+3 -3
View File
@@ -37,8 +37,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace http {
const char okHTML[] = "";
const char badRequestHTML[] = "<html><head><title>Bad Request</title></head><body><h1>400 Bad Request</h1></body></html>";
const char internalServerErrorHTML[] = "<html><head><title>Internal Server Error</title></head><body><h1>500 Internal Server Error</h1></body></html>";
const char 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";
@@ -64,7 +64,7 @@ public:
Reply();
private:
static std::string ToString(Reply::status_type status);
std::string ToString(Reply::status_type status);
boost::asio::const_buffer ToBuffer(Reply::status_type status);
};
+1 -3
View File
@@ -28,8 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OSRM_H
#define OSRM_H
#include <boost/scoped_ptr.hpp>
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <osrm/ServerPaths.h>
@@ -40,7 +38,7 @@ class OSRM {
private:
OSRM_impl * OSRM_pimpl_;
public:
OSRM(
explicit OSRM(
const ServerPaths & paths,
const bool use_shared_memory = false
);
+1 -1
View File
@@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "OSRM.h"
#include "OSRM_impl.h"
#include "OSRM.h"
#include "../Plugins/HelloWorldPlugin.h"
#include "../Plugins/LocatePlugin.h"
+4
View File
@@ -28,10 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef BASEPLUGIN_H_
#define BASEPLUGIN_H_
#include "../Util/StringUtil.h"
#include <osrm/Coordinate.h>
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <boost/foreach.hpp>
#include <string>
#include <vector>
+1 -1
View File
@@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
template<class DataFacadeT>
class LocatePlugin : public BasePlugin {
public:
LocatePlugin(DataFacadeT * facade)
explicit LocatePlugin(DataFacadeT * facade)
:
descriptor_string("locate"),
facade(facade)
+6 -7
View File
@@ -41,7 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
template<class DataFacadeT>
class NearestPlugin : public BasePlugin {
public:
NearestPlugin(DataFacadeT * facade )
explicit NearestPlugin(DataFacadeT * facade )
:
facade(facade),
descriptor_string("nearest")
@@ -50,10 +50,9 @@ public:
descriptorTable.emplace("json", 1);
}
const std::string & GetDescriptor() const { return descriptor_string; }
void HandleRequest(
const RouteParameters & routeParameters,
http::Reply& reply
http::Reply & reply
) {
//check number of parameters
if(!routeParameters.coordinates.size()) {
@@ -82,13 +81,13 @@ public:
reply.status = http::Reply::ok;
reply.content.push_back("{\"status\":");
if(UINT_MAX != result.edgeBasedNode) {
if(UINT_MAX != result.forward_node_id) {
reply.content.push_back("0,");
} else {
reply.content.push_back("207,");
}
reply.content.push_back("\"mapped_coordinate\":[");
if(UINT_MAX != result.edgeBasedNode) {
if(UINT_MAX != result.forward_node_id) {
FixedPointCoordinate::convertInternalLatLonToString(result.location.lat, temp_string);
reply.content.push_back(temp_string);
FixedPointCoordinate::convertInternalLatLonToString(result.location.lon, temp_string);
@@ -96,8 +95,8 @@ public:
reply.content.push_back(temp_string);
}
reply.content.push_back("],\"name\":\"");
if(UINT_MAX != result.edgeBasedNode) {
facade->GetName(result.nodeBasedEdgeNameID, temp_string);
if(UINT_MAX != result.forward_node_id) {
facade->GetName(result.name_id, temp_string);
reply.content.push_back(temp_string);
}
reply.content.push_back("\"}");
+1 -1
View File
@@ -33,7 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
template<class DataFacadeT>
class TimestampPlugin : public BasePlugin {
public:
TimestampPlugin(const DataFacadeT * facade)
explicit TimestampPlugin(const DataFacadeT * facade)
: facade(facade), descriptor_string("timestamp")
{ }
const std::string & GetDescriptor() const { return descriptor_string; }
+55 -67
View File
@@ -39,6 +39,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/unordered_map.hpp>
#include <cstdlib>
@@ -50,24 +52,21 @@ template<class DataFacadeT>
class ViaRoutePlugin : public BasePlugin {
private:
boost::unordered_map<std::string, unsigned> descriptorTable;
SearchEngine<DataFacadeT> * search_engine_ptr;
boost::shared_ptr<SearchEngine<DataFacadeT> > search_engine_ptr;
public:
ViaRoutePlugin(DataFacadeT * facade)
explicit ViaRoutePlugin(DataFacadeT * facade)
:
descriptor_string("viaroute"),
facade(facade)
{
//TODO: set up an engine for each thread!!
search_engine_ptr = new SearchEngine<DataFacadeT>(facade);
search_engine_ptr = boost::make_shared<SearchEngine<DataFacadeT> >(facade);
descriptorTable.emplace("json", 0);
descriptorTable.emplace("gpx" , 1);
}
virtual ~ViaRoutePlugin() {
delete search_engine_ptr;
}
virtual ~ViaRoutePlugin() { }
const std::string & GetDescriptor() const { return descriptor_string; }
@@ -81,115 +80,106 @@ public:
return;
}
RawRouteData rawRoute;
rawRoute.checkSum = facade->GetCheckSum();
const bool checksumOK = (routeParameters.checkSum == rawRoute.checkSum);
RawRouteData raw_route;
raw_route.checkSum = facade->GetCheckSum();
const bool checksumOK = (routeParameters.checkSum == raw_route.checkSum);
std::vector<std::string> textCoord;
for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) {
if( !checkCoord(routeParameters.coordinates[i]) ) {
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
rawRoute.rawViaNodeCoordinates.push_back(routeParameters.coordinates[i]);
raw_route.rawViaNodeCoordinates.push_back(routeParameters.coordinates[i]);
}
std::vector<PhantomNode> phantomNodeVector(rawRoute.rawViaNodeCoordinates.size());
for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) {
std::vector<PhantomNode> phantomNodeVector(raw_route.rawViaNodeCoordinates.size());
for(unsigned i = 0; i < raw_route.rawViaNodeCoordinates.size(); ++i) {
if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) {
// SimpleLogger().Write() <<"Decoding hint: " << routeParameters.hints[i] << " for location index " << i;
DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]);
if(phantomNodeVector[i].isValid(facade->GetNumberOfNodes())) {
// SimpleLogger().Write() << "Decoded hint " << i << " successfully";
continue;
}
}
// SimpleLogger().Write() << "Brute force lookup of coordinate " << i;
facade->FindPhantomNodeForCoordinate(
rawRoute.rawViaNodeCoordinates[i],
raw_route.rawViaNodeCoordinates[i],
phantomNodeVector[i],
routeParameters.zoomLevel
);
}
PhantomNodes segmentPhantomNodes;
for(unsigned i = 0; i < phantomNodeVector.size()-1; ++i) {
segmentPhantomNodes.startPhantom = phantomNodeVector[i];
segmentPhantomNodes.targetPhantom = phantomNodeVector[i+1];
rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes);
PhantomNodes current_phantom_node_pair;
for (unsigned i = 0; i < phantomNodeVector.size()-1; ++i)
{
current_phantom_node_pair.source_phantom = phantomNodeVector[i];
current_phantom_node_pair.target_phantom = phantomNodeVector[i+1];
raw_route.segmentEndCoordinates.push_back(current_phantom_node_pair);
}
if(
( routeParameters.alternateRoute ) &&
(1 == rawRoute.segmentEndCoordinates.size())
) {
search_engine_ptr->alternative_path(
rawRoute.segmentEndCoordinates[0],
rawRoute
);
} else {
search_engine_ptr->shortest_path(
rawRoute.segmentEndCoordinates,
rawRoute
);
if ((routeParameters.alternateRoute) && (1 == raw_route.segmentEndCoordinates.size()))
{
search_engine_ptr->alternative_path(raw_route.segmentEndCoordinates[0], raw_route);
}
else
{
search_engine_ptr->shortest_path(raw_route.segmentEndCoordinates, raw_route);
}
if(INT_MAX == rawRoute.lengthOfShortestPath ) {
SimpleLogger().Write(logDEBUG) <<
"Error occurred, single path not found";
if (INT_MAX == raw_route.lengthOfShortestPath)
{
SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
}
reply.status = http::Reply::ok;
//TODO: Move to member as smart pointer
BaseDescriptor<DataFacadeT> * desc;
if("" != routeParameters.jsonpParameter) {
if (!routeParameters.jsonpParameter.empty())
{
reply.content.push_back(routeParameters.jsonpParameter);
reply.content.push_back("(");
}
DescriptorConfig descriptorConfig;
DescriptorConfig descriptor_config;
unsigned descriptorType = 0;
unsigned descriptor_type = 0;
if(descriptorTable.find(routeParameters.outputFormat) != descriptorTable.end() ) {
descriptorType = descriptorTable.find(routeParameters.outputFormat)->second;
descriptor_type = descriptorTable.find(routeParameters.outputFormat)->second;
}
descriptorConfig.zoom_level = routeParameters.zoomLevel;
descriptorConfig.instructions = routeParameters.printInstructions;
descriptorConfig.geometry = routeParameters.geometry;
descriptorConfig.encode_geometry = routeParameters.compression;
descriptor_config.zoom_level = routeParameters.zoomLevel;
descriptor_config.instructions = routeParameters.printInstructions;
descriptor_config.geometry = routeParameters.geometry;
descriptor_config.encode_geometry = routeParameters.compression;
switch(descriptorType){
boost::shared_ptr<BaseDescriptor<DataFacadeT> > descriptor;
switch(descriptor_type){
case 0:
desc = new JSONDescriptor<DataFacadeT>();
descriptor = boost::make_shared<JSONDescriptor<DataFacadeT> >();
break;
case 1:
desc = new GPXDescriptor<DataFacadeT>();
descriptor = boost::make_shared<GPXDescriptor<DataFacadeT> >();
break;
default:
desc = new JSONDescriptor<DataFacadeT>();
descriptor = boost::make_shared<JSONDescriptor<DataFacadeT> >();
break;
}
PhantomNodes phantomNodes;
phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom;
phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom;
desc->SetConfig(descriptorConfig);
PhantomNodes phantom_nodes;
phantom_nodes.source_phantom = raw_route.segmentEndCoordinates[0].source_phantom;
phantom_nodes.target_phantom = raw_route.segmentEndCoordinates[raw_route.segmentEndCoordinates.size()-1].target_phantom;
descriptor->SetConfig(descriptor_config);
desc->Run(rawRoute, phantomNodes, facade, reply);
if("" != routeParameters.jsonpParameter) {
descriptor->Run(raw_route, phantom_nodes, facade, reply);
if (!routeParameters.jsonpParameter.empty())
{
reply.content.push_back(")\n");
}
reply.headers.resize(3);
reply.headers[0].name = "Content-Length";
std::string tmp;
unsigned content_length = 0;
BOOST_FOREACH(const std::string & snippet, reply.content) {
content_length += snippet.length();
}
intToString(content_length, tmp);
reply.headers[0].value = tmp;
switch(descriptorType){
std::string tmp_string;
intToString(content_length, tmp_string);
reply.headers[0].value = tmp_string;
switch(descriptor_type){
case 0:
if( !routeParameters.jsonpParameter.empty() ){
reply.headers[1].name = "Content-Type";
@@ -225,8 +215,6 @@ public:
}
break;
}
delete desc;
return;
}
private:
File diff suppressed because it is too large Load Diff
+185 -108
View File
@@ -30,14 +30,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngineData.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/ContainerUtils.h"
#include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/noncopyable.hpp>
#include <climits>
#include <stack>
SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap;
@@ -54,7 +54,7 @@ private:
protected:
DataFacadeT * facade;
public:
BasicRoutingInterface( DataFacadeT * facade ) : facade(facade) { }
explicit BasicRoutingInterface( DataFacadeT * facade ) : facade(facade) { }
virtual ~BasicRoutingInterface(){ };
inline void RoutingStep(
@@ -62,57 +62,58 @@ public:
SearchEngineData::QueryHeap & reverse_heap,
NodeID * middle_node_id,
int * upper_bound,
const int edge_expansion_offset,
const bool forward_direction
) const {
) const
{
const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node);
//SimpleLogger().Write() << "Settled (" << forward_heap.GetData( node ).parent << "," << node << ")=" << distance;
if(reverse_heap.WasInserted(node) ){
if (reverse_heap.WasInserted(node))
{
const int new_distance = reverse_heap.GetKey(node) + distance;
if(new_distance < *upper_bound ){
if( new_distance >= 0 ) {
if(new_distance < *upper_bound )
{
if (new_distance >= 0)
{
*middle_node_id = node;
*upper_bound = new_distance;
}
}
}
if( (distance-edge_expansion_offset) > *upper_bound ){
if (distance > *upper_bound)
{
forward_heap.DeleteAll();
return;
}
//Stalling
for(
EdgeID edge = facade->BeginEdges( node );
edge < facade->EndEdges(node);
++edge
) {
for (EdgeID edge = facade->BeginEdges( node ); edge < facade->EndEdges(node); ++edge)
{
const EdgeData & data = facade->GetEdgeData(edge);
const bool reverse_flag = (!forward_direction) ? data.forward : data.backward;
if( reverse_flag ) {
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
if (reverse_flag)
{
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.distance;
BOOST_ASSERT_MSG( edge_weight > 0, "edge_weight invalid" );
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
if(forward_heap.WasInserted( to )) {
if(forward_heap.GetKey( to ) + edge_weight < distance) {
if (forward_heap.WasInserted(to))
{
if(forward_heap.GetKey( to ) + edge_weight < distance)
{
return;
}
}
}
}
for(
EdgeID edge = facade->BeginEdges(node), end_edge = facade->EndEdges(node);
edge < end_edge;
++edge
) {
for (EdgeID edge = facade->BeginEdges(node), end_edge = facade->EndEdges(node); edge < end_edge; ++edge)
{
const EdgeData & data = facade->GetEdgeData(edge);
bool forward_directionFlag = (forward_direction ? data.forward : data.backward );
if( forward_directionFlag ) {
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
if (forward_directionFlag)
{
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.distance;
@@ -126,18 +127,19 @@ public:
}
//Found a shorter Path -> Update distance
else if ( to_distance < forward_heap.GetKey( to ) ) {
//new parent
forward_heap.GetData( to ).parent = node;
forward_heap.DecreaseKey( to, to_distance );
//new parent
}
}
}
}
inline void UnpackPath(
const std::vector<NodeID> & packed_path,
std::vector<PathData> & unpacked_path
) const {
inline void UnpackPath(const std::vector<NodeID> & packed_path, const PhantomNodes & phantom_node_pair, std::vector<PathData> & unpacked_path) const
{
const bool start_traversed_in_reverse = (packed_path.front() != phantom_node_pair.source_phantom.forward_node_id);
const bool target_traversed_in_reverse = (packed_path.back() != phantom_node_pair.target_phantom.forward_node_id);
const unsigned packed_path_size = packed_path.size();
std::stack<std::pair<NodeID, NodeID> > recursion_stack;
@@ -149,87 +151,170 @@ public:
}
std::pair<NodeID, NodeID> edge;
while(!recursion_stack.empty()) {
while (!recursion_stack.empty())
{
edge = recursion_stack.top();
recursion_stack.pop();
// facade->FindEdge does not suffice here in case of shortcuts.
// The above explanation unclear? Think!
EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = INT_MAX;
for(
EdgeID edge_id = facade->BeginEdges(edge.first);
edge_id < facade->EndEdges(edge.first);
++edge_id
){
for (EdgeID edge_id = facade->BeginEdges(edge.first); edge_id < facade->EndEdges(edge.first); ++edge_id)
{
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.second) &&
if ((facade->GetTarget(edge_id) == edge.second) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward
){
facade->GetEdgeData(edge_id).forward)
{
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
if( SPECIAL_EDGEID == smaller_edge_id ){
for(
EdgeID edge_id = facade->BeginEdges(edge.second);
edge_id < facade->EndEdges(edge.second);
++edge_id
){
if (SPECIAL_EDGEID == smaller_edge_id)
{
for (EdgeID edge_id = facade->BeginEdges(edge.second); edge_id < facade->EndEdges(edge.second); ++edge_id)
{
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.first) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).backward
){
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) && facade->GetEdgeData(edge_id).backward)
{
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
}
BOOST_ASSERT_MSG(edge_weight != INT_MAX, "edge id invalid");
BOOST_ASSERT_MSG(edge_weight != INVALID_EDGE_WEIGHT, "edge id invalid");
const EdgeData& ed = facade->GetEdgeData(smaller_edge_id);
if( ed.shortcut ) {//unpack
const EdgeData & ed = facade->GetEdgeData(smaller_edge_id);
if (ed.shortcut)
{//unpack
const NodeID middle_node_id = ed.id;
//again, we need to this in reversed order
recursion_stack.push(std::make_pair(middle_node_id, edge.second));
recursion_stack.push(std::make_pair(edge.first, middle_node_id));
} else {
BOOST_ASSERT_MSG(!ed.shortcut, "edge must be a shortcut");
}
else
{
BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
const TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
if (!facade->EdgeIsCompressed(ed.id))
{
BOOST_ASSERT( !facade->EdgeIsCompressed(ed.id) );
unpacked_path.push_back(
PathData(
facade->GetGeometryIndexForEdgeID(ed.id),
name_index,
turn_instruction,
ed.distance
)
);
}
else
{
std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(facade->GetGeometryIndexForEdgeID(ed.id), id_vector);
const int start_index = ( unpacked_path.empty() ? ( ( start_traversed_in_reverse ) ? id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position - 1 : phantom_node_pair.source_phantom.fwd_segment_position ) : 0 );
const int end_index = id_vector.size();
BOOST_ASSERT(start_index >= 0);
BOOST_ASSERT(start_index <= end_index);
for (int i = start_index; i < end_index; ++i)
{
unpacked_path.push_back(
PathData(
id_vector[i],
name_index,
TurnInstructionsClass::NoTurn,
0
)
);
}
unpacked_path.back().turnInstruction = turn_instruction;
unpacked_path.back().durationOfSegment = ed.distance;
}
}
}
if (SPECIAL_EDGEID != phantom_node_pair.target_phantom.packed_geometry_id)
{
std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(phantom_node_pair.target_phantom.packed_geometry_id, id_vector);
if (target_traversed_in_reverse)
{
std::reverse(id_vector.begin(), id_vector.end() );
}
const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id == phantom_node_pair.target_phantom.packed_geometry_id) && unpacked_path.empty();
int start_index = 0;
int end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
end_index = id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
}
if (is_local_path)
{
start_index = phantom_node_pair.source_phantom.fwd_segment_position;
end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
start_index = id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
end_index = id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
}
}
BOOST_ASSERT(start_index >= 0);
for (int i = start_index; i != end_index; (start_index < end_index ? ++i :--i))
{
BOOST_ASSERT( i >= -1 );
unpacked_path.push_back(
PathData(
ed.id,
facade->GetNameIndexFromEdgeID(ed.id),
facade->GetTurnInstructionForEdgeID(ed.id),
ed.distance
id_vector[i],
phantom_node_pair.target_phantom.name_id,
TurnInstructionsClass::NoTurn,
0
)
);
}
}
// there is no equivalent to a node-based node in an edge-expanded graph.
// two equivalent routes may start (or end) at different node-based edges
// as they are added with the offset how much "distance" on the edge
// has already been traversed. Depending on offset one needs to remove
// the last node.
if (unpacked_path.size() > 1)
{
const unsigned last_index = unpacked_path.size()-1;
const unsigned second_to_last_index = last_index -1;
//looks like a trivially true check but tests for underflow
BOOST_ASSERT(last_index > second_to_last_index);
if (unpacked_path[last_index].node == unpacked_path[second_to_last_index].node)
{
unpacked_path.pop_back();
}
BOOST_ASSERT(!unpacked_path.empty());
}
}
inline void UnpackEdge(
const NodeID s,
const NodeID t,
std::vector<NodeID> & unpacked_path
) const {
inline void UnpackEdge(const NodeID s, const NodeID t, std::vector<NodeID> & unpacked_path) const
{
std::stack<std::pair<NodeID, NodeID> > recursion_stack;
recursion_stack.push(std::make_pair(s,t));
std::pair<NodeID, NodeID> edge;
while(!recursion_stack.empty()) {
while (!recursion_stack.empty())
{
edge = recursion_stack.top();
recursion_stack.pop();
EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = INT_MAX;
for(
EdgeID edge_id = facade->BeginEdges(edge.first);
edge_id < facade->EndEdges(edge.first);
++edge_id
){
for (EdgeID edge_id = facade->BeginEdges(edge.first); edge_id < facade->EndEdges(edge.first); ++edge_id)
{
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.second) &&
@@ -241,18 +326,13 @@ public:
}
}
if( SPECIAL_EDGEID == smaller_edge_id ){
for(
EdgeID edge_id = facade->BeginEdges(edge.second);
edge_id < facade->EndEdges(edge.second);
++edge_id
){
if (SPECIAL_EDGEID == smaller_edge_id)
{
for (EdgeID edge_id = facade->BeginEdges(edge.second); edge_id < facade->EndEdges(edge.second); ++edge_id)
{
const int weight = facade->GetEdgeData(edge_id).distance;
if(
(facade->GetTarget(edge_id) == edge.first) &&
(weight < edge_weight) &&
facade->GetEdgeData(edge_id).backward
){
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) && facade->GetEdgeData(edge_id).backward)
{
smaller_edge_id = edge_id;
edge_weight = weight;
}
@@ -261,16 +341,15 @@ public:
BOOST_ASSERT_MSG(edge_weight != INT_MAX, "edge weight invalid");
const EdgeData& ed = facade->GetEdgeData(smaller_edge_id);
if(ed.shortcut) {//unpack
if (ed.shortcut)
{//unpack
const NodeID middle_node_id = ed.id;
//again, we need to this in reversed order
recursion_stack.push(
std::make_pair(middle_node_id, edge.second)
);
recursion_stack.push(
std::make_pair(edge.first, middle_node_id)
);
} else {
recursion_stack.push(std::make_pair(middle_node_id, edge.second));
recursion_stack.push(std::make_pair(edge.first, middle_node_id));
}
else
{
BOOST_ASSERT_MSG(!ed.shortcut, "edge must be shortcut");
unpacked_path.push_back(edge.first );
}
@@ -279,43 +358,41 @@ public:
}
inline void RetrievePackedPathFromHeap(
SearchEngineData::QueryHeap & forward_heap,
SearchEngineData::QueryHeap & reverse_heap,
const SearchEngineData::QueryHeap & forward_heap,
const SearchEngineData::QueryHeap & reverse_heap,
const NodeID middle_node_id,
std::vector<NodeID> & packed_path
) const {
) const
{
NodeID current_node_id = middle_node_id;
while(current_node_id != forward_heap.GetData(current_node_id).parent) {
while(current_node_id != forward_heap.GetData(current_node_id).parent)
{
current_node_id = forward_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id);
}
std::reverse(packed_path.begin(), packed_path.end());
packed_path.push_back(middle_node_id);
current_node_id = middle_node_id;
while (current_node_id != reverse_heap.GetData(current_node_id).parent){
while (current_node_id != reverse_heap.GetData(current_node_id).parent)
{
current_node_id = reverse_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id);
}
}
//TODO: reorder parameters
inline void RetrievePackedPathFromSingleHeap(
SearchEngineData::QueryHeap & search_heap,
const SearchEngineData::QueryHeap & search_heap,
const NodeID middle_node_id,
std::vector<NodeID>& packed_path
) const {
) const
{
NodeID current_node_id = middle_node_id;
while(current_node_id != search_heap.GetData(current_node_id).parent) {
while(current_node_id != search_heap.GetData(current_node_id).parent)
{
current_node_id = search_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id);
}
}
int ComputeEdgeOffset(const PhantomNode & phantom) const {
return phantom.weight1 + (phantom.isBidirected() ? phantom.weight2 : 0);
}
};
#endif /* BASICROUTINGINTERFACE_H_ */
+98 -60
View File
@@ -48,21 +48,22 @@ public:
) :
super(facade),
engine_working_data(engine_working_data)
{}
{ }
~ShortestPathRouting() {}
~ShortestPathRouting() { }
void operator()(
const std::vector<PhantomNodes> & phantom_nodes_vector,
RawRouteData & raw_route_data
) const {
) const
{
BOOST_FOREACH(
const PhantomNodes & phantom_node_pair,
phantom_nodes_vector
){
if(!phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX()) {
raw_route_data.lengthOfShortestPath = INT_MAX;
raw_route_data.lengthOfAlternativePath = INT_MAX;
if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) {
// raw_route_data.lengthOfShortestPath = INT_MAX;
// raw_route_data.lengthOfAlternativePath = INT_MAX;
return;
}
}
@@ -104,71 +105,84 @@ public:
middle2 = UINT_MAX;
//insert new starting nodes into forward heap, adjusted by previous distances.
if(search_from_1st_node) {
if(
search_from_1st_node &&
phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID
) {
// SimpleLogger().Write(logDEBUG) << "fwd1 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode,
distance1-phantom_node_pair.startPhantom.weight1,
phantom_node_pair.startPhantom.edgeBasedNode
phantom_node_pair.source_phantom.forward_node_id,
distance1-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id
);
forward_heap2.Insert(
phantom_node_pair.startPhantom.edgeBasedNode,
distance1-phantom_node_pair.startPhantom.weight1,
phantom_node_pair.startPhantom.edgeBasedNode
phantom_node_pair.source_phantom.forward_node_id,
distance1-phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id
);
}
if(phantom_node_pair.startPhantom.isBidirected() && search_from_2nd_node) {
if(
search_from_2nd_node &&
phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID
) {
// SimpleLogger().Write(logDEBUG) << "fwd1 insert: " << phantom_node_pair.source_phantom.reverse_node_id << ", w: " << -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
forward_heap1.Insert(
phantom_node_pair.startPhantom.edgeBasedNode+1,
distance2-phantom_node_pair.startPhantom.weight2,
phantom_node_pair.startPhantom.edgeBasedNode+1
phantom_node_pair.source_phantom.reverse_node_id,
distance2-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id
);
forward_heap2.Insert(
phantom_node_pair.startPhantom.edgeBasedNode+1,
distance2-phantom_node_pair.startPhantom.weight2,
phantom_node_pair.startPhantom.edgeBasedNode+1
phantom_node_pair.source_phantom.reverse_node_id,
distance2-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id
);
}
//insert new backward nodes into backward heap, unadjusted.
reverse_heap1.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode,
phantom_node_pair.targetPhantom.weight1,
phantom_node_pair.targetPhantom.edgeBasedNode
);
if(phantom_node_pair.targetPhantom.isBidirected() ) {
reverse_heap2.Insert(
phantom_node_pair.targetPhantom.edgeBasedNode+1,
phantom_node_pair.targetPhantom.weight2,
phantom_node_pair.targetPhantom.edgeBasedNode+1
if( phantom_node_pair.target_phantom.forward_node_id != SPECIAL_NODEID ) {
// SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.target_phantom.forward_node_id << ", w: " << phantom_node_pair.target_phantom.GetForwardWeightPlusOffset();
reverse_heap1.Insert(
phantom_node_pair.target_phantom.forward_node_id,
phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.target_phantom.forward_node_id
);
}
const int forward_offset = super::ComputeEdgeOffset(
phantom_node_pair.startPhantom
);
const int reverse_offset = super::ComputeEdgeOffset(
phantom_node_pair.targetPhantom
);
if( phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID ) {
// SimpleLogger().Write(logDEBUG) << "rev insert: " << phantom_node_pair.target_phantom.reverse_node_id << ", w: " << phantom_node_pair.target_phantom.GetReverseWeightPlusOffset();
reverse_heap2.Insert(
phantom_node_pair.target_phantom.reverse_node_id,
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.target_phantom.reverse_node_id
);
}
// const int forward_offset = phantom_node_pair.ComputeForwardQueueOffset();
// const int forward_offset = super::ComputeForwardOffset(
// phantom_node_pair.source_phantom
// );
// const int reverse_offset = -phantom_node_pair.ComputeReverseQueueOffset();
// const int reverse_offset = super::ComputeReverseOffset(
// phantom_node_pair.target_phantom
// );
//run two-Target Dijkstra routing step.
while(0 < (forward_heap1.Size() + reverse_heap1.Size() )){
if( !forward_heap1.Empty()){
if( 0 < forward_heap1.Size() ){
super::RoutingStep(
forward_heap1,
reverse_heap1,
&middle1,
&local_upper_bound1,
forward_offset,
true
);
}
if( !reverse_heap1.Empty() ){
if( 0 < reverse_heap1.Size() ){
super::RoutingStep(
reverse_heap1,
forward_heap1,
&middle1,
&local_upper_bound1,
reverse_offset,
false
);
}
@@ -176,23 +190,21 @@ public:
if( !reverse_heap2.Empty() ) {
while(0 < (forward_heap2.Size() + reverse_heap2.Size() )){
if( !forward_heap2.Empty() ){
if( 0 < forward_heap2.Size() ){
super::RoutingStep(
forward_heap2,
reverse_heap2,
&middle2,
&local_upper_bound2,
forward_offset,
true
);
}
if( !reverse_heap2.Empty() ){
if( 0 < reverse_heap2.Size() ){
super::RoutingStep(
reverse_heap2,
forward_heap2,
&middle2,
&local_upper_bound2,
reverse_offset,
false
);
}
@@ -201,17 +213,17 @@ public:
//No path found for both target nodes?
if(
(INT_MAX == local_upper_bound1) &&
(INT_MAX == local_upper_bound2)
(INVALID_EDGE_WEIGHT == local_upper_bound1) &&
(INVALID_EDGE_WEIGHT == local_upper_bound2)
) {
raw_route_data.lengthOfShortestPath = INT_MAX;
raw_route_data.lengthOfAlternativePath = INT_MAX;
raw_route_data.lengthOfShortestPath = INVALID_EDGE_WEIGHT;
raw_route_data.lengthOfAlternativePath = INVALID_EDGE_WEIGHT;
return;
}
if(UINT_MAX == middle1) {
if( SPECIAL_NODEID == middle1 ) {
search_from_1st_node = false;
}
if(UINT_MAX == middle2) {
if( SPECIAL_NODEID == middle2 ) {
search_from_2nd_node = false;
}
@@ -228,7 +240,7 @@ public:
BOOST_ASSERT( (unsigned)current_leg < packed_legs1.size() );
BOOST_ASSERT( (unsigned)current_leg < packed_legs2.size() );
if(INT_MAX != local_upper_bound1) {
if( INVALID_EDGE_WEIGHT != local_upper_bound1 ) {
super::RetrievePackedPathFromHeap(
forward_heap1,
reverse_heap1,
@@ -237,7 +249,7 @@ public:
);
}
if(INT_MAX != local_upper_bound2) {
if( INVALID_EDGE_WEIGHT != local_upper_bound2 ) {
super::RetrievePackedPathFromHeap(
forward_heap2,
reverse_heap2,
@@ -264,8 +276,6 @@ public:
local_upper_bound2 = local_upper_bound1;
}
// SimpleLogger().Write() << "fetched packed paths";
BOOST_ASSERT_MSG(
!temporary_packed_leg1.empty() ||
!temporary_packed_leg2.empty(),
@@ -335,11 +345,11 @@ public:
if(
(packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
phantom_node_pair.targetPhantom.isBidirected()
phantom_node_pair.target_phantom.isBidirected()
) {
const NodeID last_node_id = packed_legs2[current_leg].back();
search_from_1st_node &= !(last_node_id == phantom_node_pair.targetPhantom.edgeBasedNode+1);
search_from_2nd_node &= !(last_node_id == phantom_node_pair.targetPhantom.edgeBasedNode);
search_from_1st_node &= !(last_node_id == phantom_node_pair.target_phantom.reverse_node_id);
search_from_2nd_node &= !(last_node_id == phantom_node_pair.target_phantom.forward_node_id);
BOOST_ASSERT( search_from_1st_node != search_from_2nd_node );
}
@@ -348,14 +358,42 @@ public:
++current_leg;
}
if( distance1 > distance2 ) {
if (distance1 > distance2)
{
std::swap( packed_legs1, packed_legs2 );
}
raw_route_data.unpacked_path_segments.resize( packed_legs1.size() );
for(unsigned i = 0; i < packed_legs1.size(); ++i){
BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size() );
// const int start_offset = ( packed_legs1[0].front() == phantom_nodes_vector.front().source_phantom.forward_node_id ? 1 : -1 )*phantom_nodes_vector.front().source_phantom.fwd_segment_position;
raw_route_data.source_traversed_in_reverse = (packed_legs1.front().front() != phantom_nodes_vector.front().source_phantom.forward_node_id);
raw_route_data.target_traversed_in_reverse = (packed_legs1.back().back() != phantom_nodes_vector.back().target_phantom.forward_node_id);
for (unsigned i = 0; i < packed_legs1.size(); ++i)
{
BOOST_ASSERT(!phantom_nodes_vector.empty());
// const bool at_beginning = (packed_legs1[i] == packed_legs1.front());
// const bool at_end = (packed_legs1[i] == packed_legs1.back());
BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size());
PhantomNodes unpack_phantom_node_pair = phantom_nodes_vector[i];
// if (!at_beginning)
// {
// unpack_phantom_node_pair.source_phantom.packed_geometry_id = SPECIAL_EDGEID;
// unpack_phantom_node_pair.source_phantom.fwd_segment_position = 0;
// }
// if (!at_end)
// {
// unpack_phantom_node_pair.target_phantom.packed_geometry_id = SPECIAL_EDGEID;
// unpack_phantom_node_pair.target_phantom.fwd_segment_position = 0;
// }
super::UnpackPath(
// -- packed input
packed_legs1[i],
// -- start and end of (sub-)route
unpack_phantom_node_pair,
// -- unpacked output
raw_route_data.unpacked_path_segments[i]
);
}
+1 -1
View File
@@ -36,7 +36,7 @@ namespace qi = boost::spirit::qi;
template <typename Iterator, class HandlerT>
struct APIGrammar : qi::grammar<Iterator> {
APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h) {
explicit APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h) {
api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query);
query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | cmp | language | instruction | geometry | alt_route | old_API) ) ;
+9
View File
@@ -86,6 +86,15 @@ public:
const unsigned id
) const = 0;
virtual bool EdgeIsCompressed( const unsigned id ) const = 0;
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const = 0;
virtual void GetUncompressedGeometry(
const unsigned id,
std::vector<unsigned> & result_nodes
) const = 0;
virtual TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id
) const = 0;
+113 -25
View File
@@ -45,6 +45,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <osrm/Coordinate.h>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
template<class EdgeDataT>
class InternalDataFacade : public BaseDataFacade<EdgeDataT> {
@@ -61,14 +64,23 @@ private:
QueryGraph * m_query_graph;
std::string m_timestamp;
ShM<FixedPointCoordinate, false>::vector m_coordinate_list;
boost::shared_ptr<ShM<FixedPointCoordinate, false>::vector> m_coordinate_list;
ShM<NodeID, false>::vector m_via_node_list;
ShM<unsigned, false>::vector m_name_ID_list;
ShM<TurnInstruction, false>::vector m_turn_instruction_list;
ShM<char, false>::vector m_names_char_list;
ShM<unsigned, false>::vector m_name_begin_indices;
ShM<bool, false>::vector m_egde_is_compressed;
ShM<unsigned, false>::vector m_geometry_indices;
ShM<unsigned, false>::vector m_geometry_list;
StaticRTree<RTreeLeaf, false> * m_static_rtree;
boost::shared_ptr<
StaticRTree<
RTreeLeaf,
ShM<FixedPointCoordinate, false>::vector,
false
>
> m_static_rtree;
void LoadTimestamp(const boost::filesystem::path & timestamp_path) {
@@ -103,7 +115,7 @@ private:
);
BOOST_ASSERT_MSG(0 != node_list.size(), "node list empty");
BOOST_ASSERT_MSG(0 != edge_list.size(), "edge list empty");
// BOOST_ASSERT_MSG(0 != edge_list.size(), "edge list empty");
SimpleLogger().Write() << "loaded " << node_list.size() << " nodes and " << edge_list.size() << " edges";
m_query_graph = new QueryGraph(node_list, edge_list);
@@ -113,42 +125,44 @@ private:
}
void LoadNodeAndEdgeInformation(
const boost::filesystem::path nodes_file,
const boost::filesystem::path edges_file
const boost::filesystem::path & nodes_file,
const boost::filesystem::path & edges_file
) {
boost::filesystem::ifstream nodes_input_stream(
nodes_file,
std::ios::binary
);
SimpleLogger().Write(logDEBUG) << "Loading node data";
NodeInfo current_node;
unsigned number_of_coordinates = 0;
nodes_input_stream.read(
(char *)&number_of_coordinates,
sizeof(unsigned)
);
m_coordinate_list.resize(number_of_coordinates);
m_coordinate_list = boost::make_shared<std::vector<FixedPointCoordinate> >(number_of_coordinates);
for(unsigned i = 0; i < number_of_coordinates; ++i) {
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
m_coordinate_list[i] = FixedPointCoordinate(
m_coordinate_list->at(i) = FixedPointCoordinate(
current_node.lat,
current_node.lon
);
BOOST_ASSERT( ( std::abs(m_coordinate_list->at(i).lat) >> 30) == 0 );
BOOST_ASSERT( ( std::abs(m_coordinate_list->at(i).lon) >> 30) == 0 );
}
std::vector<FixedPointCoordinate>(m_coordinate_list).swap(m_coordinate_list);
nodes_input_stream.close();
SimpleLogger().Write(logDEBUG) << "Loading edge data";
boost::filesystem::ifstream edges_input_stream(
edges_file,
std::ios::binary
);
unsigned number_of_edges = 0;
edges_input_stream.read((char*)&number_of_edges, sizeof(unsigned));
m_via_node_list.resize(number_of_edges);
m_name_ID_list.resize(number_of_edges);
m_via_node_list.resize (number_of_edges);
m_name_ID_list.resize (number_of_edges);
m_turn_instruction_list.resize(number_of_edges);
m_egde_is_compressed.resize (number_of_edges);
unsigned compressed = 0;
OriginalEdgeData current_edge_data;
for(unsigned i = 0; i < number_of_edges; ++i) {
@@ -159,17 +173,63 @@ private:
m_via_node_list[i] = current_edge_data.via_node;
m_name_ID_list[i] = current_edge_data.name_id;
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
m_egde_is_compressed[i] = current_edge_data.compressed_geometry;
if(m_egde_is_compressed[i]) {
++compressed;
}
}
edges_input_stream.close();
}
void LoadGeometries(const boost::filesystem::path & geometry_file)
{
std::ifstream geometry_stream(
geometry_file.c_str(),
std::ios::binary
);
unsigned number_of_indices = 0;
unsigned number_of_compressed_geometries = 0;
geometry_stream.read(
(char *)&number_of_indices,
sizeof(unsigned)
);
m_geometry_indices.resize(number_of_indices);
geometry_stream.read(
(char *)&(m_geometry_indices[0]),
number_of_indices*sizeof(unsigned)
);
geometry_stream.read(
(char *)&number_of_compressed_geometries,
sizeof(unsigned)
);
BOOST_ASSERT( m_geometry_indices.back() == number_of_compressed_geometries );
m_geometry_list.resize( number_of_compressed_geometries );
geometry_stream.read(
(char *)&(m_geometry_list[0]),
number_of_compressed_geometries*sizeof(unsigned)
);
geometry_stream.close();
}
void LoadRTree(
const boost::filesystem::path & ram_index_path,
const boost::filesystem::path & file_index_path
) {
m_static_rtree = new StaticRTree<RTreeLeaf>(
BOOST_ASSERT_MSG(
!m_coordinate_list->empty(),
"coordinates must be loaded before r-tree"
);
m_static_rtree = boost::make_shared<StaticRTree<RTreeLeaf> >(
ram_index_path,
file_index_path
file_index_path,
m_coordinate_list
);
}
@@ -204,10 +264,10 @@ private:
public:
~InternalDataFacade() {
delete m_query_graph;
delete m_static_rtree;
m_static_rtree.reset();
}
InternalDataFacade( const ServerPaths & server_paths ) {
explicit InternalDataFacade( const ServerPaths & server_paths ) {
//generate paths of data files
if( server_paths.find("hsgrdata") == server_paths.end() ) {
throw OSRMException("no hsgr file given in ini file");
@@ -218,6 +278,9 @@ public:
if( server_paths.find("fileindex") == server_paths.end() ) {
throw OSRMException("no leaf index file given in ini file");
}
if( server_paths.find("geometries") == server_paths.end() ) {
throw OSRMException("no geometries file given in ini file");
}
if( server_paths.find("nodesdata") == server_paths.end() ) {
throw OSRMException("no nodes file given in ini file");
}
@@ -249,12 +312,17 @@ public:
paths_iterator = server_paths.find("namesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & names_data_path = paths_iterator->second;
paths_iterator = server_paths.find("geometries");
BOOST_ASSERT(server_paths.end() != paths_iterator);
const boost::filesystem::path & geometries_path = paths_iterator->second;
//load data
SimpleLogger().Write() << "loading graph data";
LoadGraph(hsgr_path);
SimpleLogger().Write() << "loading egde information";
LoadNodeAndEdgeInformation(nodes_data_path, edges_data_path);
SimpleLogger().Write() << "loading geometries";
LoadGeometries( geometries_path );
SimpleLogger().Write() << "loading r-tree";
LoadRTree(ram_index_path, file_index_path);
SimpleLogger().Write() << "loading timestamp";
@@ -319,10 +387,13 @@ public:
FixedPointCoordinate GetCoordinateOfNode(
const unsigned id
) const {
const NodeID node = m_via_node_list.at(id);
return m_coordinate_list.at(node);
return m_coordinate_list->at(id);
};
bool EdgeIsCompressed( const unsigned id ) const {
return m_egde_is_compressed.at(id);
}
TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id
) const {
@@ -346,11 +417,12 @@ public:
PhantomNode & resulting_phantom_node,
const unsigned zoom_level
) const {
return m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
);
const bool found = m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
);
return found;
}
unsigned GetCheckSum() const { return m_check_sum; }
@@ -368,8 +440,8 @@ public:
name_id < m_name_begin_indices.size(),
"name id too high"
);
unsigned begin_index = m_name_begin_indices[name_id];
unsigned end_index = m_name_begin_indices[name_id+1];
const unsigned begin_index = m_name_begin_indices[name_id];
const unsigned end_index = m_name_begin_indices[name_id+1];
BOOST_ASSERT_MSG(
begin_index < m_names_char_list.size(),
"begin index of name too high"
@@ -389,6 +461,22 @@ public:
);
}
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const {
return m_via_node_list.at(id);
}
virtual void GetUncompressedGeometry(
const unsigned id, std::vector<unsigned> & result_nodes
) const {
const unsigned begin = m_geometry_indices.at(id);
const unsigned end = m_geometry_indices.at(id+1);
result_nodes.clear();
result_nodes.insert(result_nodes.begin(),
m_geometry_list.begin() + begin,
m_geometry_list.begin() + end);
}
std::string GetTimestamp() const {
return m_timestamp;
}
+85 -21
View File
@@ -30,9 +30,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//implements all data storage when shared memory _IS_ used
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include "BaseDataFacade.h"
#include "SharedDataType.h"
@@ -42,6 +39,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../../Util/ProgramOptions.h"
#include "../../Util/SimpleLogger.h"
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <algorithm>
template<class EdgeDataT>
@@ -55,7 +55,7 @@ private:
typedef typename StaticGraph<EdgeData, true>::_StrEdge GraphEdge;
typedef typename QueryGraph::InputEdge InputEdge;
typedef typename super::RTreeLeaf RTreeLeaf;
typedef typename StaticRTree<RTreeLeaf, true>::TreeNode RTreeNode;
typedef typename StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>::TreeNode RTreeNode;
SharedDataLayout * data_layout;
char * shared_memory;
@@ -72,15 +72,25 @@ private:
boost::shared_ptr<SharedMemory> m_large_memory;
std::string m_timestamp;
ShM<FixedPointCoordinate, true>::vector m_coordinate_list;
boost::shared_ptr<
ShM<FixedPointCoordinate, true>::vector
> m_coordinate_list;
ShM<NodeID, true>::vector m_via_node_list;
ShM<unsigned, true>::vector m_name_ID_list;
ShM<TurnInstruction, true>::vector m_turn_instruction_list;
ShM<char, true>::vector m_names_char_list;
ShM<unsigned, true>::vector m_name_begin_indices;
boost::shared_ptr<StaticRTree<RTreeLeaf, true> > m_static_rtree;
ShM<bool, true>::vector m_egde_is_compressed;
ShM<unsigned, true>::vector m_geometry_indices;
ShM<unsigned, true>::vector m_geometry_list;
// SharedDataFacade() { }
boost::shared_ptr<
StaticRTree<
RTreeLeaf,
ShM<FixedPointCoordinate, true>::vector,
true
>
> m_static_rtree;
void LoadTimestamp() {
char * timestamp_ptr = shared_memory + data_layout->GetTimeStampOffset();
@@ -95,13 +105,19 @@ private:
void LoadRTree(
const boost::filesystem::path & file_index_path
) {
BOOST_ASSERT_MSG(
!m_coordinate_list->empty(),
"coordinates must be loaded before r-tree"
);
RTreeNode * tree_ptr = (RTreeNode *)(
shared_memory + data_layout->GetRSearchTreeOffset()
);
m_static_rtree = boost::make_shared<StaticRTree<RTreeLeaf, true> >(
m_static_rtree = boost::make_shared<StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true> >(
tree_ptr,
data_layout->r_search_tree_size,
file_index_path
file_index_path,
m_coordinate_list
);
}
@@ -112,7 +128,7 @@ private:
);
GraphEdge * graph_edges_ptr = (GraphEdge *)(
shared_memory + data_layout->GetGraphEdgeListOffsett()
shared_memory + data_layout->GetGraphEdgeListOffset()
);
typename ShM<GraphNode, true>::vector node_list(
@@ -126,7 +142,6 @@ private:
m_query_graph.reset(
new QueryGraph(node_list, edge_list)
);
}
void LoadNodeAndEdgeInformation() {
@@ -134,11 +149,10 @@ private:
FixedPointCoordinate * coordinate_list_ptr = (FixedPointCoordinate *)(
shared_memory + data_layout->GetCoordinateListOffset()
);
typename ShM<FixedPointCoordinate, true>::vector coordinate_list(
m_coordinate_list = boost::make_shared<ShM<FixedPointCoordinate, true>::vector> (
coordinate_list_ptr,
data_layout->coordinate_list_size
);
m_coordinate_list.swap( coordinate_list );
TurnInstruction * turn_instruction_list_ptr = (TurnInstruction *)(
shared_memory + data_layout->GetTurnInstructionListOffset()
@@ -190,6 +204,36 @@ private:
m_names_char_list.swap(names_char_list);
}
void LoadGeometries()
{
unsigned * geometries_compressed_ptr = (unsigned *)(
shared_memory + data_layout->GetGeometriesIndicatorOffset()
);
typename ShM<bool, true>::vector egde_is_compressed(
geometries_compressed_ptr,
data_layout->geometries_indicators
);
m_egde_is_compressed.swap(egde_is_compressed);
unsigned * geometries_index_ptr = (unsigned *)(
shared_memory + data_layout->GetGeometriesIndexListOffset()
);
typename ShM<unsigned, true>::vector geometry_begin_indices(
geometries_index_ptr,
data_layout->geometries_index_list_size
);
m_geometry_indices.swap(geometry_begin_indices);
unsigned * geometries_list_ptr = (unsigned *)(
shared_memory + data_layout->GetGeometryListOffset()
);
typename ShM<unsigned, true>::vector geometry_list(
geometries_list_ptr,
data_layout->geometries_list_size
);
m_geometry_list.swap(geometry_list);
}
public:
SharedDataFacade( ) {
data_timestamp_ptr = (SharedDataTimestamp *)SharedMemoryFactory::Get(
@@ -241,6 +285,7 @@ public:
LoadGraph();
LoadNodeAndEdgeInformation();
LoadGeometries();
LoadRTree(ram_index_path);
LoadTimestamp();
LoadViaNodeList();
@@ -250,7 +295,6 @@ public:
}
}
//search graph access
unsigned GetNumberOfNodes() const {
return m_query_graph->GetNumberOfNodes();
@@ -307,10 +351,29 @@ public:
FixedPointCoordinate GetCoordinateOfNode(
const unsigned id
) const {
const NodeID node = m_via_node_list.at(id);
return m_coordinate_list.at(node);
return m_coordinate_list->at(id);
};
virtual bool EdgeIsCompressed( const unsigned id ) const {
return m_egde_is_compressed.at(id);
}
virtual void GetUncompressedGeometry(
const unsigned id, std::vector<unsigned> & result_nodes
) const {
const unsigned begin = m_geometry_indices.at(id);
const unsigned end = m_geometry_indices.at(id+1);
result_nodes.clear();
result_nodes.insert(result_nodes.begin(),
m_geometry_list.begin() + begin,
m_geometry_list.begin() + end);
}
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const {
return m_via_node_list.at(id);
}
TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id
) const {
@@ -334,11 +397,12 @@ public:
PhantomNode & resulting_phantom_node,
const unsigned zoom_level
) const {
return m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
);
const bool found = m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
);
return found;
}
unsigned GetCheckSum() const { return m_check_sum; }
+97 -34
View File
@@ -43,7 +43,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/integer.hpp>
typedef BaseDataFacade<QueryEdge::EdgeData>::RTreeLeaf RTreeLeaf;
typedef StaticRTree<RTreeLeaf, true>::TreeNode RTreeNode;
typedef StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>::TreeNode RTreeNode;
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
struct SharedDataLayout {
@@ -56,6 +56,9 @@ struct SharedDataLayout {
uint64_t coordinate_list_size;
uint64_t turn_instruction_list_size;
uint64_t r_search_tree_size;
uint64_t geometries_index_list_size;
uint64_t geometries_list_size;
uint64_t geometries_indicators;
unsigned checksum;
unsigned timestamp_length;
@@ -72,8 +75,12 @@ struct SharedDataLayout {
coordinate_list_size(0),
turn_instruction_list_size(0),
r_search_tree_size(0),
geometries_index_list_size(0),
geometries_list_size(0),
geometries_indicators(0),
checksum(0),
timestamp_length(0)
{
ram_index_file_name[0] = '\0';
}
@@ -90,23 +97,29 @@ struct SharedDataLayout {
SimpleLogger().Write(logDEBUG) << "coordinate_list_size: " << coordinate_list_size;
SimpleLogger().Write(logDEBUG) << "turn_instruction_list_size: " << turn_instruction_list_size;
SimpleLogger().Write(logDEBUG) << "r_search_tree_size: " << r_search_tree_size;
SimpleLogger().Write(logDEBUG) << "geometries_indicators: " << geometries_indicators << "/" << ((geometries_indicators/8) + 1);
SimpleLogger().Write(logDEBUG) << "geometries_index_list_size: " << geometries_index_list_size;
SimpleLogger().Write(logDEBUG) << "geometries_list_size: " << geometries_list_size;
SimpleLogger().Write(logDEBUG) << "sizeof(checksum): " << sizeof(checksum);
SimpleLogger().Write(logDEBUG) << "ram index file name: " << ram_index_file_name;
}
uint64_t GetSizeOfLayout() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge)) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructions) ) +
(r_search_tree_size * sizeof(RTreeNode) ) +
sizeof(checksum) +
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode) ) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge) ) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate) ) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode) ) +
(geometries_indicators/32 + 1) * sizeof(unsigned) +
(geometries_index_list_size * sizeof(unsigned) ) +
(geometries_list_size * sizeof(unsigned) ) +
sizeof(checksum) +
1024*sizeof(char);
return result;
}
@@ -140,10 +153,10 @@ struct SharedDataLayout {
(via_node_list_size * sizeof(NodeID) );
return result;
}
uint64_t GetGraphEdgeListOffsett() const {
uint64_t GetGraphEdgeListOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) ;
@@ -184,29 +197,79 @@ struct SharedDataLayout {
}
uint64_t GetRSearchTreeOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge)) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructions) );
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode) ) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge) ) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate) ) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass));
return result;
}
uint64_t GetGeometriesIndicatorOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode) ) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge) ) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate) ) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode) );
return result;
}
uint64_t GetGeometriesIndexListOffset() const
{ uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode) ) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge) ) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate) ) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode) ) +
(geometries_indicators/32 + 1) * sizeof(unsigned);
return result;
}
uint64_t GetGeometryListOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode) ) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge) ) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate) ) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode) ) +
(geometries_indicators/32 + 1) * sizeof(unsigned) +
(geometries_index_list_size * sizeof(unsigned) );
return result;
}
uint64_t GetChecksumOffset() const {
uint64_t result =
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode)) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge)) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate)) +
(turn_instruction_list_size * sizeof(TurnInstructions) ) +
(r_search_tree_size * sizeof(RTreeNode) );
(name_index_list_size * sizeof(unsigned) ) +
(name_char_list_size * sizeof(char) ) +
(name_id_list_size * sizeof(unsigned) ) +
(via_node_list_size * sizeof(NodeID) ) +
(graph_node_list_size * sizeof(QueryGraph::_StrNode) ) +
(graph_edge_list_size * sizeof(QueryGraph::_StrEdge) ) +
(timestamp_length * sizeof(char) ) +
(coordinate_list_size * sizeof(FixedPointCoordinate) ) +
(turn_instruction_list_size * sizeof(TurnInstructionsClass)) +
(r_search_tree_size * sizeof(RTreeNode) ) +
(geometries_indicators/32 + 1) * sizeof(unsigned) +
(geometries_index_list_size * sizeof(unsigned) ) +
(geometries_list_size * sizeof(unsigned) );
return result;
}
};
+7 -8
View File
@@ -36,7 +36,6 @@ namespace http {
void Reply::setSize(const unsigned size) {
BOOST_FOREACH ( Header& h, headers) {
if("Content-Length" == h.name) {
std::string sizeString;
intToString(size,h.value);
}
}
@@ -74,10 +73,10 @@ std::vector<boost::asio::const_buffer> Reply::HeaderstoBuffers(){
std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(ToBuffer(status));
for (std::size_t i = 0; i < headers.size(); ++i) {
Header& h = headers[i];
buffers.push_back(boost::asio::buffer(h.name));
Header& current_header = headers[i];
buffers.push_back(boost::asio::buffer(current_header.name));
buffers.push_back(boost::asio::buffer(seperators));
buffers.push_back(boost::asio::buffer(h.value));
buffers.push_back(boost::asio::buffer(current_header.value));
buffers.push_back(boost::asio::buffer(crlf));
}
buffers.push_back(boost::asio::buffer(crlf));
@@ -88,16 +87,16 @@ Reply Reply::StockReply(Reply::status_type status) {
Reply rep;
rep.status = status;
rep.content.clear();
rep.content.push_back( ToString(status) );
rep.content.push_back(rep.ToString(status));
rep.headers.resize(3);
rep.headers[0].name = "Access-Control-Allow-Origin";
rep.headers[0].value = "*";
rep.headers[1].name = "Content-Length";
std::string s;
intToString(rep.content.size(), s);
std::string size_string;
intToString(rep.content.size(), size_string);
rep.headers[1].value = s;
rep.headers[1].value = size_string;
rep.headers[2].name = "Content-Type";
rep.headers[2].value = "text/html";
return rep;
+7 -11
View File
@@ -27,12 +27,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "APIGrammar.h"
#include "RequestHandler.h"
#include "Http/Request.h"
#include "../Library/OSRM.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <boost/foreach.hpp>
@@ -76,21 +78,15 @@ void RequestHandler::handle_request(const http::Request& req, http::Reply& rep){
if ( !result || (it != request.end()) ) {
rep = http::Reply::StockReply(http::Reply::badRequest);
rep.content.clear();
const int position = std::distance(request.begin(), it);
rep.content.push_back(
"{\"status\":400,\"status_message\":\"Query string malformed close to position "
);
std::string tmp_position_string;
intToString(position, tmp_position_string);
rep.content.push_back(
"Input seems to be malformed close to position "
"<br><pre>"
);
rep.content.push_back( request );
rep.content.push_back(tmp_position_string);
rep.content.push_back("<br>");
const unsigned end = std::distance(request.begin(), it);
for(unsigned i = 0; i < end; ++i) {
rep.content.push_back("&nbsp;");
}
rep.content.push_back("^<br></pre>");
rep.content.push_back("\"}");
} else {
//parsing done, lets call the right plugin to handle the request
BOOST_ASSERT_MSG(
+5 -4
View File
@@ -28,10 +28,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef REQUEST_HANDLER_H
#define REQUEST_HANDLER_H
#include "Http/Request.h"
#include <osrm/Reply.h>
#include <boost/noncopyable.hpp>
#include <string>
@@ -41,6 +37,11 @@ struct APIGrammar;
struct RouteParameters;
class OSRM;
namespace http {
class Reply;
struct Request;
}
class RequestHandler : private boost::noncopyable {
public:
+142 -112
View File
@@ -38,11 +38,13 @@ boost::tuple<boost::tribool, char*> RequestParser::Parse(
Request& req,
char* begin,
char* end,
http::CompressionType * compressionType
) {
while (begin != end) {
http::CompressionType * compressionType)
{
while (begin != end)
{
boost::tribool result = consume(req, *begin++, compressionType);
if (result || !result){
if (result || !result)
{
return boost::make_tuple(result, begin);
}
}
@@ -50,193 +52,216 @@ boost::tuple<boost::tribool, char*> RequestParser::Parse(
return boost::make_tuple(result, begin);
}
boost::tribool RequestParser::consume(
Request& req, char input,
http::CompressionType * compressionType
) {
switch (state_) {
boost::tribool RequestParser::consume(Request& req, char input, http::CompressionType * compressionType)
{
switch (state_)
{
case method_start:
if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
} else {
state_ = method;
return boost::indeterminate;
}
state_ = method;
return boost::indeterminate;
case method:
if (input == ' ') {
if (input == ' ')
{
state_ = uri;
return boost::indeterminate;
} else if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
return boost::indeterminate;
}
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
return boost::indeterminate;
case uri_start:
if (isCTL(input)) {
if (isCTL(input))
{
return false;
} else {
state_ = uri;
req.uri.push_back(input);
return boost::indeterminate;
}
state_ = uri;
req.uri.push_back(input);
return boost::indeterminate;
case uri:
if (input == ' ') {
if (input == ' ')
{
state_ = http_version_h;
return boost::indeterminate;
} else if (isCTL(input)) {
return false;
} else {
req.uri.push_back(input);
return boost::indeterminate;
}
if (isCTL(input))
{
return false;
}
req.uri.push_back(input);
return boost::indeterminate;
case http_version_h:
if (input == 'H') {
if (input == 'H')
{
state_ = http_version_t_1;
return boost::indeterminate;
} else {
return false;
}
return false;
case http_version_t_1:
if (input == 'T') {
if (input == 'T')
{
state_ = http_version_t_2;
return boost::indeterminate;
} else {
return false;
}
return false;
case http_version_t_2:
if (input == 'T') {
if (input == 'T')
{
state_ = http_version_p;
return boost::indeterminate;
} else {
return false;
}
return false;
case http_version_p:
if (input == 'P') {
if (input == 'P')
{
state_ = http_version_slash;
return boost::indeterminate;
} else {
return false;
}
return false;
case http_version_slash:
if (input == '/') {
if (input == '/')
{
state_ = http_version_major_start;
return boost::indeterminate;
} else {
return false;
}
return false;
case http_version_major_start:
if (isDigit(input)) {
if (isDigit(input))
{
state_ = http_version_major;
return boost::indeterminate;
} else {
return false;
}
return false;
case http_version_major:
if (input == '.') {
if (input == '.')
{
state_ = http_version_minor_start;
return boost::indeterminate;
} else if (isDigit(input)) {
return boost::indeterminate;
} else {
return false;
}
if (isDigit(input))
{
return boost::indeterminate;
}
return false;
case http_version_minor_start:
if (isDigit(input)) {
if (isDigit(input))
{
state_ = http_version_minor;
return boost::indeterminate;
} else {
return false;
}
return false;
case http_version_minor:
if (input == '\r') {
if (input == '\r')
{
state_ = expecting_newline_1;
return boost::indeterminate;
} else if (isDigit(input)) {
}
if (isDigit(input))
{
return boost::indeterminate;
}
else {
return false;
}
return false;
case expecting_newline_1:
if (input == '\n') {
if (input == '\n')
{
state_ = header_line_start;
return boost::indeterminate;
} else {
return false;
}
return false;
case header_line_start:
if(header.name == "Accept-Encoding") {
if(header.name == "Accept-Encoding")
{
/* giving gzip precedence over deflate */
if(header.value.find("deflate") != std::string::npos)
if (header.value.find("deflate") != std::string::npos)
{
*compressionType = deflateRFC1951;
if(header.value.find("gzip") != std::string::npos)
}
if (header.value.find("gzip") != std::string::npos)
{
*compressionType = gzipRFC1952;
}
}
if("Referer" == header.name)
if ("Referer" == header.name)
{
req.referrer = header.value;
}
if("User-Agent" == header.name)
if ("User-Agent" == header.name)
{
req.agent = header.value;
}
if (input == '\r') {
if (input == '\r')
{
state_ = expecting_newline_3;
return boost::indeterminate;
} else if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
state_ = header_name;
header.Clear();
header.name.push_back(input);
return boost::indeterminate;
}
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
state_ = header_name;
header.Clear();
header.name.push_back(input);
return boost::indeterminate;
case header_lws:
if (input == '\r') {
if (input == '\r')
{
state_ = expecting_newline_2;
return boost::indeterminate;
} else if (input == ' ' || input == '\t') {
}
if (input == ' ' || input == '\t')
{
return boost::indeterminate;
}
else if (isCTL(input)) {
if (isCTL(input)) {
return false;
} else {
state_ = header_value;
return boost::indeterminate;
}
state_ = header_value;
return boost::indeterminate;
case header_name:
if (input == ':') {
if (input == ':')
{
state_ = space_before_header_value;
return boost::indeterminate;
} else if (!isChar(input) || isCTL(input) || isTSpecial(input)) {
return false;
} else {
header.name.push_back(input);
return boost::indeterminate;
}
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
header.name.push_back(input);
return boost::indeterminate;
case space_before_header_value:
if (input == ' ') {
if (input == ' ')
{
state_ = header_value;
return boost::indeterminate;
} else {
return false;
}
return false;
case header_value:
if (input == '\r') {
if (input == '\r')
{
state_ = expecting_newline_2;
return boost::indeterminate;
} else if (isCTL(input)) {
return false;
} else {
header.value.push_back(input);
return boost::indeterminate;
}
if (isCTL(input))
{
return false;
}
header.value.push_back(input);
return boost::indeterminate;
case expecting_newline_2:
if (input == '\n') {
if (input == '\n')
{
state_ = header_line_start;
return boost::indeterminate;
} else {
return false;
}
return false;
case expecting_newline_3:
return (input == '\n');
default:
@@ -244,27 +269,32 @@ boost::tribool RequestParser::consume(
}
}
inline bool RequestParser::isChar(int c) {
inline bool RequestParser::isChar(int c)
{
return c >= 0 && c <= 127;
}
inline bool RequestParser::isCTL(int c) {
inline bool RequestParser::isCTL(int c)
{
return (c >= 0 && c <= 31) || (c == 127);
}
inline bool RequestParser::isTSpecial(int c) {
switch (c) {
case '(': case ')': case '<': case '>': case '@':
case ',': case ';': case ':': case '\\': case '"':
case '/': case '[': case ']': case '?': case '=':
case '{': case '}': case ' ': case '\t':
return true;
default:
return false;
inline bool RequestParser::isTSpecial(int c)
{
switch (c)
{
case '(': case ')': case '<': case '>': case '@':
case ',': case ';': case ':': case '\\': case '"':
case '/': case '[': case ']': case '?': case '=':
case '{': case '}': case ' ': case '\t':
return true;
default:
return false;
}
}
inline bool RequestParser::isDigit(int c) {
inline bool RequestParser::isDigit(int c)
{
return c >= '0' && c <= '9';
}
+2 -1
View File
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/make_shared.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
@@ -72,7 +73,7 @@ public:
void Run() {
std::vector<boost::shared_ptr<boost::thread> > threads;
for (unsigned i = 0; i < threadPoolSize; ++i) {
boost::shared_ptr<boost::thread> thread(new boost::thread(boost::bind(&boost::asio::io_service::run, &ioService)));
boost::shared_ptr<boost::thread> thread = boost::make_shared<boost::thread>(boost::bind(&boost::asio::io_service::run, &ioService));
threads.push_back(thread);
}
for (unsigned i = 0; i < threads.size(); ++i)
+76 -84
View File
@@ -46,99 +46,91 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
typedef QueryEdge::EdgeData EdgeData;
typedef QueryEdge::EdgeData EdgeData;
typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
std::vector<NodeInfo> internal_to_external_node_map;
std::vector<TurnRestriction> restrictions_vector;
std::vector<NodeID> bollard_node_IDs_vector;
std::vector<NodeID> traffic_light_node_IDs_vector;
std::vector<NodeInfo> internal_to_external_node_map;
std::vector<TurnRestriction> restrictions_vector;
std::vector<NodeID> bollard_node_IDs_vector;
std::vector<NodeID> traffic_light_node_IDs_vector;
int main (int argc, char * argv[]) {
int main(int argc, char *argv[])
{
LogPolicy::GetInstance().Unmute();
if(argc < 3) {
SimpleLogger().Write(logWARNING) <<
"usage:\n" << argv[0] << " <osrm> <osrm.restrictions>";
if (argc < 3)
{
SimpleLogger().Write(logWARNING) << "usage:\n" << argv[0] << " <osrm> <osrm.restrictions>";
return -1;
}
SimpleLogger().Write() <<
"Using restrictions from file: " << argv[2];
std::ifstream restriction_ifstream(argv[2], std::ios::binary);
const UUID uuid_orig;
UUID uuid_loaded;
restriction_ifstream.read((char *) &uuid_loaded, sizeof(UUID));
try
{
SimpleLogger().Write() << "Using restrictions from file: " << argv[2];
std::ifstream restriction_ifstream(argv[2], std::ios::binary);
const UUID uuid_orig;
UUID uuid_loaded;
restriction_ifstream.read((char *)&uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
SimpleLogger().Write(logWARNING) <<
argv[2] << " was prepared with a different build. "
"Reprocess to get rid of this warning.";
if (!uuid_loaded.TestGraphUtil(uuid_orig))
{
SimpleLogger().Write(logWARNING) << argv[2] << " was prepared with a different build. "
"Reprocess to get rid of this warning.";
}
if (!restriction_ifstream.good())
{
throw OSRMException("Could not access <osrm-restrictions> files");
}
uint32_t usable_restriction_count = 0;
restriction_ifstream.read((char *)&usable_restriction_count, sizeof(uint32_t));
restrictions_vector.resize(usable_restriction_count);
restriction_ifstream.read((char *)&(restrictions_vector[0]),
usable_restriction_count * sizeof(TurnRestriction));
restriction_ifstream.close();
std::ifstream input_stream;
input_stream.open(argv[1], std::ifstream::in | std::ifstream::binary);
if (!input_stream.is_open())
{
throw OSRMException("Cannot open osrm file");
}
std::vector<ImportEdge> edge_list;
NodeID node_based_node_count = readBinaryOSRMGraphFromStream(
input_stream, edge_list, bollard_node_IDs_vector, traffic_light_node_IDs_vector,
&internal_to_external_node_map, restrictions_vector);
input_stream.close();
BOOST_ASSERT_MSG(restrictions_vector.size() == usable_restriction_count,
"size of restrictions_vector changed");
SimpleLogger().Write() << restrictions_vector.size() << " restrictions, "
<< bollard_node_IDs_vector.size() << " bollard nodes, "
<< traffic_light_node_IDs_vector.size() << " traffic lights";
/***
* Building an edge-expanded graph from node-based input an turn
* restrictions
*/
SimpleLogger().Write() << "Starting SCC graph traversal";
TarjanSCC *tarjan = new TarjanSCC(node_based_node_count, edge_list, bollard_node_IDs_vector,
traffic_light_node_IDs_vector, restrictions_vector,
internal_to_external_node_map);
std::vector<ImportEdge>().swap(edge_list);
tarjan->Run();
std::vector<TurnRestriction>().swap(restrictions_vector);
std::vector<NodeID>().swap(bollard_node_IDs_vector);
std::vector<NodeID>().swap(traffic_light_node_IDs_vector);
SimpleLogger().Write() << "finished component analysis";
}
if(!restriction_ifstream.good()) {
throw OSRMException("Could not access <osrm-restrictions> files");
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
}
uint32_t usable_restriction_count = 0;
restriction_ifstream.read(
(char*)&usable_restriction_count,
sizeof(uint32_t)
);
restrictions_vector.resize(usable_restriction_count);
restriction_ifstream.read(
(char *)&(restrictions_vector[0]),
usable_restriction_count*sizeof(TurnRestriction)
);
restriction_ifstream.close();
std::ifstream input_stream;
input_stream.open( argv[1], std::ifstream::in | std::ifstream::binary );
if (!input_stream.is_open()) {
throw OSRMException("Cannot open osrm file");
}
std::vector<ImportEdge> edge_list;
NodeID node_based_node_count = readBinaryOSRMGraphFromStream(
input_stream,
edge_list,
bollard_node_IDs_vector,
traffic_light_node_IDs_vector,
&internal_to_external_node_map,
restrictions_vector
);
input_stream.close();
BOOST_ASSERT_MSG(
restrictions_vector.size() == usable_restriction_count,
"size of restrictions_vector changed"
);
SimpleLogger().Write() <<
restrictions_vector.size() << " restrictions, " <<
bollard_node_IDs_vector.size() << " bollard nodes, " <<
traffic_light_node_IDs_vector.size() << " traffic lights";
/***
* Building an edge-expanded graph from node-based input an turn restrictions
*/
SimpleLogger().Write() << "Starting SCC graph traversal";
TarjanSCC * tarjan = new TarjanSCC (
node_based_node_count,
edge_list,
bollard_node_IDs_vector,
traffic_light_node_IDs_vector,
restrictions_vector,
internal_to_external_node_map
);
std::vector<ImportEdge>().swap(edge_list);
tarjan->Run();
std::vector<TurnRestriction>().swap(restrictions_vector);
std::vector<NodeID>().swap(bollard_node_IDs_vector);
std::vector<NodeID>().swap(traffic_light_node_IDs_vector);
SimpleLogger().Write() << "finished component analysis";
return 0;
}
+142 -163
View File
@@ -48,45 +48,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
const unsigned number_of_elements = 268435456;
struct Statistics { double min, max, med, mean, dev; };
struct Statistics
{
double min, max, med, mean, dev;
};
void RunStatistics(std::vector<double> & timings_vector, Statistics & stats) {
void RunStatistics(std::vector<double> &timings_vector, Statistics &stats)
{
std::sort(timings_vector.begin(), timings_vector.end());
stats.min = timings_vector.front();
stats.max = timings_vector.back();
stats.med = timings_vector[timings_vector.size()/2];
double primary_sum = std::accumulate(
timings_vector.begin(),
timings_vector.end(),
0.0
);
stats.med = timings_vector[timings_vector.size() / 2];
double primary_sum = std::accumulate(timings_vector.begin(), timings_vector.end(), 0.0);
stats.mean = primary_sum / timings_vector.size();
double primary_sq_sum = std::inner_product( timings_vector.begin(),
timings_vector.end(),
timings_vector.begin(),
0.0
);
stats.dev = std::sqrt(
primary_sq_sum / timings_vector.size() - (stats.mean * stats.mean)
);
double primary_sq_sum = std::inner_product(
timings_vector.begin(), timings_vector.end(), timings_vector.begin(), 0.0);
stats.dev = std::sqrt(primary_sq_sum / timings_vector.size() - (stats.mean * stats.mean));
}
int main (int argc, char * argv[]) {
int main(int argc, char *argv[])
{
LogPolicy::GetInstance().Unmute();
SimpleLogger().Write() <<
"starting up engines, " << g_GIT_DESCRIPTION << ", " <<
"compiled at " << __DATE__ << ", " __TIME__;
SimpleLogger().Write() << "starting up engines, " << g_GIT_DESCRIPTION << ", "
<< "compiled at " << __DATE__ << ", " __TIME__;
#ifdef __FreeBSD__
SimpleLogger().Write() << "Not supported on FreeBSD";
return 0;
SimpleLogger().Write() << "Not supported on FreeBSD";
return 0;
#endif
if( 1 == argc ) {
SimpleLogger().Write(logWARNING) <<
"usage: " << argv[0] << " /path/on/device";
if (1 == argc)
{
SimpleLogger().Write(logWARNING) << "usage: " << argv[0] << " /path/on/device";
return -1;
}
@@ -94,119 +89,105 @@ int main (int argc, char * argv[]) {
test_path /= "osrm.tst";
SimpleLogger().Write(logDEBUG) << "temporary file: " << test_path.string();
try {
//create files for testing
if( 2 == argc) {
//create file to test
if( boost::filesystem::exists(test_path) ) {
try
{
// create files for testing
if (2 == argc)
{
// create file to test
if (boost::filesystem::exists(test_path))
{
throw OSRMException("Data file already exists");
}
double time1, time2;
int * random_array = new int[number_of_elements];
std::generate (
random_array,
random_array+number_of_elements,
std::rand
);
int *random_array = new int[number_of_elements];
std::generate(random_array, random_array + number_of_elements, std::rand);
#ifdef __APPLE__
FILE * fd = fopen(test_path.string().c_str(), "w");
FILE *fd = fopen(test_path.string().c_str(), "w");
fcntl(fileno(fd), F_NOCACHE, 1);
fcntl(fileno(fd), F_RDAHEAD, 0);
time1 = get_timestamp();
write(
fileno(fd),
(char*)random_array,
number_of_elements*sizeof(unsigned)
);
write(fileno(fd), (char *)random_array, number_of_elements * sizeof(unsigned));
time2 = get_timestamp();
fclose(fd);
#endif
#ifdef __linux__
int f = open(
test_path.string().c_str(),
O_CREAT|O_TRUNC|O_WRONLY|O_SYNC,
S_IRWXU
);
int f =
open(test_path.string().c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_SYNC, S_IRWXU);
time1 = get_timestamp();
int ret = write(
f,
random_array,
number_of_elements*sizeof(unsigned)
);
if(-1 == ret) {
int ret = write(f, random_array, number_of_elements * sizeof(unsigned));
if (-1 == ret)
{
throw OSRMException("could not write random data file");
}
time2 = get_timestamp();
close(f);
#endif
delete[] random_array;
SimpleLogger().Write(logDEBUG) <<
"writing raw 1GB took " << (time2-time1)*1000 << "ms";
SimpleLogger().Write() << "raw write performance: " <<
std::setprecision(5) << std::fixed <<
1024*1024/((time2-time1)*1000) << "MB/sec";
SimpleLogger().Write(logDEBUG) << "writing raw 1GB took " << (time2 - time1) * 1000
<< "ms";
SimpleLogger().Write() << "raw write performance: " << std::setprecision(5)
<< std::fixed << 1024 * 1024 / ((time2 - time1) * 1000)
<< "MB/sec";
SimpleLogger().Write(logDEBUG) <<
"finished creation of random data. Flush disk cache now!";
} else {
SimpleLogger().Write(logDEBUG)
<< "finished creation of random data. Flush disk cache now!";
}
else
{
//
// Run Non-Cached I/O benchmarks
//
if( !boost::filesystem::exists(test_path) ) {
if (!boost::filesystem::exists(test_path))
{
throw OSRMException("data file does not exist");
}
double time1, time2;
//volatiles do not get optimized
// volatiles do not get optimized
Statistics stats;
#ifdef __APPLE__
volatile unsigned single_block[1024];
char * raw_array = new char[number_of_elements*sizeof(unsigned)];
FILE * fd = fopen(test_path.string().c_str(), "r");
char *raw_array = new char[number_of_elements * sizeof(unsigned)];
FILE *fd = fopen(test_path.string().c_str(), "r");
fcntl(fileno(fd), F_NOCACHE, 1);
fcntl(fileno(fd), F_RDAHEAD, 0);
#endif
#ifdef __linux__
char * single_block = (char*) memalign(
512,
1024*sizeof(unsigned)
);
char *single_block = (char *)memalign(512, 1024 * sizeof(unsigned));
int f = open(test_path.string().c_str(), O_RDONLY|O_DIRECT|O_SYNC);
SimpleLogger().Write(logDEBUG) <<
"opened, error: " << strerror(errno);
char * raw_array = (char*) memalign(
512,
number_of_elements*sizeof(unsigned)
);
int f = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
if (-1 == f)
{
SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
return -1;
}
char *raw_array = (char *)memalign(512, number_of_elements * sizeof(unsigned));
#endif
time1 = get_timestamp();
#ifdef __APPLE__
read(fileno(fd), raw_array, number_of_elements*sizeof(unsigned));
read(fileno(fd), raw_array, number_of_elements * sizeof(unsigned));
close(fileno(fd));
fd = fopen(test_path.string().c_str(), "r");
#endif
#ifdef __linux__
int ret = read(f, raw_array, number_of_elements*sizeof(unsigned));
SimpleLogger().Write(logDEBUG) <<
"read " << ret << " bytes, error: " << strerror(errno);
int ret = read(f, raw_array, number_of_elements * sizeof(unsigned));
SimpleLogger().Write(logDEBUG) << "read " << ret
<< " bytes, error: " << strerror(errno);
close(f);
f = open(test_path.string().c_str(), O_RDONLY|O_DIRECT|O_SYNC);
SimpleLogger().Write(logDEBUG) <<
"opened, error: " << strerror(errno);
f = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
#endif
time2 = get_timestamp();
SimpleLogger().Write(logDEBUG) <<
"reading raw 1GB took " << (time2-time1)*1000 << "ms";
SimpleLogger().Write() << "raw read performance: " <<
std::setprecision(5) << std::fixed <<
1024*1024/((time2-time1)*1000) << "MB/sec";
SimpleLogger().Write(logDEBUG) << "reading raw 1GB took " << (time2 - time1) * 1000
<< "ms";
SimpleLogger().Write() << "raw read performance: " << std::setprecision(5) << std::fixed
<< 1024 * 1024 / ((time2 - time1) * 1000) << "MB/sec";
std::vector<double> timing_results_raw_random;
SimpleLogger().Write(logDEBUG) << "running 1000 random I/Os of 4KB";
@@ -217,60 +198,59 @@ int main (int argc, char * argv[]) {
#ifdef __linux__
lseek(f, 0, SEEK_SET);
#endif
//make 1000 random access, time each I/O seperately
unsigned number_of_blocks = (number_of_elements*sizeof(unsigned)-1)/4096;
for(unsigned i = 0; i < 1000; ++i) {
unsigned block_to_read = std::rand()%number_of_blocks;
off_t current_offset = block_to_read*4096;
// make 1000 random access, time each I/O seperately
unsigned number_of_blocks = (number_of_elements * sizeof(unsigned) - 1) / 4096;
for (unsigned i = 0; i < 1000; ++i)
{
unsigned block_to_read = std::rand() % number_of_blocks;
off_t current_offset = block_to_read * 4096;
time1 = get_timestamp();
#ifdef __APPLE__
int ret1 = fseek(fd, current_offset, SEEK_SET);
int ret2 = read(fileno(fd), (char*)&single_block[0], 4096);
int ret2 = read(fileno(fd), (char *)&single_block[0], 4096);
#endif
#ifdef __FreeBSD__
int ret1 = 0;
int ret2 = 0;
int ret1 = 0;
int ret2 = 0;
#endif
#ifdef __linux__
int ret1 = lseek(f, current_offset, SEEK_SET);
int ret2 = read(f, (char*)single_block, 4096);
int ret2 = read(f, (char *)single_block, 4096);
#endif
time2 = get_timestamp();
if( ((off_t)-1) == ret1) {
SimpleLogger().Write(logWARNING)
<< "offset: " << current_offset;
SimpleLogger().Write(logWARNING)
<< "seek error " << strerror(errno);
if (((off_t) - 1) == ret1)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
SimpleLogger().Write(logWARNING) << "seek error " << strerror(errno);
throw OSRMException("seek error");
}
if(-1 == ret2) {
SimpleLogger().Write(logWARNING)
<< "offset: " << current_offset;
SimpleLogger().Write(logWARNING)
<< "read error " << strerror(errno);
if (-1 == ret2)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
throw OSRMException("read error");
}
timing_results_raw_random.push_back((time2-time1)*1000.);
timing_results_raw_random.push_back((time2 - time1) * 1000.);
}
// Do statistics
SimpleLogger().Write(logDEBUG) << "running raw random I/O statistics";
std::ofstream random_csv("random.csv", std::ios::trunc);
for(unsigned i = 0; i < timing_results_raw_random.size(); ++i) {
for (unsigned i = 0; i < timing_results_raw_random.size(); ++i)
{
random_csv << i << ", " << timing_results_raw_random[i] << std::endl;
}
random_csv.close();
RunStatistics(timing_results_raw_random, stats);
SimpleLogger().Write() << "raw random I/O: " <<
std::setprecision(5) << std::fixed <<
"min: " << stats.min << "ms, " <<
"mean: " << stats.mean << "ms, " <<
"med: " << stats.med << "ms, " <<
"max: " << stats.max << "ms, " <<
"dev: " << stats.dev << "ms";
SimpleLogger().Write() << "raw random I/O: " << std::setprecision(5) << std::fixed
<< "min: " << stats.min << "ms, "
<< "mean: " << stats.mean << "ms, "
<< "med: " << stats.med << "ms, "
<< "max: " << stats.max << "ms, "
<< "dev: " << stats.dev << "ms";
std::vector<double> timing_results_raw_seq;
#ifdef __APPLE__
@@ -280,81 +260,80 @@ int main (int argc, char * argv[]) {
lseek(f, 0, SEEK_SET);
#endif
//read every 100th block
for(
unsigned i = 0;
i < 1000;
++i
) {
off_t current_offset = i*4096;
// read every 100th block
for (unsigned i = 0; i < 1000; ++i)
{
off_t current_offset = i * 4096;
time1 = get_timestamp();
#ifdef __APPLE__
#ifdef __APPLE__
int ret1 = fseek(fd, current_offset, SEEK_SET);
int ret2 = read(fileno(fd), (char*)&single_block, 4096);
#endif
int ret2 = read(fileno(fd), (char *)&single_block, 4096);
#endif
#ifdef __FreeBSD__
int ret1 = 0;
int ret2 = 0;
#endif
#ifdef __FreeBSD__
int ret1 = 0;
int ret2 = 0;
#endif
#ifdef __linux__
#ifdef __linux__
int ret1 = lseek(f, current_offset, SEEK_SET);
int ret2 = read(f, (char*)single_block, 4096);
#endif
int ret2 = read(f, (char *)single_block, 4096);
#endif
time2 = get_timestamp();
if( ((off_t)-1) == ret1) {
SimpleLogger().Write(logWARNING)
<< "offset: " << current_offset;
SimpleLogger().Write(logWARNING)
<< "seek error " << strerror(errno);
if (((off_t) - 1) == ret1)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
SimpleLogger().Write(logWARNING) << "seek error " << strerror(errno);
throw OSRMException("seek error");
}
if(-1 == ret2) {
SimpleLogger().Write(logWARNING)
<< "offset: " << current_offset;
SimpleLogger().Write(logWARNING)
<< "read error " << strerror(errno);
if (-1 == ret2)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
throw OSRMException("read error");
}
timing_results_raw_seq.push_back((time2-time1)*1000.);
timing_results_raw_seq.push_back((time2 - time1) * 1000.);
}
#ifdef __APPLE__
#ifdef __APPLE__
fclose(fd);
// free(single_element);
free(raw_array);
// free(single_block);
#endif
#ifdef __linux__
// free(single_block);
#endif
#ifdef __linux__
close(f);
#endif
//Do statistics
#endif
// Do statistics
SimpleLogger().Write(logDEBUG) << "running sequential I/O statistics";
//print simple statistics: min, max, median, variance
// print simple statistics: min, max, median, variance
std::ofstream seq_csv("sequential.csv", std::ios::trunc);
for(unsigned i = 0; i < timing_results_raw_seq.size(); ++i) {
for (unsigned i = 0; i < timing_results_raw_seq.size(); ++i)
{
seq_csv << i << ", " << timing_results_raw_seq[i] << std::endl;
}
seq_csv.close();
RunStatistics(timing_results_raw_seq, stats);
SimpleLogger().Write() << "raw sequential I/O: " <<
std::setprecision(5) << std::fixed <<
"min: " << stats.min << "ms, " <<
"mean: " << stats.mean << "ms, " <<
"med: " << stats.med << "ms, " <<
"max: " << stats.max << "ms, " <<
"dev: " << stats.dev << "ms";
SimpleLogger().Write() << "raw sequential I/O: " << std::setprecision(5) << std::fixed
<< "min: " << stats.min << "ms, "
<< "mean: " << stats.mean << "ms, "
<< "med: " << stats.med << "ms, "
<< "max: " << stats.max << "ms, "
<< "dev: " << stats.dev << "ms";
if( boost::filesystem::exists(test_path) ) {
if (boost::filesystem::exists(test_path))
{
boost::filesystem::remove(test_path);
SimpleLogger().Write(logDEBUG) << "removing temporary files";
}
}
} catch ( const std::exception & e ) {
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
SimpleLogger().Write(logWARNING) << "cleaning up, and exiting";
if(boost::filesystem::exists(test_path)) {
if (boost::filesystem::exists(test_path))
{
boost::filesystem::remove(test_path);
SimpleLogger().Write(logWARNING) << "removing temporary files";
}
+15 -8
View File
@@ -33,13 +33,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
int main() {
LogPolicy::GetInstance().Unmute();
SimpleLogger().Write() <<
"starting up engines, " << g_GIT_DESCRIPTION << ", " <<
"compiled at " << __DATE__ << ", " __TIME__;
SimpleLogger().Write() << "Releasing all locks";
SharedBarriers barrier;
barrier.pending_update_mutex.unlock();
barrier.query_mutex.unlock();
barrier.update_mutex.unlock();
try
{
SimpleLogger().Write() <<
"starting up engines, " << g_GIT_DESCRIPTION << ", " <<
"compiled at " << __DATE__ << ", " __TIME__;
SimpleLogger().Write() << "Releasing all locks";
SharedBarriers barrier;
barrier.pending_update_mutex.unlock();
barrier.query_mutex.unlock();
barrier.update_mutex.unlock();
}
catch(const std::exception & e)
{
SimpleLogger().Write(logWARNING) << "[excpetion] " << e.what();
}
return 0;
}
+20 -20
View File
@@ -105,11 +105,11 @@ inline bool GenerateDataStoreOptions(const int argc, const char * argv[], Server
boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
".edges file"
)
// (
// "geometry",
// boost::program_options::value<boost::filesystem::path>(&paths["geometries"]),
// ".geometry file"
// )
(
"geometry",
boost::program_options::value<boost::filesystem::path>(&paths["geometry"]),
".geometry file"
)
(
"ramindex",
boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
@@ -180,13 +180,13 @@ inline bool GenerateDataStoreOptions(const int argc, const char * argv[], Server
boost::program_options::notify(option_variables);
const bool parameter_present =
(paths.find("hsgrdata") != paths.end() && !paths.find("hsgrdata")->second.string().empty() ) ||
(paths.find("hsgrdata") != paths.end() && !paths.find("hsgrdata" )->second.string().empty()) ||
(paths.find("nodesdata") != paths.end() && !paths.find("nodesdata")->second.string().empty()) ||
(paths.find("edgesdata") != paths.end() && !paths.find("edgesdata")->second.string().empty()) ||
// (paths.find("geometry") != paths.end() && !paths.find("geometry")->second.string().empty())) ||
(paths.find("ramindex") != paths.end() && !paths.find("ramindex")->second.string().empty()) ||
(paths.find("geometry") != paths.end() && !paths.find("geometry" )->second.string().empty()) ||
(paths.find("ramindex") != paths.end() && !paths.find("ramindex" )->second.string().empty()) ||
(paths.find("fileindex") != paths.end() && !paths.find("fileindex")->second.string().empty()) ||
(paths.find("timestamp") != paths.end() && !paths.find("timestamp")->second.string().empty()) ;
(paths.find("timestamp") != paths.end() && !paths.find("timestamp")->second.string().empty());
if (parameter_present)
{
@@ -244,11 +244,11 @@ inline bool GenerateDataStoreOptions(const int argc, const char * argv[], Server
path_iterator->second = base_string + ".edges";
}
// path_iterator = paths.find("geometries");
// if (path_iterator != paths.end())
// {
// path_iterator->second = base_string + ".geometry";
// }
path_iterator = paths.find("geometry");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".geometry";
}
path_iterator = paths.find("ramindex");
if (path_iterator != paths.end())
@@ -296,12 +296,12 @@ inline bool GenerateDataStoreOptions(const int argc, const char * argv[], Server
}
AssertPathExists(path_iterator->second);
// path_iterator = paths.find("geometries");
// if (path_iterator == paths.end() || path_iterator->second.string().empty())
// {
// path_iterator->second = base_string + ".geometry";
// }
// AssertPathExists(path_iterator->second);
path_iterator = paths.find("geometry");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
{
throw OSRMException(".geometry file must be specified");
}
AssertPathExists(path_iterator->second);
path_iterator = paths.find("ramindex");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
+9 -3
View File
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/unordered_map.hpp>
@@ -135,7 +136,7 @@ NodeID readBinaryOSRMGraphFromStream(
short type;
NodeID nameID;
int length;
bool isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow;
bool isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow, is_split;
for (EdgeID i=0; i<m; ++i) {
input_stream.read((char*)&source, sizeof(unsigned));
@@ -149,6 +150,7 @@ NodeID readBinaryOSRMGraphFromStream(
input_stream.read((char*)&ignoreInGrid, sizeof(bool));
input_stream.read((char*)&isAccessRestricted, sizeof(bool));
input_stream.read((char*)&isContraFlow, sizeof(bool));
input_stream.read((char*)&is_split, sizeof(bool));
BOOST_ASSERT_MSG(length > 0, "loaded null length edge" );
BOOST_ASSERT_MSG(weight > 0, "loaded null weight");
@@ -189,7 +191,7 @@ NodeID readBinaryOSRMGraphFromStream(
std::swap(forward, backward);
}
EdgeT inputEdge(source, target, nameID, weight, forward, backward, type, isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow );
EdgeT inputEdge(source, target, nameID, weight, forward, backward, type, isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow, is_split );
edge_list.push_back(inputEdge);
}
std::sort(edge_list.begin(), edge_list.end());
@@ -444,7 +446,10 @@ unsigned readHSGRFromStream(
hsgr_input_stream.read( (char*) &number_of_nodes, sizeof(unsigned) );
BOOST_ASSERT_MSG( 0 != number_of_nodes, "number of nodes is zero");
hsgr_input_stream.read( (char*) &number_of_edges, sizeof(unsigned) );
BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero");
SimpleLogger().Write() << "number_of_nodes: " << number_of_nodes << ", number_of_edges: " << number_of_edges;
// BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero");
node_list.resize(number_of_nodes + 1);
hsgr_input_stream.read(
(char*) &(node_list[0]),
@@ -457,6 +462,7 @@ unsigned readHSGRFromStream(
number_of_edges*sizeof(EdgeT)
);
hsgr_input_stream.close();
return number_of_nodes;
}
+1 -1
View File
@@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class IniFile {
public:
IniFile(const char * config_filename);
explicit IniFile(const char * config_filename);
std::string GetParameter(const std::string & key);
+2 -2
View File
@@ -33,8 +33,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class OSRMException: public std::exception {
public:
OSRMException(const char * message) : message(message) {}
OSRMException(const std::string & message) : message(message) {}
explicit OSRMException(const char * message) : message(message) {}
explicit OSRMException(const std::string & message) : message(message) {}
virtual ~OSRMException() throw() {}
private:
virtual const char* what() const throw() {
+15
View File
@@ -110,6 +110,10 @@ inline unsigned GenerateServerProgramOptions(
"edgesdata",
boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
".edges file")
(
"geometry",
boost::program_options::value<boost::filesystem::path>(&paths["geometries"]),
".geometry file")
(
"ramindex",
boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
@@ -252,6 +256,17 @@ inline unsigned GenerateServerProgramOptions(
}
path_iterator = paths.find("geometries");
if(
path_iterator != paths.end() &&
!boost::filesystem::is_regular_file(path_iterator->second)
) {
path_iterator->second = base_string + ".geometry";
} else {
throw OSRMException(base_string + ".geometry not found");
}
path_iterator = paths.find("ramindex");
if(
path_iterator != paths.end() &&
+21 -11
View File
@@ -32,11 +32,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/noncopyable.hpp>
#include <boost/thread/mutex.hpp>
#include <cstdio>
#include <ostream>
#include <iostream>
enum LogLevel { logINFO, logWARNING, logDEBUG };
static boost::mutex logger_mutex;
static boost::mutex logger_mutex;
const char COL_RESET[] = "\x1b[0m";
const char RED[] = "\x1b[31m";
const char GREEN[] = "\x1b[32m";
@@ -70,16 +72,20 @@ private:
bool m_is_mute;
};
class SimpleLogger {
class SimpleLogger
{
public:
SimpleLogger() : level(logINFO) { }
std::ostringstream& Write(LogLevel l = logINFO) {
try {
std::ostringstream& Write(LogLevel l = logINFO)
{
try
{
boost::mutex::scoped_lock lock(logger_mutex);
level = l;
os << "[";
switch(level) {
switch(level)
{
case logINFO:
os << "info";
break;
@@ -96,22 +102,26 @@ public:
break;
}
os << "] ";
} catch (...) { }
}
catch (...) { }
return os;
}
virtual ~SimpleLogger() {
if(!LogPolicy::GetInstance().IsMute()) {
switch(level) {
if(!LogPolicy::GetInstance().IsMute())
{
const bool is_terminal = isatty(fileno(stdout));
switch(level)
{
case logINFO:
std::cout << os.str() << COL_RESET << std::endl;
std::cout << os.str() << (is_terminal ? COL_RESET : "") << std::endl;
break;
case logWARNING:
std::cerr << RED << os.str() << COL_RESET << std::endl;
std::cerr << (is_terminal ? RED : "") << os.str() << (is_terminal ? COL_RESET : "") << std::endl;
break;
case logDEBUG:
#ifndef NDEBUG
std::cout << YELLOW << os.str() << COL_RESET << std::endl;
std::cout << (is_terminal ? YELLOW : "") << os.str() << (is_terminal ? COL_RESET : "") << std::endl;
#endif
break;
default:
+34
View File
@@ -126,6 +126,40 @@ static inline uint64_t stringToInt64(const std::string& input) {
return value;
}
// source: http://tinodidriksen.com/2011/05/28/cpp-convert-string-to-double-speed/
static inline double StringToDouble(const char *p)
{
double r = 0.0;
bool neg = false;
if (*p == '-')
{
neg = true;
++p;
}
while (*p >= '0' && *p <= '9')
{
r = (r*10.0) + (*p - '0');
++p;
}
if (*p == '.')
{
double f = 0.0;
int n = 0;
++p;
while (*p >= '0' && *p <= '9')
{
f = (f*10.0) + (*p - '0');
++p;
++n;
}
r += f / std::pow(10.0, n);
}
if (neg)
{
r = -r;
}
return r;
}
static inline void doubleToString(const double value, std::string & output){
output.clear();
+86 -25
View File
@@ -44,22 +44,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/mman.h>
#endif
#include <boost/integer.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/integer.hpp>
#include <boost/iostreams/seek.hpp>
#include <fstream>
#include <string>
#include <vector>
int main( const int argc, const char * argv[] ) {
int main( const int argc, const char * argv[] )
{
LogPolicy::GetInstance().Unmute();
SharedBarriers barrier;
#ifdef __linux__
if( -1 == mlockall(MCL_CURRENT | MCL_FUTURE) ) {
SimpleLogger().Write(logWARNING) <<
"Process " << argv[0] << " could not request RAM lock";
}
const bool lock_flags = MCL_CURRENT | MCL_FUTURE;
if (-1 == mlockall(lock_flags))
{
SimpleLogger().Write(logWARNING) << "Process " << argv[0] << " could not request RAM lock";
}
#endif
try {
@@ -89,22 +92,25 @@ int main( const int argc, const char * argv[] ) {
return 0;
}
if( server_paths.find("hsgrdata") == server_paths.end() ) {
throw OSRMException("no hsgr file given in ini file");
throw OSRMException("no hsgr file found");
}
if( server_paths.find("ramindex") == server_paths.end() ) {
throw OSRMException("no ram index file given in ini file");
throw OSRMException("no ram index file found");
}
if( server_paths.find("fileindex") == server_paths.end() ) {
throw OSRMException("no leaf index file given in ini file");
throw OSRMException("no leaf index file found");
}
if( server_paths.find("nodesdata") == server_paths.end() ) {
throw OSRMException("no nodes file given in ini file");
throw OSRMException("no nodes file found");
}
if( server_paths.find("edgesdata") == server_paths.end() ) {
throw OSRMException("no edges file given in ini file");
throw OSRMException("no edges file found");
}
if( server_paths.find("namesdata") == server_paths.end() ) {
throw OSRMException("no names file given in ini file");
throw OSRMException("no names file found");
}
if( server_paths.find("geometry") == server_paths.end() ) {
throw OSRMException("no geometry file found");
}
ServerPaths::const_iterator paths_iterator = server_paths.find("hsgrdata");
@@ -136,7 +142,10 @@ int main( const int argc, const char * argv[] ) {
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path & names_data_path = paths_iterator->second;
paths_iterator = server_paths.find("geometry");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path & geometries_data_path = paths_iterator->second;
// get the shared memory segment to use
bool use_first_segment = SharedMemory::RegionExists( LAYOUT_2 );
@@ -163,7 +172,6 @@ int main( const int argc, const char * argv[] ) {
shared_layout_ptr->ram_index_file_name[end_of_string_index] = '\0';
// collect number of elements to store in shared memory object
SimpleLogger().Write(logDEBUG) << "Collecting files sizes";
SimpleLogger().Write() << "load names from: " << names_data_path;
// number of entries in name index
boost::filesystem::ifstream name_stream(
@@ -192,6 +200,7 @@ int main( const int argc, const char * argv[] ) {
shared_layout_ptr->via_node_list_size = number_of_original_edges;
shared_layout_ptr->name_id_list_size = number_of_original_edges;
shared_layout_ptr->turn_instruction_list_size = number_of_original_edges;
shared_layout_ptr->geometries_indicators = number_of_original_edges;
boost::filesystem::ifstream hsgr_input_stream(
hsgr_path,
@@ -200,13 +209,15 @@ int main( const int argc, const char * argv[] ) {
UUID uuid_loaded, uuid_orig;
hsgr_input_stream.read((char *)&uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
SimpleLogger().Write(logWARNING) <<
".hsgr was prepared with different build. "
"Reprocess to get rid of this warning.";
} else {
if (uuid_loaded.TestGraphUtil(uuid_orig))
{
SimpleLogger().Write(logDEBUG) << "UUID checked out ok";
}
else
{
SimpleLogger().Write(logWARNING) << ".hsgr was prepared with different build. "
"Reprocess to get rid of this warning.";
}
// load checksum
unsigned checksum = 0;
@@ -274,8 +285,21 @@ int main( const int argc, const char * argv[] ) {
shared_layout_ptr->coordinate_list_size = coordinate_list_size;
// allocate shared memory block
// load geometries sizes
std::ifstream geometry_input_stream(
geometries_data_path.c_str(),
std::ios::binary
);
unsigned number_of_geometries_indices = 0;
unsigned number_of_compressed_geometries = 0;
geometry_input_stream.read((char *)&number_of_geometries_indices, sizeof(unsigned));
shared_layout_ptr->geometries_index_list_size = number_of_geometries_indices;
boost::iostreams::seek(geometry_input_stream, number_of_geometries_indices*sizeof(unsigned), BOOST_IOS::cur);
geometry_input_stream.read( (char *)&number_of_compressed_geometries, sizeof(unsigned));
shared_layout_ptr->geometries_list_size = number_of_compressed_geometries;
// allocate shared memory block
SimpleLogger().Write() << "allocating shared memory of " << shared_layout_ptr->GetSizeOfLayout() << " bytes";
SharedMemory * shared_memory = SharedMemoryFactory::Get(
DATA,
@@ -285,11 +309,9 @@ int main( const int argc, const char * argv[] ) {
// read actual data into shared memory object //
// Loading street names
// SimpleLogger().Write() << "Loading names index and chars from: " << names_data_path.string();
unsigned * name_index_ptr = (unsigned*)(
shared_memory_ptr + shared_layout_ptr->GetNameIndexOffset()
);
// SimpleLogger().Write(logDEBUG) << "Bytes: " << shared_layout_ptr->name_index_list_size*sizeof(unsigned);
name_stream.read(
(char*)name_index_ptr,
@@ -316,9 +338,12 @@ int main( const int argc, const char * argv[] ) {
shared_memory_ptr + shared_layout_ptr->GetTurnInstructionListOffset()
);
unsigned * geometries_indicator_ptr = (unsigned *)(
shared_memory_ptr + shared_layout_ptr->GetGeometriesIndicatorOffset()
);
OriginalEdgeData current_edge_data;
for(unsigned i = 0; i < number_of_original_edges; ++i) {
// SimpleLogger().Write() << i << "/" << number_of_edges;
edges_input_stream.read(
(char*)&(current_edge_data),
sizeof(OriginalEdgeData)
@@ -326,9 +351,43 @@ int main( const int argc, const char * argv[] ) {
via_node_ptr[i] = current_edge_data.via_node;
name_id_ptr[i] = current_edge_data.name_id;
turn_instructions_ptr[i] = current_edge_data.turn_instruction;
const unsigned bucket = i / 32;
const unsigned offset = i % 32;
unsigned value = ((0 == offset) ? 0 : geometries_indicator_ptr[bucket]);
if (current_edge_data.compressed_geometry)
{
geometries_indicator_ptr[bucket] = (value | (1 << offset));
}
}
edges_input_stream.close();
// load compressed geometry
unsigned temporary_value;
unsigned * geometries_index_ptr = (unsigned *)(
shared_memory_ptr + shared_layout_ptr->GetGeometriesIndexListOffset()
);
geometry_input_stream.seekg(0, geometry_input_stream.beg);
geometry_input_stream.read((char *)&temporary_value, sizeof(unsigned));
BOOST_ASSERT(temporary_value == shared_layout_ptr->geometries_index_list_size);
geometry_input_stream.read(
(char *)geometries_index_ptr,
shared_layout_ptr->geometries_index_list_size*sizeof(unsigned)
);
unsigned * geometries_list_ptr = (unsigned *)(
shared_memory_ptr + shared_layout_ptr->GetGeometryListOffset()
);
geometry_input_stream.read((char *)&temporary_value, sizeof(unsigned));
BOOST_ASSERT(temporary_value == shared_layout_ptr->geometries_list_size);
geometry_input_stream.read(
(char *)geometries_list_ptr,
shared_layout_ptr->geometries_list_size*sizeof(unsigned)
);
// Loading list of coordinates
FixedPointCoordinate * coordinates_ptr = (FixedPointCoordinate *)(
shared_memory_ptr + shared_layout_ptr->GetCoordinateListOffset()
@@ -370,7 +429,7 @@ int main( const int argc, const char * argv[] ) {
// load the edges of the search graph
QueryGraph::_StrEdge * graph_edge_list_ptr = (QueryGraph::_StrEdge *)(
shared_memory_ptr + shared_layout_ptr->GetGraphEdgeListOffsett()
shared_memory_ptr + shared_layout_ptr->GetGraphEdgeListOffset()
);
hsgr_input_stream.read(
(char*) graph_edge_list_ptr,
@@ -421,6 +480,8 @@ int main( const int argc, const char * argv[] ) {
}
}
SimpleLogger().Write() << "all data loaded";
shared_layout_ptr->PrintInformation();
} catch(const std::exception & e) {
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
}
+76 -46
View File
@@ -43,6 +43,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdlib>
#include <boost/unordered_map.hpp>
#include <iostream>
#include <fstream>
#include <string>
@@ -99,12 +101,14 @@ int main (int argc, char *argv[]) {
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
options(cmdline_options).positional(positional_options).run(), option_variables);
if(option_variables.count("version")) {
if(option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
return 0;
}
if(option_variables.count("help")) {
if(option_variables.count("help"))
{
SimpleLogger().Write() << visible_options;
return 0;
}
@@ -112,24 +116,38 @@ int main (int argc, char *argv[]) {
boost::program_options::notify(option_variables);
// parse config file
if(boost::filesystem::is_regular_file(config_file_path)) {
SimpleLogger().Write() << "Reading options from: " << config_file_path.c_str();
if(boost::filesystem::is_regular_file(config_file_path))
{
SimpleLogger().Write() << "Reading options from: " << config_file_path.string();
std::string config_str;
PrepareConfigFile( config_file_path.c_str(), config_str );
PrepareConfigFile(config_file_path.c_str(), config_str);
std::stringstream config_stream( config_str );
boost::program_options::store(parse_config_file(config_stream, config_file_options), option_variables);
boost::program_options::notify(option_variables);
}
if(!option_variables.count("input")) {
SimpleLogger().Write(logWARNING) << "No input file specified";
if(!option_variables.count("input"))
{
SimpleLogger().Write() << visible_options;
return -1;
return 0;
}
if(1 > requested_num_threads) {
if(1 > requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return -1;
return 1;
}
if(!boost::filesystem::is_regular_file(input_path))
{
SimpleLogger().Write(logWARNING) << "Input file " << input_path.string() << " not found!";
return 1;
}
if(!boost::filesystem::is_regular_file(profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string() << " not found!";
return 1;
}
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
@@ -139,51 +157,65 @@ int main (int argc, char *argv[]) {
/*** Setup Scripting Environment ***/
ScriptingEnvironment scriptingEnvironment(profile_path.c_str());
omp_set_num_threads( std::min( omp_get_num_procs(), requested_num_threads) );
omp_set_num_threads(std::min(omp_get_num_procs(), requested_num_threads));
bool file_has_pbf_format(false);
std::string output_file_name(input_path.c_str());
std::string restrictionsFileName(input_path.c_str());
std::string output_file_name = input_path.string();
std::string restrictionsFileName = input_path.string();
std::string::size_type pos = output_file_name.find(".osm.bz2");
if(pos==std::string::npos) {
if(pos==std::string::npos)
{
pos = output_file_name.find(".osm.pbf");
if(pos!=std::string::npos) {
if (pos!=std::string::npos)
{
file_has_pbf_format = true;
}
}
if(pos==std::string::npos) {
if (pos==std::string::npos)
{
pos = output_file_name.find(".pbf");
if(pos!=std::string::npos) {
if (pos!=std::string::npos)
{
file_has_pbf_format = true;
}
}
if(pos!=std::string::npos) {
output_file_name.replace(pos, 8, ".osrm");
restrictionsFileName.replace(pos, 8, ".osrm.restrictions");
} else {
pos=output_file_name.find(".osm");
if(pos!=std::string::npos) {
output_file_name.replace(pos, 5, ".osrm");
restrictionsFileName.replace(pos, 5, ".osrm.restrictions");
} else {
if (pos == std::string::npos)
{
pos = output_file_name.find(".osm");
if (pos == std::string::npos)
{
output_file_name.append(".osrm");
restrictionsFileName.append(".osrm.restrictions");
}
else
{
output_file_name.replace(pos, 5, ".osrm");
restrictionsFileName.replace(pos, 5, ".osrm.restrictions");
}
}
else
{
output_file_name.replace(pos, 8, ".osrm");
restrictionsFileName.replace(pos, 8, ".osrm.restrictions");
}
StringMap stringMap;
boost::unordered_map<std::string, NodeID> stringMap;
ExtractionContainers externalMemory;
stringMap[""] = 0;
extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap);
BaseParser* parser;
if(file_has_pbf_format) {
if(file_has_pbf_format)
{
parser = new PBFParser(input_path.c_str(), extractCallBacks, scriptingEnvironment);
} else {
}
else
{
parser = new XMLParser(input_path.c_str(), extractCallBacks, scriptingEnvironment);
}
if(!parser->ReadHeader()) {
if(!parser->ReadHeader())
{
throw OSRMException("Parser not initialized!");
}
SimpleLogger().Write() << "Parsing in progress..";
@@ -193,9 +225,10 @@ int main (int argc, char *argv[]) {
(get_timestamp() - parsing_start_time) <<
" seconds";
if( externalMemory.all_edges_list.empty() ) {
if (externalMemory.all_edges_list.empty())
{
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
return -1;
return 1;
}
externalMemory.PrepareData(output_file_name, restrictionsFileName);
@@ -203,22 +236,19 @@ int main (int argc, char *argv[]) {
delete parser;
delete extractCallBacks;
SimpleLogger().Write() <<
"extraction finished after " << get_timestamp() - startup_time <<
"s";
SimpleLogger().Write() << "extraction finished after " << get_timestamp() - startup_time << "s";
SimpleLogger().Write() << "To prepare the data for routing, run: " << "./osrm-prepare " << output_file_name << std::endl;
SimpleLogger().Write() << "To prepare the data for routing, run: "
<< "./osrm-prepare " << output_file_name << std::endl;
} catch(boost::program_options::too_many_positional_options_error& e) {
}
catch(boost::program_options::too_many_positional_options_error& e)
{
SimpleLogger().Write(logWARNING) << "Only one input file can be specified";
return -1;
} catch(boost::program_options::error& e) {
SimpleLogger().Write(logWARNING) << e.what();
return -1;
} catch(std::exception & e) {
SimpleLogger().Write(logWARNING) << "Unhandled exception: " << e.what();
return -1;
return 1;
}
catch(std::exception & e)
{
SimpleLogger().Write(logWARNING) << "Exception occured: " << e.what();
return 1;
}
return 0;
}
+15 -15
View File
@@ -16,9 +16,9 @@ When a max speed is set, osrm will use 2/3 of that as the actual speed.
| bc | trunk | 60 |
When I route I should get
| from | to | route | speed |
| a | b | ab | 85 km/h |
| b | c | bc | 40 km/h |
| from | to | route | speed |
| a | b | ab | 85 km/h |
| b | c | bc | 40 km/h +- 1 |
Scenario: Car - Do not ignore maxspeed when higher than way speed
Given the node map
@@ -30,22 +30,22 @@ When a max speed is set, osrm will use 2/3 of that as the actual speed.
| bc | residential | 90 |
When I route I should get
| from | to | route | speed |
| a | b | ab | 25 km/h |
| b | c | bc | 60 km/h |
| from | to | route | speed |
| a | b | ab | 25 km/h |
| b | c | bc | 60 km/h +- 1 |
Scenario: Car - Forward/backward maxspeed
Given a grid size of 100 meters
Then routability should be
| highway | maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
| primary | | | | 65 km/h | 65 km/h |
| primary | 60 | | | 40 km/h | 40 km/h |
| primary | | 60 | | 40 km/h | 65 km/h |
| primary | | | 60 | 65 km/h | 40 km/h |
| primary | 15 | 60 | | 40 km/h | 10 km/h |
| primary | 15 | | 60 | 10 km/h | 40 km/h |
| primary | 15 | 30 | 60 | 20 km/h | 40 km/h |
| highway | maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
| primary | | | | 65 km/h | 65 km/h |
| primary | 60 | | | 40 km/h | 40 km/h |
| primary | | 60 | | 40 km/h | 65 km/h |
| primary | | | 60 | 65 km/h | 40 km/h |
| primary | 15 | 60 | | 40 km/h | 10 km/h +- 1 |
| primary | 15 | | 60 | 10 km/h +- 1| 40 km/h |
| primary | 15 | 30 | 60 | 20 km/h | 40 km/h |
Scenario: Car - Maxspeed should not allow routing on unroutable ways
Then routability should be
@@ -62,4 +62,4 @@ When a max speed is set, osrm will use 2/3 of that as the actual speed.
| runway | | | | | | |
| runway | | | 100 | | | |
| runway | | | | 100 | | |
| runway | | | | | 100 | |
| runway | | | | | 100 | |
+17 -17
View File
@@ -1,24 +1,24 @@
@routing @car @speed
@routing @car @speed
Feature: Car - speeds
Background:
Given the profile "car"
And a grid size of 1000 meters
Scenario: Car - speed of various way types
Then routability should be
| highway | oneway | bothw |
| motorway | no | 90 km/h |
| motorway_link | no | 75 km/h |
| trunk | no | 85 km/h |
| trunk_link | no | 70 km/h |
| primary | no | 65 km/h |
| primary_link | no | 60 km/h |
| secondary | no | 55 km/h |
| secondary_link | no | 50 km/h |
| tertiary | no | 40 km/h |
| tertiary_link | no | 30 km/h |
| unclassified | no | 25 km/h |
| residential | no | 25 km/h |
| living_street | no | 10 km/h |
| service | no | 15 km/h |
| highway | oneway | bothw |
| motorway | no | 90 km/h |
| motorway_link | no | 75 km/h |
| trunk | no | 85 km/h +- 1 |
| trunk_link | no | 70 km/h +- 1 |
| primary | no | 65 km/h +- 1 |
| primary_link | no | 60 km/h |
| secondary | no | 55 km/h +- 1 |
| secondary_link | no | 50 km/h |
| tertiary | no | 40 km/h |
| tertiary_link | no | 30 km/h |
| unclassified | no | 25 km/h |
| residential | no | 25 km/h |
| living_street | no | 10 km/h |
| service | no | 15 km/h |
+30
View File
@@ -0,0 +1,30 @@
@extract @options @files
Feature: osrm-extract command line options: files
# expansions:
# {base} => path to current input file
# {profile} => path to current profile script
Background:
Given the profile "testbot"
And the node map
| a | b |
And the ways
| nodes |
| ab |
And the data has been saved to disk
Scenario: osrm-extract - Passing base file
When I run "osrm-extract {base}.osm --profile {profile}"
Then stderr should be empty
And it should exit with code 0
Scenario: osrm-extract - Order of options should not matter
When I run "osrm-extract --profile {profile} {base}.osm"
Then stderr should be empty
And it should exit with code 0
Scenario: osrm-extract - Missing input file
When I run "osrm-extract over-the-rainbow.osrm --profile {profile}"
And stderr should contain "over-the-rainbow.osrm"
And stderr should contain "not found"
And it should exit with code 1
+47
View File
@@ -0,0 +1,47 @@
@extract @options @help
Feature: osrm-extract command line options: help
Background:
Given the profile "testbot"
Scenario: osrm-extract - Help should be shown when no options are passed
When I run "osrm-extract"
Then stderr should be empty
And stdout should contain "osrm-extract <input.osm/.osm.bz2/.osm.pbf> [options]:"
And stdout should contain "Options:"
And stdout should contain "--version"
And stdout should contain "--help"
And stdout should contain "--config"
And stdout should contain "Configuration:"
And stdout should contain "--profile"
And stdout should contain "--threads"
And stdout should contain 12 lines
And it should exit with code 0
Scenario: osrm-extract - Help, short
When I run "osrm-extract -h"
Then stderr should be empty
And stdout should contain "osrm-extract <input.osm/.osm.bz2/.osm.pbf> [options]:"
And stdout should contain "Options:"
And stdout should contain "--version"
And stdout should contain "--help"
And stdout should contain "--config"
And stdout should contain "Configuration:"
And stdout should contain "--profile"
And stdout should contain "--threads"
And stdout should contain 12 lines
And it should exit with code 0
Scenario: osrm-extract - Help, long
When I run "osrm-extract --help"
Then stderr should be empty
And stdout should contain "osrm-extract <input.osm/.osm.bz2/.osm.pbf> [options]:"
And stdout should contain "Options:"
And stdout should contain "--version"
And stdout should contain "--help"
And stdout should contain "--config"
And stdout should contain "Configuration:"
And stdout should contain "--profile"
And stdout should contain "--threads"
And stdout should contain 12 lines
And it should exit with code 0
+12
View File
@@ -0,0 +1,12 @@
@extract @options @invalid
Feature: osrm-extract command line options: invalid options
Background:
Given the profile "testbot"
Scenario: osrm-extract - Non-existing option
When I run "osrm-extract --fly-me-to-the-moon"
Then stdout should be empty
And stderr should contain "option"
And stderr should contain "fly-me-to-the-moon"
And it should exit with code 1
+22
View File
@@ -0,0 +1,22 @@
@extract @options @version
Feature: osrm-extract command line options: version
# the regex will match these two formats:
# v0.3.7.0 # this is the normal format when you build from a git clone
# -128-NOTFOUND # if you build from a shallow clone (used on Travis)
Background:
Given the profile "testbot"
Scenario: osrm-extract - Version, short
When I run "osrm-extract --v"
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
Scenario: osrm-extract - Version, long
When I run "osrm-extract --version"
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
+30
View File
@@ -0,0 +1,30 @@
@prepare @options @files
Feature: osrm-prepare command line options: files
# expansions:
# {base} => path to current input file
# {profile} => path to current profile script
Background:
Given the profile "testbot"
And the node map
| a | b |
And the ways
| nodes |
| ab |
And the data has been extracted
Scenario: osrm-prepare - Passing base file
When I run "osrm-prepare {base}.osrm --profile {profile}"
Then stderr should be empty
And it should exit with code 0
Scenario: osrm-prepare - Order of options should not matter
When I run "osrm-prepare --profile {profile} {base}.osrm"
Then stderr should be empty
And it should exit with code 0
Scenario: osrm-prepare - Missing input file
When I run "osrm-prepare over-the-rainbow.osrm --profile {profile}"
And stderr should contain "over-the-rainbow.osrm"
And stderr should contain "not found"
And it should exit with code 1
+50
View File
@@ -0,0 +1,50 @@
@prepare @options @help
Feature: osrm-prepare command line options: help
Background:
Given the profile "testbot"
Scenario: osrm-prepare - Help should be shown when no options are passed
When I run "osrm-prepare"
Then stderr should be empty
And stdout should contain "osrm-prepare <input.osrm> [options]:"
And stdout should contain "Options:"
And stdout should contain "--version"
And stdout should contain "--help"
And stdout should contain "--config"
And stdout should contain "Configuration:"
And stdout should contain "--restrictions"
And stdout should contain "--profile"
And stdout should contain "--threads"
And stdout should contain 15 lines
And it should exit with code 0
Scenario: osrm-prepare - Help, short
When I run "osrm-prepare -h"
Then stderr should be empty
And stdout should contain "osrm-prepare <input.osrm> [options]:"
And stdout should contain "Options:"
And stdout should contain "--version"
And stdout should contain "--help"
And stdout should contain "--config"
And stdout should contain "Configuration:"
And stdout should contain "--restrictions"
And stdout should contain "--profile"
And stdout should contain "--threads"
And stdout should contain 15 lines
And it should exit with code 0
Scenario: osrm-prepare - Help, long
When I run "osrm-prepare --help"
Then stderr should be empty
And stdout should contain "osrm-prepare <input.osrm> [options]:"
And stdout should contain "Options:"
And stdout should contain "--version"
And stdout should contain "--help"
And stdout should contain "--config"
And stdout should contain "Configuration:"
And stdout should contain "--restrictions"
And stdout should contain "--profile"
And stdout should contain "--threads"
And stdout should contain 15 lines
And it should exit with code 0
+12
View File
@@ -0,0 +1,12 @@
@prepare @options @invalid
Feature: osrm-prepare command line options: invalid options
Background:
Given the profile "testbot"
Scenario: osrm-prepare - Non-existing option
When I run "osrm-prepare --fly-me-to-the-moon"
Then stdout should be empty
And stderr should contain "option"
And stderr should contain "fly-me-to-the-moon"
And it should exit with code 1
+22
View File
@@ -0,0 +1,22 @@
@prepare @options @version
Feature: osrm-prepare command line options: version
# the regex will match these two formats:
# v0.3.7.0 # this is the normal format when you build from a git clone
# -128-NOTFOUND # if you build from a shallow clone (used on Travis)
Background:
Given the profile "testbot"
Scenario: osrm-prepare - Version, short
When I run "osrm-prepare --v"
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
Scenario: osrm-prepare - Version, long
When I run "osrm-prepare --version"
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
@@ -1,5 +1,5 @@
@routing @options @files
Feature: Command line options: files
@routed @options @files
Feature: osrm-routed command line options: files
# Normally when launching osrm-routed, it will keep running as a server until it's shut down.
# For testing program options, the --trial option is used, which causes osrm-routed to quit
# immediately after initialization. This makes testing easier and faster.
@@ -14,9 +14,9 @@ Feature: Command line options: files
And the ways
| nodes |
| ab |
And I preprocess data
And the data has been prepared
Scenario: Passing base file
Scenario: osrm-routed - Passing base file
When I run "osrm-routed {base}.osrm --trial"
Then stdout should contain /^\[info\] starting up engines/
And stdout should contain /\d{1,2}\.\d{1,2}\.\d{1,2}/
@@ -24,4 +24,4 @@ Feature: Command line options: files
And stdout should contain /^\[info\] loaded plugin: viaroute/
And stdout should contain /^\[info\] trial run/
And stdout should contain /^\[info\] shutdown completed/
And it should exit with code 0
And it should exit with code 0
@@ -1,10 +1,10 @@
@routing @options
Feature: Command line options: help
@routed @options @help
Feature: osrm-routed command line options: help
Background:
Given the profile "testbot"
Scenario: Help should be shown when no options are passed
Scenario: osrm-routed - Help should be shown when no options are passed
When I run "osrm-routed"
Then stderr should be empty
And stdout should contain "osrm-routed <base.osrm> [<options>]:"
@@ -25,9 +25,10 @@ Feature: Command line options: help
And stdout should contain "--port"
And stdout should contain "--threads"
And stdout should contain "--sharedmemory"
And stdout should contain 22 lines
And it should exit with code 0
Scenario: Help, short
Scenario: osrm-routed - Help, short
When I run "osrm-routed -h"
Then stderr should be empty
And stdout should contain "osrm-routed <base.osrm> [<options>]:"
@@ -48,9 +49,10 @@ Feature: Command line options: help
And stdout should contain "--port"
And stdout should contain "--threads"
And stdout should contain "--sharedmemory"
And stdout should contain 22 lines
And it should exit with code 0
Scenario: Help, long
Scenario: osrm-routed - Help, long
When I run "osrm-routed --help"
Then stderr should be empty
And stdout should contain "osrm-routed <base.osrm> [<options>]:"
@@ -71,4 +73,5 @@ Feature: Command line options: help
And stdout should contain "--port"
And stdout should contain "--threads"
And stdout should contain "--sharedmemory"
And it should exit with code 0
And stdout should contain 22 lines
And it should exit with code 0
@@ -1,17 +1,17 @@
@routing @options
Feature: Command line options: invalid options
@routed @options @invalid
Feature: osrm-routed command line options: invalid options
Background:
Given the profile "testbot"
Scenario: Non-existing option
Scenario: osrm-routed - Non-existing option
When I run "osrm-routed --fly-me-to-the-moon"
Then stdout should be empty
And stderr should contain "exception"
And stderr should contain "fly-me-to-the-moon"
And it should exit with code 1
Scenario: Missing file
Scenario: osrm-routed - Missing file
When I run "osrm-routed over-the-rainbow.osrm"
Then stdout should contain "over-the-rainbow.osrm"
And stderr should contain "exception"
@@ -1,5 +1,5 @@
@routing @options
Feature: Command line options: version
@routed @options @version
Feature: osrm-routed command line options: version
# the regex will match these two formats:
# v0.3.7.0 # this is the normal format when you build from a git clone
# -128-NOTFOUND # if you build from a shallow clone (used on Travis)
@@ -7,14 +7,14 @@ Feature: Command line options: version
Background:
Given the profile "testbot"
Scenario: Version, short
Scenario: osrm-routed - Version, short
When I run "osrm-routed --v"
Then stderr should be empty
And stdout should contain 1 line
And stdout should contain /(v\d{1,2}\.\d{1,2}\.\d{1,2}|\w*-\d+-\w+)/
And it should exit with code 0
Scenario: Version, long
Scenario: osrm-routed - Version, long
When I run "osrm-routed --version"
Then stderr should be empty
And stdout should contain 1 line
+25
View File
@@ -133,3 +133,28 @@ Given /^the input file ([^"]*)$/ do |file|
raise "*** Input file must in .osm format" unless File.extname(file)=='.osm'
@osm_str = File.read file
end
Given /^the data has been saved to disk$/ do
begin
write_input_data
rescue OSRMError => e
@process_error = e
end
end
Given /^the data has been extracted$/ do
begin
write_input_data
extract_data unless extracted?
rescue OSRMError => e
@process_error = e
end
end
Given /^the data has been prepared$/ do
begin
reprocess
rescue OSRMError => e
@process_error = e
end
end
+12 -18
View File
@@ -1,25 +1,19 @@
When(/^I run "osrm\-routed\s?(.*?)"$/) do |options|
Dir.chdir TEST_FOLDER do
if options.include? '{base}'
# expand {base} to base path of preprocessed data file
raise "*** Cannot expand {base} without a preprocessed file." unless @osm_file
options_expanded = options.gsub "{base}", "#{@osm_file}"
else
options_expanded = options
end
begin
Timeout.timeout(1) do
@stdout = `#{BIN_PATH}/osrm-routed #{options_expanded} 2>error.log`
@stderr = File.read 'error.log'
@exit_code = $?.exitstatus
end
rescue Timeout::Error
raise "*** osrm-routed didn't quit. Maybe the --trial option wasn't used?"
end
begin
Timeout.timeout(1) { run_bin 'osrm-routed', options }
rescue Timeout::Error
raise "*** osrm-routed didn't quit. Maybe the --trial option wasn't used?"
end
end
When(/^I run "osrm\-extract\s?(.*?)"$/) do |options|
run_bin 'osrm-extract', options
end
When(/^I run "osrm\-prepare\s?(.*?)"$/) do |options|
run_bin 'osrm-prepare', options
end
Then /^it should exit with code (\d+)$/ do |code|
@exit_code.should == code.to_i
end
+1 -9
View File
@@ -29,16 +29,8 @@ Then /^response should be a well-formed route$/ do
@json['via_indices'].class.should == Array
end
When /^I preprocess data$/ do
begin
reprocess
rescue OSRMError => e
@process_error = e
end
end
Then /^"([^"]*)" should return code (\d+)$/ do |binary, code|
@process_error.is_a?(OSRMError).should == true
@process_error.process.should == binary
@process_error.code.to_i.should == code.to_i
end
end

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