Compare commits

..

150 Commits

Author SHA1 Message Date
Patrick Niklaus db0db58bf8 Make gcc 4.8 happy and disable protected because of lambdas 2016-03-19 00:01:43 +01:00
Daniel Patterson 1751fedfd0 Include edge duration information. 2016-03-18 23:34:28 +01:00
Patrick Niklaus b3599ea249 Implement viewport code to fix simplification
This fixes #2083
2016-03-18 23:25:54 +01:00
Patrick Niklaus 2927d149db Add tests for coordinate transformation 2016-03-18 23:25:44 +01:00
Patrick Niklaus 0d628da3ba Consolidate math functions 2016-03-18 23:25:44 +01:00
Patrick Niklaus 497e4154a7 get_name_for_id -> GetNameForID 2016-03-18 19:29:09 +01:00
Patrick Niklaus 88db0ba90c Simplfy name change announcement 2016-03-18 18:16:20 +01:00
Moritz Kobitzsch 44e1e57790 fix division by zero 2016-03-18 17:41:55 +01:00
Moritz Kobitzsch 1a4f6cba7a restructured to only return valid turns to the outside + cleanup 2016-03-18 17:41:55 +01:00
Moritz Kobitzsch ee5020baf3 less new names, forks consider road classes, api clean-up 2016-03-18 17:41:55 +01:00
Moritz Kobitzsch 7b755eea54 implement basic turn handling 2016-03-18 17:41:55 +01:00
Moritz Kobitzsch fbdafca4f2 implements relative position feature based on coordinates 2016-03-18 17:33:05 +01:00
Patrick Niklaus 873950ee86 Don't sum up durations of merged steps since we do that in a different place now 2016-03-18 17:33:05 +01:00
Patrick Niklaus 50fcc65431 Fix foward/backwad swap 2016-03-18 17:33:05 +01:00
Patrick Niklaus 343011c3da Limit zoomlevel to 18 2016-03-18 17:33:05 +01:00
Patrick Niklaus 4c66fcafaa Fix shared memory 2016-03-18 17:33:05 +01:00
Patrick Niklaus 513fd09780 Fixup for last commit 2016-03-18 17:33:05 +01:00
Daniel Patterson f6de8f3444 Enables the use of multiple segment-speed-files on the osrm-contract
command line, and exposes the file name used for each edge in the debug
tiles.
2016-03-18 17:33:05 +01:00
Patrick Niklaus 082eac68f7 Fix ingestion fixed duration values from UnpackPath 2016-03-18 17:33:05 +01:00
Patrick Niklaus 7091331b55 Fix durations in UnpackPath 2016-03-18 17:33:05 +01:00
Moritz Kobitzsch 7149e25636 fixes a broken assertion 2016-03-18 17:33:05 +01:00
Moritz Kobitzsch f76fc7fd83 fix merging of turn instructions 2016-03-18 17:33:05 +01:00
Patrick Niklaus 6a0db71e34 Include reverse edges again 2016-03-18 17:33:05 +01:00
Patrick Niklaus d6776b3e81 Formating and logging changes for turn classification 2016-03-18 17:33:05 +01:00
Patrick Niklaus f9eb22093b Handle case of dead-end edges by inserting an invalid turn 2016-03-18 17:33:05 +01:00
Moritz Kobitzsch 9fb86bcac5 report depart/arrive in addition to waypoint 2016-03-18 17:33:05 +01:00
Patrick Niklaus 17d775588d Only install necessary headers 2016-03-18 17:33:05 +01:00
Daniel J. Hofmann 810c0f3b3e Adds the license preamble for all publicly installed eaders, closes #2036 2016-03-18 17:33:05 +01:00
Patrick Niklaus fe3005f630 Remove the encoder/decoder dependecy from Hint 2016-03-18 17:33:04 +01:00
Patrick Niklaus ab7ded02c1 Rename alternative -> alternatives 2016-03-18 17:33:04 +01:00
Patrick Niklaus bad4d4d6c7 Remove obsolete debug information 2016-03-18 17:33:04 +01:00
Patrick Niklaus 8485a99349 Just return NoSegment in map matching if all candidates are empty 2016-03-18 17:33:04 +01:00
Patrick Niklaus af6b84a432 Add failing test for map matching of outlier 2016-03-18 17:33:04 +01:00
Patrick Niklaus 1dc26585d2 Fix missing capitalization of error codes 2016-03-18 17:33:04 +01:00
Moritz Kobitzsch a95f4a8816 encapsulated into class 2016-03-18 17:33:04 +01:00
Moritz Kobitzsch 94a2072533 improving fork handling on three-way turns 2016-03-18 17:33:04 +01:00
Moritz Kobitzsch a5568f8be4 fix comparison for ramps on three-way turns 2016-03-18 17:33:04 +01:00
Patrick Niklaus dafd724923 Minor auto iterator cleanup 2016-03-18 17:33:04 +01:00
Patrick Niklaus 807f5c0014 Don't pass down unsnapped coordinates. All information is already there 2016-03-18 17:33:04 +01:00
Patrick Niklaus 956b264ece Fix camMergeTrivially 2016-03-18 17:33:04 +01:00
Moritz Kobitzsch 8967cebd10 fixes roundabout counting 2016-03-18 17:33:04 +01:00
Moritz Kobitzsch 431a8cb5c1 fixes assignment for basic turn types / invalid ramp assignment 2016-03-18 17:33:04 +01:00
Patrick Niklaus 1675ff1748 Add edge id assertions 2016-03-18 17:33:04 +01:00
Patrick Niklaus c8cd89355c Don't pass shared_ptr down to functions
"Don’t pass a smart pointer as a function parameter unless you want to
use or manipulate the smart pointer itself, such as to share or transfer
ownership."

Source:
http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
2016-03-18 17:33:04 +01:00
Patrick Niklaus e50bf1062f Move bearing to public namespace 2016-03-18 17:33:04 +01:00
Daniel J. Hofmann 50cf0cf84f Properly includes needed headers in turn analysis interface 2016-03-18 17:33:04 +01:00
Daniel J. Hofmann da298f0f28 Const-correctnes for compressed geometry iterator 2016-03-18 17:33:04 +01:00
Daniel J. Hofmann d5a3d817aa Use stdint and using type-alias for discrete angle 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 5f4424482e Hide functional road classification based on tags in implementation file 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 9d0da926e5 Inline initialize functional road classification hash table 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 512dd9a5e2 256 functional road classes should be enough 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann bba7e49d15 Moves route assembly into implementation file 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 70066c3ed0 Fixes remaining engine/guidance includes 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 5661628f2c Fixes accumulate living in <numeric> and not <algorithm> 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 2ff9386368 Puts step maneuver handling into implementation file 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 37e93cf96a Removes penalizing move 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann a7b99b1549 Uses static_casts for underlying type in post processing 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 3443baa311 Fix asymmetry in min/max from using -max 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann d88ce65385 Adapts MakeResponse to not pass vector by pointer 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 7865bd8815 Fixes multi-line comment 2016-03-18 17:33:03 +01:00
Daniel J. Hofmann 6856f00074 Runs scripts/format.sh 2016-03-18 17:33:03 +01:00
Patrick Niklaus bc67488f25 Fix coodinate include and unused warnings 2016-03-18 17:33:03 +01:00
Moritz Kobitzsch 6c5822fb45 start of four way turns 2016-03-18 17:33:03 +01:00
Moritz Kobitzsch 779ddeeb69 improved fork handling 2016-03-18 17:33:03 +01:00
Patrick Niklaus 01c4b3f7a3 Fix crash on extracting Berlin in guidance 2016-03-18 17:33:03 +01:00
Moritz Kobitzsch fecd3d27ac bugfixing/classification 2016-03-18 17:33:02 +01:00
Patrick Niklaus 0724c4a2d8 Big Restructuring / Cleanup 2016-03-18 17:33:02 +01:00
Moritz Kobitzsch cba4baf920 starting on conflict resolution 2016-03-18 17:33:02 +01:00
Lauren Budorick dda6d49f4a Fixes for gcc compiling, temporary hacks to remove later 2016-03-18 17:33:02 +01:00
Moritz Kobitzsch 6f9d8a691d handle segregated roads (merge for turn analysis) 2016-03-18 17:33:02 +01:00
Moritz Kobitzsch f713408d46 structural changes, motorway handling 2016-03-18 17:33:02 +01:00
Moritz Kobitzsch 80843ecc89 enter and exit roundabout feature - currently not showing turn 2016-03-18 17:33:02 +01:00
Moritz Kobitzsch aced4ebe56 migrated out of edge based graph factory 2016-03-18 17:33:02 +01:00
Moritz Kobitzsch df00b99d84 relative waypoint locations 2016-03-18 17:33:02 +01:00
Moritz Kobitzsch 7dfe91bba0 handling of roundabouts (simple version) 2016-03-18 17:33:02 +01:00
Moritz Kobitzsch 8753590f59 advanced guidance on 5.0 2016-03-18 17:33:02 +01:00
Patrick Niklaus 12ff303cf8 Fix numerical problems with polyline 2016-03-18 17:33:02 +01:00
Patrick Niklaus 70dfe23f0e Fix table response format to return null + double in seconds 2016-03-18 17:33:02 +01:00
Patrick Niklaus 6ca0afa212 Return NoMatch 2016-03-18 17:33:02 +01:00
Daniel J. Hofmann 31f735b08e Provides ctor from base path for EngineConfig, fixes #2030 2016-03-18 17:33:02 +01:00
Patrick Niklaus b01b7dcbca Add support for tile plugin 2016-03-18 17:33:02 +01:00
Patrick Niklaus 248a0af761 Preliminary integration of the tile plugin 2016-03-18 17:33:02 +01:00
Patrick Niklaus 49fff1d93f sources and destinations can be empty actually 2016-03-18 17:33:02 +01:00
Daniel J. Hofmann 29a72a9e1a Fixes coordinate, source and destination validation by means of backporting #2041 2016-03-18 17:33:01 +01:00
Daniel J. Hofmann b3a709b98d Fixes ownership semantics and forwarding references misplacements in the JSON factory 2016-03-18 17:33:01 +01:00
Daniel J. Hofmann aa3472cc6b Unwrap function call from identity lambda 2016-03-18 17:33:01 +01:00
Daniel J. Hofmann 3db1509855 Uses JSON's String constructor for polyline encoding 2016-03-18 17:33:01 +01:00
Daniel J. Hofmann 53f47458a2 Passes coordinates by value 2016-03-18 17:33:01 +01:00
Daniel J. Hofmann f784b85cd6 Asserts on unknown TurnInstruction 2016-03-18 17:33:01 +01:00
Daniel J. Hofmann 02c3c3e847 Fixes header includes in the JSON factory 2016-03-18 17:33:01 +01:00
Dane Springmeyer 8af3a036a7 fix compile of osrm-components 2016-03-18 17:33:01 +01:00
Patrick Niklaus 7803d6116b Fix if the last coordinate is not found 2016-03-18 17:33:01 +01:00
Patrick Niklaus 07cd80d042 Allocate correct table size 2016-03-18 17:33:01 +01:00
Patrick Niklaus fd6abcfde3 Fix travel mode passing from profiles up to the API 2016-03-18 17:33:01 +01:00
Patrick Niklaus 690a2a41a4 Fix geometries type in steps 2016-03-18 17:33:01 +01:00
Patrick Niklaus dd1f9e5a6a Fix table parameter parsing 2016-03-18 17:33:01 +01:00
Patrick Niklaus e4ed2f6a2f Fix behaviour of table if sources/destinations arrays are empty 2016-03-18 17:33:01 +01:00
Patrick Niklaus 25f86b68dc Fuck. this. shit. 2016-03-18 17:33:01 +01:00
Patrick Niklaus 5916ddda80 Change stream operator of strong typedef 2016-03-18 17:33:01 +01:00
Patrick Niklaus 2e214ac222 Fix stream operator for coordinate 2016-03-18 17:33:01 +01:00
Patrick Niklaus 5acd2ca394 Add stream operator to Rectangle 2016-03-18 17:33:01 +01:00
Patrick Niklaus ffaf0fc86f Add euclideanDistance to coordinate_calculation 2016-03-18 17:33:01 +01:00
Patrick Niklaus ef6c62d224 Simplify static_rtree tests 2016-03-18 17:33:01 +01:00
Patrick Niklaus fed2a67e42 First round of lat,lng -> lng,lat switcheroo 2016-03-18 17:33:00 +01:00
Patrick Niklaus 059ee4e350 Add rectangle unit test 2016-03-18 17:33:00 +01:00
Patrick Niklaus 53a74ce3e6 Fix match and trip API response 2016-03-18 17:33:00 +01:00
Patrick Niklaus b18c7d75da Fix out-of-bounds write in map_matching 2016-03-18 17:33:00 +01:00
Dane Springmeyer f3e5ce561a Fix compile on OS X 2016-03-18 17:33:00 +01:00
Patrick Niklaus 65d56182f2 Finish the nearest plugin 2016-03-18 17:33:00 +01:00
Patrick Niklaus 1c05d8b7ae Initialize NearestParameters correctly 2016-03-18 17:33:00 +01:00
Patrick Niklaus 6223ee887c Adapt to feedback in #519 2016-03-18 17:33:00 +01:00
Patrick Niklaus d1528dc4ac Add trip plugin 2016-03-18 17:33:00 +01:00
Patrick Niklaus 7a042e643f Hook up map matching 2016-03-18 17:33:00 +01:00
Patrick Niklaus a129e549eb First compiling version of map_match plugin 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann 581b5c2ab6 Adapts example/example.cpp to new osrm api 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann ece2056a13 Install _all_ transitively from public headers included header 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann d6e5b79747 Fix missing headers in hint.hpp 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann 2d98bacdd5 Adds $prefix/include/osrm to include dirs so that transitive header includes without osrm prefix can be found 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann 8863947e86 Adapt the example to include all osrm public headers 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann 27f74432a0 Fixes missing public header installations 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann 03d88b3df2 Fix forward declarations in publicly facing osrm header 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann bdfa072cac Enable all plugins with aStatus::Error return code fallback for not implemented ones 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann 65ba774ebc Adds publicly facing alias headers for parameters 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann d34c215c09 Temporarily comment out match.cpp as to not break the build process 2016-03-18 17:33:00 +01:00
Daniel J. Hofmann c88eeb89c6 We don't need templates at all, this is not CRTP? 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann bde8ec1dbd Fix classes for service member function definitions 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann 49a173652b Service skeletons for nearest, trip, match 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann e4dace1d51 Fix grammar constraint and enable all plugin links 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann 43d1e40284 Plugin grammar skeletons 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann 139220058e Enforce parameter and grammar type to catch subtle bugs 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann 11a92a8e54 Link parameters to grammars 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann d3a2c1c41c Require a BaseParameters type at compile time via enable_if 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann 566505fd0f Adapts Nearest plugin to new API 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann 9dada6b46a Fix deleting incomplete type and make Engine moveable only 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann f9d2440d95 Adapts publicly facing new API 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann a4387f39f1 Adapts NearestParameters to new API 2016-03-18 17:32:59 +01:00
Patrick Niklaus 1902292629 Initial non-building match plugin 2016-03-18 17:32:59 +01:00
Lauren Budorick bbf2ac23b4 Include numeric in assemble_overview.cpp (needed on OSX for std::accumulate) 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann 445df08fb4 Semantic action handler requires passing optional by value and fusion::vector2 2016-03-18 17:32:59 +01:00
Patrick Niklaus 27a2b061bf Add tests for bearing parsing 2016-03-18 17:32:59 +01:00
Patrick Niklaus 944947962b Add table service 2016-03-18 17:32:59 +01:00
Patrick Niklaus fda8f6ecef Add table API 2016-03-18 17:32:59 +01:00
Daniel J. Hofmann ca6c1d7bb1 Optional<T> semantic action handler takes T argument 2016-03-18 17:32:59 +01:00
Patrick Niklaus d88dda1a45 Fix parameter parsing tests 2016-03-18 17:32:59 +01:00
Patrick Niklaus 207f1d7732 Fix table plugin 2016-03-18 17:32:58 +01:00
Daniel J. Hofmann d73600387b First take at distance table API re-write 2016-03-18 17:32:58 +01:00
Daniel J. Hofmann 9194ab590c Adapts TableParameters and its validation to new API 2016-03-18 17:32:58 +01:00
Patrick Niklaus 68eeb20c5c Add viaroute suport for new API 2016-03-18 17:32:58 +01:00
Patrick Niklaus 2f3b4373f9 Also exclude the compressed flag from the data format 2016-03-18 17:30:13 +01:00
Patrick Niklaus 1b25bebeac Remove geometry indicator 2016-03-18 17:30:13 +01:00
68 changed files with 1331 additions and 1545 deletions
+2 -4
View File
@@ -80,7 +80,7 @@ add_executable(osrm-extract src/tools/extract.cpp)
add_executable(osrm-contract src/tools/contract.cpp)
add_executable(osrm-routed src/tools/routed.cpp $<TARGET_OBJECTS:SERVER> $<TARGET_OBJECTS:UTIL>)
add_executable(osrm-datastore src/tools/store.cpp $<TARGET_OBJECTS:UTIL>)
add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:UTIL> $<TARGET_OBJECTS:STORAGE>)
add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_extract $<TARGET_OBJECTS:EXTRACTOR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_contract $<TARGET_OBJECTS:CONTRACTOR> $<TARGET_OBJECTS:UTIL>)
add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:UTIL>)
@@ -94,7 +94,6 @@ add_executable(server-tests EXCLUDE_FROM_ALL unit_tests/server_tests.cpp ${Serve
# Benchmarks
add_executable(rtree-bench EXCLUDE_FROM_ALL src/benchmarks/static_rtree.cpp $<TARGET_OBJECTS:UTIL>)
target_include_directories(engine-tests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/unit_tests)
target_include_directories(util-tests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/unit_tests)
target_include_directories(rtree-bench PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/unit_tests)
@@ -382,10 +381,9 @@ set(EngineHeader include/engine/status.hpp include/engine/engine_config.hpp incl
set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/strong_typedef.hpp)
set(ExtractorHeader include/extractor/extractor.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp)
set(StorageHeader include/storage/storage.hpp include/storage/storage_config.hpp)
#set(StorageHeader include/storage/storage.hpp include/storage/storage_config.hpp)
install(FILES ${EngineHeader} DESTINATION include/osrm/engine)
install(FILES ${UtilHeader} DESTINATION include/osrm/util)
install(FILES ${StorageHeader} DESTINATION include/osrm/storage)
install(FILES ${ExtractorHeader} DESTINATION include/osrm/extractor)
install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor)
install(FILES ${LibraryGlob} DESTINATION include/osrm)
+1 -2
View File
@@ -29,8 +29,7 @@ int main(int argc, const char *argv[]) try
using namespace osrm;
// Configure based on a .osrm base path, and no datasets in shared mem from osrm-datastore
EngineConfig config;
config.storage_config = {argv[1]};
EngineConfig config{argv[1]};
config.use_shared_memory = false;
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
+3 -31
View File
@@ -72,7 +72,7 @@ class RouteAPI : public BaseAPI
}
util::json::Object MakeRoute(const std::vector<PhantomNodes> &segment_end_coordinates,
const std::vector<std::vector<PathData>> &unpacked_path_segments,
std::vector<std::vector<PathData>> unpacked_path_segments,
const std::vector<bool> &source_traversed_in_reverse,
const std::vector<bool> &target_traversed_in_reverse) const
{
@@ -82,6 +82,7 @@ class RouteAPI : public BaseAPI
legs.reserve(number_of_legs);
leg_geometries.reserve(number_of_legs);
unpacked_path_segments = guidance::postProcess(std::move(unpacked_path_segments));
for (auto idx : util::irange(0UL, number_of_legs))
{
const auto &phantoms = segment_end_coordinates[idx];
@@ -97,43 +98,14 @@ class RouteAPI : public BaseAPI
if (parameters.steps)
{
auto steps = guidance::assembleSteps(
leg.steps = guidance::assembleSteps(
BaseAPI::facade, path_data, leg_geometry, phantoms.source_phantom,
phantoms.target_phantom, reversed_source, reversed_target);
/* Perform step-based post-processing.
*
* Using post-processing on basis of route-steps for a single leg at a time
* comes at the cost that we cannot count the correct exit for roundabouts.
* We can only emit the exit nr/intersections up to/starting at a part of the leg.
* If a roundabout is not terminated in a leg, we will end up with a enter-roundabout
* and exit-roundabout-nr where the exit nr is out of sync with the previous enter.
*
* | S |
* * *
* ----* * ----
* T
* ----* * ----
* V * *
* | |
* | |
*
* Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say to take
* the second exit, even though counting from S it would be the third.
* For S, we only emit `roundabout` without an exit number, showing that we enter a roundabout
* to find a via point.
* The same exit will be emitted, though, if we should start routing at S, making
* the overall response consistent.
*/
leg.steps = guidance::postProcess(std::move(steps));
leg_geometry = guidance::resyncGeometry(std::move(leg_geometry),leg.steps);
}
leg_geometries.push_back(std::move(leg_geometry));
legs.push_back(std::move(leg));
}
auto route = guidance::assembleRoute(legs);
boost::optional<util::json::Value> json_overview;
if (parameters.overview != RouteParameters::OverviewType::False)
+5 -4
View File
@@ -60,10 +60,10 @@ struct RouteParameters : public BaseParameters
const bool alternatives_,
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> uturns_,
std::vector<boost::optional<bool>> uturns_,
Args... args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
geometries{geometries_}, overview{overview_}, uturns{uturns_}
geometries{geometries_}, overview{overview_}, uturns{std::move(uturns_)}
{
}
@@ -71,11 +71,12 @@ struct RouteParameters : public BaseParameters
bool alternatives = true;
GeometriesType geometries = GeometriesType::Polyline;
OverviewType overview = OverviewType::Simplified;
boost::optional<bool> uturns;
std::vector<boost::optional<bool>> uturns;
bool IsValid() const
{
return coordinates.size() >= 2 && BaseParameters::IsValid();
return coordinates.size() >= 2 && BaseParameters::IsValid() &&
(uturns.empty() || uturns.size() == coordinates.size());
}
};
}
-126
View File
@@ -1,126 +0,0 @@
#ifndef OSRM_BASE64_HPP
#define OSRM_BASE64_HPP
#include <string>
#include <iterator>
#include <type_traits>
#include <cstddef>
#include <climits>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/range/algorithm/copy.hpp>
// RFC 4648 "The Base16, Base32, and Base64 Data Encodings"
// See: https://tools.ietf.org/html/rfc4648
// Implementation adapted from: http://stackoverflow.com/a/28471421
// The C++ standard guarantees none of this by default, but we need it in the following.
static_assert(CHAR_BIT == 8u, "we assume a byte holds 8 bits");
static_assert(sizeof(char) == 1u, "we assume a char is one byte large");
namespace osrm
{
namespace engine
{
// Encoding Implementation
// Encodes a chunk of memory to Base64.
inline std::string encodeBase64(const unsigned char *first, std::size_t size)
{
using namespace boost::archive::iterators;
const std::string bytes{first, first + size};
using Iter = base64_from_binary<transform_width<std::string::const_iterator, 6, 8>>;
Iter view_first{begin(bytes)};
Iter view_last{end(bytes)};
std::string encoded{view_first, view_last};
return encoded.append((3 - size % 3) % 3, '=');
}
// C++11 standard 3.9.1/1: Plain char, signed char, and unsigned char are three distinct types
// Overload for signed char catches (not only but also) C-string literals.
inline std::string encodeBase64(const signed char *first, std::size_t size)
{
return encodeBase64(reinterpret_cast<const unsigned char *>(first), size);
}
// Overload for char catches (not only but also) C-string literals.
inline std::string encodeBase64(const char *first, std::size_t size)
{
return encodeBase64(reinterpret_cast<const unsigned char *>(first), size);
}
// Convenience specialization, encoding from string instead of byte-dumping it.
inline std::string encodeBase64(const std::string &x) { return encodeBase64(x.data(), x.size()); }
// Encode any sufficiently trivial object to Base64.
template <typename T> std::string encodeBase64Bytewise(const T &x)
{
#if not defined __GNUC__ or __GNUC__ > 4
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
return encodeBase64(reinterpret_cast<const unsigned char *>(&x), sizeof(T));
}
// Decoding Implementation
// Decodes into a chunk of memory that is at least as large as the input.
template <typename OutputIter> void decodeBase64(const std::string &encoded, OutputIter out)
{
using namespace boost::archive::iterators;
using namespace boost::algorithm;
using Iter = transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>;
Iter view_first{begin(encoded)};
Iter view_last{end(encoded)};
const auto null = [](const unsigned char c)
{
return c == '\0';
};
const auto bytes = trim_right_copy_if(std::string{view_first, view_last}, null);
boost::copy(bytes, out);
}
// Convenience specialization, filling string instead of byte-dumping into it.
inline std::string decodeBase64(const std::string &encoded)
{
std::string rv;
decodeBase64(encoded, std::back_inserter(rv));
return rv;
}
// Decodes from Base 64 to any sufficiently trivial object.
template <typename T> T decodeBase64Bytewise(const std::string &encoded)
{
#if not defined __GNUC__ or __GNUC__ > 4
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
T x;
decodeBase64(encoded, reinterpret_cast<unsigned char *>(&x));
return x;
}
} // ns engine
} // ns osrm
#endif /* OSRM_BASE64_HPP */
@@ -143,8 +143,6 @@ class BaseDataFacade
virtual std::size_t GetCoreSize() const = 0;
virtual std::string GetTimestamp() const = 0;
virtual bool GetUTurnsDefault() const = 0;
};
}
}
@@ -9,7 +9,6 @@
#include "engine/geospatial_query.hpp"
#include "extractor/original_edge_data.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
#include "contractor/query_edge.hpp"
#include "util/shared_memory_vector_wrapper.hpp"
@@ -80,7 +79,6 @@ class InternalDataFacade final : public BaseDataFacade
util::ShM<unsigned, false>::vector m_segment_weights;
util::ShM<uint8_t, false>::vector m_datasource_list;
util::ShM<std::string, false>::vector m_datasource_names;
extractor::ProfileProperties m_profile_properties;
boost::thread_specific_ptr<InternalRTree> m_static_rtree;
boost::thread_specific_ptr<InternalGeospatialQuery> m_geospatial_query;
@@ -88,26 +86,26 @@ class InternalDataFacade final : public BaseDataFacade
boost::filesystem::path file_index_path;
util::RangeTable<16, false> m_name_table;
void LoadProfileProperties(const boost::filesystem::path &properties_path)
{
boost::filesystem::ifstream in_stream(properties_path);
if (!in_stream)
{
throw util::exception("Could not open " + properties_path.string() + " for reading.");
}
in_stream.read(reinterpret_cast<char*>(&m_profile_properties), sizeof(m_profile_properties));
}
void LoadTimestamp(const boost::filesystem::path &timestamp_path)
{
util::SimpleLogger().Write() << "Loading Timestamp";
boost::filesystem::ifstream timestamp_stream(timestamp_path);
if (!timestamp_stream)
if (boost::filesystem::exists(timestamp_path))
{
throw util::exception("Could not open " + timestamp_path.string() + " for reading.");
util::SimpleLogger().Write() << "Loading Timestamp";
boost::filesystem::ifstream timestamp_stream(timestamp_path);
if (!timestamp_stream)
{
util::SimpleLogger().Write(logWARNING) << timestamp_path << " not found";
}
getline(timestamp_stream, m_timestamp);
}
if (m_timestamp.empty())
{
m_timestamp = "n/a";
}
if (25 < m_timestamp.length())
{
m_timestamp.resize(25);
}
getline(timestamp_stream, m_timestamp);
}
void LoadGraph(const boost::filesystem::path &hsgr_path)
@@ -220,33 +218,28 @@ class InternalDataFacade final : public BaseDataFacade
void LoadDatasourceInfo(const boost::filesystem::path &datasource_names_file,
const boost::filesystem::path &datasource_indexes_file)
{
boost::filesystem::ifstream datasources_stream(datasource_indexes_file, std::ios::binary);
if (!datasources_stream)
std::ifstream datasources_stream(datasource_indexes_file.c_str(), std::ios::binary);
if (datasources_stream)
{
throw util::exception("Could not open " + datasource_indexes_file.string() + " for reading!");
}
BOOST_ASSERT(datasources_stream);
std::size_t number_of_datasources = 0;
datasources_stream.read(reinterpret_cast<char *>(&number_of_datasources),
sizeof(std::size_t));
if (number_of_datasources > 0)
{
m_datasource_list.resize(number_of_datasources);
datasources_stream.read(reinterpret_cast<char *>(&(m_datasource_list[0])),
number_of_datasources * sizeof(uint8_t));
std::size_t number_of_datasources = 0;
datasources_stream.read(reinterpret_cast<char *>(&number_of_datasources),
sizeof(std::size_t));
if (number_of_datasources > 0)
{
m_datasource_list.resize(number_of_datasources);
datasources_stream.read(reinterpret_cast<char *>(&(m_datasource_list[0])),
number_of_datasources * sizeof(uint8_t));
}
}
boost::filesystem::ifstream datasourcenames_stream(datasource_names_file, std::ios::binary);
if (!datasourcenames_stream)
std::ifstream datasourcenames_stream(datasource_names_file.c_str(), std::ios::binary);
if (datasourcenames_stream)
{
throw util::exception("Could not open " + datasource_names_file.string() + " for reading!");
}
BOOST_ASSERT(datasourcenames_stream);
std::string name;
while (std::getline(datasourcenames_stream, name))
{
m_datasource_names.push_back(std::move(name));
std::string name;
while (std::getline(datasourcenames_stream, name))
{
m_datasource_names.push_back(name);
}
}
}
@@ -283,35 +276,52 @@ class InternalDataFacade final : public BaseDataFacade
m_geospatial_query.reset();
}
explicit InternalDataFacade(const storage::StorageConfig& config)
explicit InternalDataFacade(
const std::unordered_map<std::string, boost::filesystem::path> &server_paths)
{
ram_index_path = config.ram_index_path;
file_index_path = config.file_index_path;
// cache end iterator to quickly check .find against
const auto end_it = end(server_paths);
const auto file_for = [&server_paths, &end_it](const std::string &path)
{
const auto it = server_paths.find(path);
if (it == end_it || !boost::filesystem::is_regular_file(it->second))
throw util::exception("no valid " + path + " file given in ini file");
return it->second;
};
const auto optional_file_for = [&server_paths, &end_it](const std::string &path)
{
const auto it = server_paths.find(path);
if (it == end_it)
throw util::exception("no valid " + path + " file given in ini file");
return it->second;
};
ram_index_path = file_for("ramindex");
file_index_path = file_for("fileindex");
util::SimpleLogger().Write() << "loading graph data";
LoadGraph(config.hsgr_data_path);
LoadGraph(file_for("hsgrdata"));
util::SimpleLogger().Write() << "loading edge information";
LoadNodeAndEdgeInformation(config.nodes_data_path, config.edges_data_path);
LoadNodeAndEdgeInformation(file_for("nodesdata"), file_for("edgesdata"));
util::SimpleLogger().Write() << "loading core information";
LoadCoreInformation(config.core_data_path);
LoadCoreInformation(file_for("coredata"));
util::SimpleLogger().Write() << "loading geometries";
LoadGeometries(config.geometries_path);
LoadGeometries(file_for("geometries"));
util::SimpleLogger().Write() << "loading datasource info";
LoadDatasourceInfo(config.datasource_names_path,
config.datasource_indexes_path);
LoadDatasourceInfo(optional_file_for("datasource_names"),
optional_file_for("datasource_indexes"));
util::SimpleLogger().Write() << "loading timestamp";
LoadTimestamp(config.timestamp_path);
util::SimpleLogger().Write() << "loading profile properties";
LoadProfileProperties(config.properties_path);
LoadTimestamp(file_for("timestamp"));
util::SimpleLogger().Write() << "loading street names";
LoadStreetNames(config.names_data_path);
LoadStreetNames(file_for("namesdata"));
}
// search graph access
@@ -642,14 +652,16 @@ class InternalDataFacade final : public BaseDataFacade
virtual std::string GetDatasourceName(const uint8_t datasource_name_id) const override final
{
BOOST_ASSERT(m_datasource_names.size() >= 1);
BOOST_ASSERT(m_datasource_names.size() > datasource_name_id);
if (m_datasource_names.empty() || datasource_name_id > m_datasource_names.size())
{
if (datasource_name_id == 0)
return "lua profile";
return "UNKNOWN";
}
return m_datasource_names[datasource_name_id];
}
std::string GetTimestamp() const override final { return m_timestamp; }
bool GetUTurnsDefault() const override final { return m_profile_properties.allow_u_turn_at_via; }
};
}
}
@@ -8,7 +8,6 @@
#include "storage/shared_memory.hpp"
#include "extractor/guidance/turn_instruction.hpp"
#include "extractor/profile_properties.hpp"
#include "engine/geospatial_query.hpp"
#include "util/range_table.hpp"
@@ -69,7 +68,6 @@ class SharedDataFacade final : public BaseDataFacade
std::unique_ptr<storage::SharedMemory> m_layout_memory;
std::unique_ptr<storage::SharedMemory> m_large_memory;
std::string m_timestamp;
extractor::ProfileProperties* m_profile_properties;
std::shared_ptr<util::ShM<util::Coordinate, true>::vector> m_coordinate_list;
util::ShM<NodeID, true>::vector m_via_node_list;
@@ -100,12 +98,6 @@ class SharedDataFacade final : public BaseDataFacade
util::SimpleLogger().Write() << "set checksum: " << m_check_sum;
}
void LoadProfileProperties()
{
m_profile_properties =
data_layout->GetBlockPtr<extractor::ProfileProperties>(shared_memory, storage::SharedDataLayout::PROPERTIES);
}
void LoadTimestamp()
{
auto timestamp_ptr =
@@ -351,7 +343,6 @@ class SharedDataFacade final : public BaseDataFacade
LoadViaNodeList();
LoadNames();
LoadCoreInformation();
LoadProfileProperties();
util::SimpleLogger().Write() << "number of geometries: "
<< m_coordinate_list->size();
@@ -693,11 +684,16 @@ class SharedDataFacade final : public BaseDataFacade
virtual std::string GetDatasourceName(const uint8_t datasource_name_id) const override final
{
BOOST_ASSERT(m_datasource_name_offsets.size() >= 1);
BOOST_ASSERT(m_datasource_name_offsets.size() > datasource_name_id);
std::string result;
result.reserve(m_datasource_name_lengths[datasource_name_id]);
if (m_datasource_name_offsets.empty() ||
datasource_name_id > m_datasource_name_offsets.size())
{
if (datasource_name_id == 0)
return "lua profile";
return "UNKNOWN";
}
std::copy(m_datasource_name_data.begin() + m_datasource_name_offsets[datasource_name_id],
m_datasource_name_data.begin() + m_datasource_name_offsets[datasource_name_id] +
m_datasource_name_lengths[datasource_name_id],
@@ -707,8 +703,6 @@ class SharedDataFacade final : public BaseDataFacade
}
std::string GetTimestamp() const override final { return m_timestamp; }
bool GetUTurnsDefault() const override final { return m_profile_properties->allow_u_turn_at_via; }
};
}
}
+18 -4
View File
@@ -28,10 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ENGINE_CONFIG_HPP
#define ENGINE_CONFIG_HPP
#include "storage/storage_config.hpp"
#include <boost/filesystem/path.hpp>
#include <unordered_map>
#include <string>
namespace osrm
@@ -42,9 +41,24 @@ namespace engine
struct EngineConfig
{
bool IsValid() const;
EngineConfig() = default;
storage::StorageConfig storage_config;
EngineConfig(const boost::filesystem::path &base)
: server_paths{{"ramindex", base.string() + ".ramIndex"},
{"fileindex", base.string() + ".fileIndex"},
{"hsgrdata", base.string() + ".hsgr"},
{"nodesdata", base.string() + ".nodes"},
{"edgesdata", base.string() + ".edges"},
{"coredata", base.string() + ".core"},
{"geometries", base.string() + ".geometry"},
{"timestamp", base.string() + ".timestamp"},
{"datasource_names", base.string() + ".datasource_names"},
{"datasource_indexes", base.string() + ".datasource_indexes"},
{"namesdata", base.string() + ".names"}}
{
}
std::unordered_map<std::string, boost::filesystem::path> server_paths;
int max_locations_trip = -1;
int max_locations_viaroute = -1;
int max_locations_distance_table = -1;
@@ -51,8 +51,7 @@ LegGeometry assembleGeometry(const DataFacadeT &facade,
current_distance +=
util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate);
// all changes to this check have to be matched with assemble_steps
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
if (!isSilent(path_point.turn_instruction))
{
geometry.segment_distances.push_back(current_distance);
geometry.segment_offsets.push_back(geometry.locations.size());
+32 -28
View File
@@ -24,14 +24,11 @@ namespace guidance
{
namespace detail
{
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const LegGeometry &leg_geometry,
const std::size_t segment_index);
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const WaypointType waypoint_type,
const LegGeometry &leg_geometry);
const LegGeometry &leg_geometry,
const std::size_t segment_index,
const unsigned exit);
} // ns detail
template <typename DataFacadeT>
@@ -43,7 +40,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
const bool source_traversed_in_reverse,
const bool target_traversed_in_reverse)
{
const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0.;
const double constexpr ZERO_DURACTION = 0., ZERO_DISTANCE = 0., NO_BEARING = 0.;
const EdgeWeight source_duration =
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
const auto source_mode = source_traversed_in_reverse ? source_node.backward_travel_mode
@@ -71,7 +68,8 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
distance_to_start >= MINIMAL_RELATIVE_DISTANCE &&
distance_to_start <= MAXIMAL_RELATIVE_DISTANCE
? angleToDirectionModifier(util::coordinate_calculation::computeAngle(
source_node.input_location, leg_geometry.locations[0], leg_geometry.locations[1]))
source_node.input_location, leg_geometry.locations[0],
leg_geometry.locations[1]))
: extractor::guidance::DirectionModifier::UTurn;
if (leg_data.size() > 0)
@@ -80,8 +78,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
StepManeuver maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction{extractor::guidance::TurnType::NoTurn,
initial_modifier},
WaypointType::Depart, leg_geometry);
maneuver.location = source_node.location;
WaypointType::Depart, leg_geometry, segment_index, INVALID_EXIT_NR);
// PathData saves the information we need of the segment _before_ the turn,
// but a RouteStep is with regard to the segment after the turn.
@@ -92,8 +89,7 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
{
segment_duration += path_point.duration_until_turn;
// all changes to this check have to be matched with assemble_geometry
if (path_point.turn_instruction.type != extractor::guidance::TurnType::NoTurn)
if (path_point.turn_instruction != extractor::guidance::TurnInstruction::NO_TURN())
{
BOOST_ASSERT(segment_duration >= 0);
const auto name = facade.GetNameForID(path_point.name_id);
@@ -107,7 +103,8 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1});
maneuver = detail::stepManeuverFromGeometry(path_point.turn_instruction,
leg_geometry, segment_index);
WaypointType::None, leg_geometry,
segment_index, path_point.exit);
segment_index++;
segment_duration = 0;
}
@@ -133,10 +130,13 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
// |---| source_duration
// |---------| target_duration
StepManeuver maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction{extractor::guidance::TurnType::NoTurn,
initial_modifier},
WaypointType::Depart, leg_geometry);
StepManeuver maneuver = {source_node.location,
NO_BEARING,
NO_BEARING,
extractor::guidance::TurnInstruction{
extractor::guidance::TurnType::NoTurn, initial_modifier},
WaypointType::Depart,
INVALID_EXIT_NR};
int duration = target_duration - source_duration;
BOOST_ASSERT(duration >= 0);
@@ -162,17 +162,21 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
target_node.input_location))
: extractor::guidance::DirectionModifier::UTurn;
// This step has length zero, the only reason we need it is the target location
auto final_maneuver = detail::stepManeuverFromGeometry(
extractor::guidance::TurnInstruction{extractor::guidance::TurnType::NoTurn, final_modifier},
WaypointType::Arrive, leg_geometry);
steps.push_back(RouteStep{target_node.name_id,
facade.GetNameForID(target_node.name_id),
ZERO_DURATION,
ZERO_DISTANCE,
target_mode,
final_maneuver,
leg_geometry.locations.size(),
leg_geometry.locations.size()});
steps.push_back(
RouteStep{target_node.name_id,
facade.GetNameForID(target_node.name_id),
ZERO_DURACTION,
ZERO_DISTANCE,
target_mode,
StepManeuver{target_node.location,
NO_BEARING,
NO_BEARING,
extractor::guidance::TurnInstruction{
extractor::guidance::TurnType::NoTurn, final_modifier},
WaypointType::Arrive,
INVALID_EXIT_NR},
leg_geometry.locations.size(),
leg_geometry.locations.size()});
return steps;
}
+2 -11
View File
@@ -1,8 +1,7 @@
#ifndef ENGINE_GUIDANCE_POST_PROCESSING_HPP
#define ENGINE_GUIDANCE_POST_PROCESSING_HPP
#include "engine/guidance/route_step.hpp"
#include "engine/guidance/leg_geometry.hpp"
#include "engine/internal_route_result.hpp"
#include <vector>
@@ -13,15 +12,7 @@ namespace engine
namespace guidance
{
// passed as none-reference to modify in-place and move out again
std::vector<RouteStep> postProcess(std::vector<RouteStep> steps);
// postProcess will break the connection between the leg geometry
// for which a segment is supposed to represent exactly the coordinates
// between routing maneuvers and the route steps itself.
// If required, we can get both in sync again using this function.
// Move in LegGeometry for modification in place.
LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep> &steps);
std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>> path_data);
} // namespace guidance
} // namespace engine
-10
View File
@@ -5,7 +5,6 @@
#include "extractor/guidance/turn_instruction.hpp"
#include <cstdint>
#include <vector>
namespace osrm
{
@@ -21,14 +20,6 @@ enum class WaypointType : std::uint8_t
Depart,
};
//A represenetation of intermediate intersections
struct IntermediateIntersection
{
double duration;
double distance;
util::Coordinate location;
};
struct StepManeuver
{
util::Coordinate location;
@@ -37,7 +28,6 @@ struct StepManeuver
extractor::guidance::TurnInstruction instruction;
WaypointType waypoint_type;
unsigned exit;
std::vector<IntermediateIntersection> intersections;
};
} // namespace guidance
} // namespace engine
+7 -15
View File
@@ -34,44 +34,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <cstdint>
#include <iosfwd>
namespace osrm
{
namespace engine
{
// Fwd. decls.
namespace datafacade
{
struct BaseDataFacade;
}
// Is returned as a temporary identifier for snapped coodinates
struct Hint
{
PhantomNode phantom;
std::uint32_t data_checksum;
bool IsValid(const util::Coordinate new_input_coordinates,
const datafacade::BaseDataFacade &facade) const;
template <typename DataFacadeT>
bool IsValid(const util::Coordinate new_input_coordinates, DataFacadeT &facade) const
{
return phantom.IsValid(facade.GetNumberOfNodes(), new_input_coordinates) &&
facade.GetCheckSum() == data_checksum;
}
std::string ToBase64() const;
static Hint FromBase64(const std::string &base64Hint);
friend bool operator==(const Hint &, const Hint &);
friend std::ostream &operator<<(std::ostream &, const Hint &);
};
#ifndef _MSC_VER
static_assert(sizeof(Hint) == 60 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 88;
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
"ENCODED_HINT_SIZE does not match size of Hint");
#else
// PhantomNode is bigger under windows because MSVC does not support bit packing
static_assert(sizeof(Hint) == 64 + 4, "Hint is bigger than expected");
constexpr std::size_t ENCODED_HINT_SIZE = 92;
constexpr std::size_t ENCODED_HINT_SIZE = 84;
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
"ENCODED_HINT_SIZE does not match size of Hint");
#endif
+2
View File
@@ -29,6 +29,8 @@ struct PathData
extractor::guidance::TurnInstruction turn_instruction;
// travel mode of the street that leads to the turn
extractor::TravelMode travel_mode : 4;
// exit ID of highway exit, roundabout exit, intersection nr
unsigned exit;
};
struct InternalRouteResult
+91
View File
@@ -0,0 +1,91 @@
#ifndef OBJECT_ENCODER_HPP
#define OBJECT_ENCODER_HPP
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
#include <cstdint>
#include <climits>
namespace osrm
{
namespace engine
{
namespace detail
{
static_assert(CHAR_BIT == 8u, "we assume a byte holds 8 bits");
static_assert(sizeof(char) == 1u, "we assume a char is one byte large");
using Base64FromBinary = boost::archive::iterators::base64_from_binary<
boost::archive::iterators::transform_width<const char *, // sequence of chars
6, // get view of 6 bit
8 // from sequence of 8 bit
>>;
using BinaryFromBase64 = boost::archive::iterators::transform_width<
boost::archive::iterators::binary_from_base64<std::string::const_iterator>,
8, // get a view of 8 bit
6 // from a sequence of 6 bit
>;
} // ns detail
template <typename T> std::string encodeBase64(const T &x)
{
#if not defined __GNUC__ or __GNUC__ > 4
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
std::vector<unsigned char> bytes{reinterpret_cast<const char *>(&x),
reinterpret_cast<const char *>(&x) + sizeof(T)};
BOOST_ASSERT(!bytes.empty());
std::size_t bytes_to_pad{0};
while (bytes.size() % 3 != 0)
{
bytes_to_pad += 1;
bytes.push_back(0);
}
BOOST_ASSERT(bytes_to_pad == 0 || bytes_to_pad == 1 || bytes_to_pad == 2);
BOOST_ASSERT_MSG(0 == bytes.size() % 3, "base64 input data size is not a multiple of 3");
std::string encoded{detail::Base64FromBinary{bytes.data()},
detail::Base64FromBinary{bytes.data() + (bytes.size() - bytes_to_pad)}};
std::replace(begin(encoded), end(encoded), '+', '-');
std::replace(begin(encoded), end(encoded), '/', '_');
return encoded;
}
template <typename T> T decodeBase64(std::string encoded)
{
#if not defined __GNUC__ or __GNUC__ > 4
static_assert(std::is_trivially_copyable<T>::value, "requires a trivially copyable type");
#endif
std::replace(begin(encoded), end(encoded), '-', '+');
std::replace(begin(encoded), end(encoded), '_', '/');
T rv;
std::copy(detail::BinaryFromBase64{begin(encoded)},
detail::BinaryFromBase64{begin(encoded) + encoded.length()},
reinterpret_cast<char *>(&rv));
return rv;
}
} // ns engine
} // ns osrm
#endif /* OBJECT_ENCODER_HPP */
-2
View File
@@ -187,8 +187,6 @@ struct PhantomNode
#ifndef _MSC_VER
static_assert(sizeof(PhantomNode) == 60, "PhantomNode has more padding then expected");
#else
static_assert(sizeof(PhantomNode) == 64, "PhantomNode has more padding then expected");
#endif
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
+1
View File
@@ -5,6 +5,7 @@
#include "engine/plugins/plugin_base.hpp"
#include "engine/api/route_api.hpp"
#include "engine/object_encoder.hpp"
#include "engine/search_engine_data.hpp"
#include "engine/routing_algorithms/shortest_path.hpp"
#include "engine/routing_algorithms/alternative_path.hpp"
@@ -321,7 +321,8 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
{
unpacked_path.push_back(
PathData{id_vector[i], name_index, weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(), travel_mode});
extractor::guidance::TurnInstruction::NO_TURN(), travel_mode,
INVALID_EXIT_NR});
}
BOOST_ASSERT(unpacked_path.size() > 0);
unpacked_path.back().turn_instruction = turn_instruction;
@@ -395,7 +396,8 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
id_vector[i], phantom_node_pair.target_phantom.name_id, weight_vector[i],
extractor::guidance::TurnInstruction::NO_TURN(),
target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode
: phantom_node_pair.target_phantom.forward_travel_mode});
: phantom_node_pair.target_phantom.forward_travel_mode,
INVALID_EXIT_NR});
}
if (is_local_path && unpacked_path.size() > 0)
@@ -237,10 +237,14 @@ class ShortestPathRouting final
}
}
static const constexpr bool UTURN_DEFAULT = false;
void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector,
const boost::optional<bool> uturns,
const std::vector<boost::optional<bool>> &uturn_indicators,
InternalRouteResult &raw_route_data) const
{
BOOST_ASSERT(uturn_indicators.empty() ||
uturn_indicators.size() == phantom_nodes_vector.size() + 1);
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes());
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
@@ -266,7 +270,7 @@ class ShortestPathRouting final
std::vector<NodeID> total_packed_path_to_reverse;
std::vector<std::size_t> packed_leg_to_reverse_begin;
const bool allow_u_turn_at_via = uturns ? *uturns : super::facade->GetUTurnsDefault();
const bool use_uturn_indicators = !uturn_indicators.empty();
std::size_t current_leg = 0;
// this implements a dynamic program that finds the shortest route through
@@ -282,6 +286,12 @@ class ShortestPathRouting final
const auto &source_phantom = phantom_node_pair.source_phantom;
const auto &target_phantom = phantom_node_pair.target_phantom;
const bool use_uturn_default =
!use_uturn_indicators || !uturn_indicators[current_leg + 1];
const bool allow_u_turn_at_via =
(use_uturn_default && UTURN_DEFAULT) ||
(!use_uturn_default && *uturn_indicators[current_leg + 1]);
bool search_to_forward_node = target_phantom.forward_node_id != SPECIAL_NODEID;
bool search_to_reverse_node = target_phantom.reverse_node_id != SPECIAL_NODEID;
@@ -4,7 +4,7 @@
#define EDGE_BASED_GRAPH_FACTORY_HPP_
#include "extractor/edge_based_edge.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/speed_profile.hpp"
#include "extractor/restriction_map.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "extractor/edge_based_node.hpp"
@@ -52,7 +52,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<QueryNode> &node_info_list,
ProfileProperties profile_properties,
SpeedProfileProperties speed_profile,
const util::NameTable &name_table);
void Run(const std::string &original_edge_data_filename,
@@ -106,7 +106,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &m_traffic_lights;
const CompressedEdgeContainer &m_compressed_edge_container;
ProfileProperties profile_properties;
SpeedProfileProperties speed_profile;
const util::NameTable &name_table;
+2 -6
View File
@@ -40,8 +40,6 @@ namespace osrm
namespace extractor
{
struct ProfileProperties;
class Extractor
{
public:
@@ -51,15 +49,13 @@ class Extractor
private:
ExtractorConfig config;
void SetupScriptingEnvironment(lua_State *myLuaState, SpeedProfileProperties &speed_profile);
std::pair<std::size_t, std::size_t>
BuildEdgeExpandedGraph(lua_State* lua_state,
const ProfileProperties& profile_properties,
std::vector<QueryNode> &internal_to_external_node_map,
BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list);
void WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const;
void WriteNodeMapping(const std::vector<QueryNode> &internal_to_external_node_map);
void FindComponents(unsigned max_edge_id,
const util::DeallocatingVector<EdgeBasedEdge> &edges,
-2
View File
@@ -71,7 +71,6 @@ struct ExtractorConfig
edge_segment_lookup_path = basepath + ".osrm.edge_segment_lookup";
edge_penalty_path = basepath + ".osrm.edge_penalties";
edge_based_node_weights_output_path = basepath + ".osrm.enw";
profile_properties_output_path = basepath + ".osrm.properties";
}
boost::filesystem::path config_file_path;
@@ -89,7 +88,6 @@ struct ExtractorConfig
std::string node_output_path;
std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path;
std::string profile_properties_output_path;
unsigned requested_num_threads;
unsigned small_component_size;
+5
View File
@@ -3,6 +3,7 @@
#include "util/typedefs.hpp"
#include "extractor/speed_profile.hpp"
#include "util/node_based_graph.hpp"
#include <memory>
@@ -21,6 +22,8 @@ class GraphCompressor
using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
public:
GraphCompressor(SpeedProfileProperties speed_profile);
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_lights,
RestrictionMap &restriction_map,
@@ -31,6 +34,8 @@ class GraphCompressor
void PrintStatistics(unsigned original_number_of_nodes,
unsigned original_number_of_edges,
const util::NodeBasedDynamicGraph &graph) const;
SpeedProfileProperties speed_profile;
};
}
}
-48
View File
@@ -1,48 +0,0 @@
#ifndef PROFILE_PROPERTIES_HPP
#define PROFILE_PROPERTIES_HPP
#include <boost/numeric/conversion/cast.hpp>
namespace osrm
{
namespace extractor
{
struct ProfileProperties
{
ProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0), allow_u_turn_at_via(false), use_turn_restrictions(false)
{
}
double GetUturnPenalty() const
{
return u_turn_penalty / 10.;
}
void SetUturnPenalty(const double u_turn_penalty_)
{
u_turn_penalty = boost::numeric_cast<int>(u_turn_penalty_ * 10.);
}
double GetTrafficSignalPenalty() const
{
return traffic_signal_penalty / 10.;
}
void SetTrafficSignalPenalty(const double traffic_signal_penalty_)
{
traffic_signal_penalty = boost::numeric_cast<int>(traffic_signal_penalty_ * 10.);
}
//! penalty to cross a traffic light in deci-seconds
int traffic_signal_penalty;
//! penalty to do a uturn in deci-seconds
int u_turn_penalty;
bool allow_u_turn_at_via;
bool use_turn_restrictions;
};
}
}
#endif
+2 -3
View File
@@ -19,8 +19,6 @@ namespace osrm
namespace extractor
{
class ProfileProperties;
/**
* Parses the relations that represents turn restrictions.
*
@@ -42,10 +40,11 @@ class ProfileProperties;
class RestrictionParser
{
public:
RestrictionParser(lua_State *lua_state, const ProfileProperties& properties);
RestrictionParser(lua_State *lua_state);
boost::optional<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const;
private:
void ReadUseRestrictionsSetting(lua_State *lua_state);
void ReadRestrictionExceptions(lua_State *lua_state);
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
+3 -15
View File
@@ -1,11 +1,6 @@
#ifndef SCRIPTING_ENVIRONMENT_HPP
#define SCRIPTING_ENVIRONMENT_HPP
#include "extractor/profile_properties.hpp"
#include "extractor/raster_source.hpp"
#include "util/lua_util.hpp"
#include <string>
#include <memory>
#include <mutex>
@@ -28,25 +23,18 @@ namespace extractor
class ScriptingEnvironment
{
public:
struct Context
{
ProfileProperties properties;
SourceContainer sources;
util::LuaState state;
};
explicit ScriptingEnvironment(const std::string &file_name);
ScriptingEnvironment(const ScriptingEnvironment &) = delete;
ScriptingEnvironment &operator=(const ScriptingEnvironment &) = delete;
Context &GetContex();
lua_State *GetLuaState();
private:
void InitContext(Context &context);
void InitLuaState(lua_State *lua_state);
std::mutex init_mutex;
std::string file_name;
tbb::enumerable_thread_specific<std::unique_ptr<Context>> script_contexts;
tbb::enumerable_thread_specific<std::shared_ptr<lua_State>> script_contexts;
};
}
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef SPEED_PROFILE_PROPERTIES_HPP
#define SPEED_PROFILE_PROPERTIES_HPP
namespace osrm
{
namespace extractor
{
struct SpeedProfileProperties
{
SpeedProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0), has_turn_penalty_function(false)
{
}
int traffic_signal_penalty;
int u_turn_penalty;
bool has_turn_penalty_function;
};
}
}
#endif
-38
View File
@@ -1,38 +0,0 @@
/*
Copyright (c) 2016, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GLOBAL_STORAGE_CONFIG_HPP
#define GLOBAL_STORAGE_CONFIG_HPP
#include "storage/storage_config.hpp"
namespace osrm
{
using storage::StorageConfig;
}
#endif
@@ -27,7 +27,7 @@ struct RouteParametersGrammar : public BaseParametersGrammar
using AlternativeT = bool;
using GeometriesT = engine::api::RouteParameters::GeometriesType;
using OverviewT = engine::api::RouteParameters::OverviewType;
using UturnsT = bool;
using UturnsT = std::vector<boost::optional<bool>>;
RouteParametersGrammar() : BaseParametersGrammar(root_rule, parameters)
{
@@ -72,9 +72,9 @@ struct RouteParametersGrammar : public BaseParametersGrammar
overview_rule = qi::lit("overview=simplified")[set_simplified_type] |
qi::lit("overview=full")[set_full_type] |
qi::lit("overview=false")[set_false_type];
uturns_rule = qi::lit("uturns=default") | (qi::lit("uturns=") >> qi::bool_)[set_uturns];
uturns_rule = qi::lit("uturns=") >> -qi::bool_ % ";";
route_rule = steps_rule[set_steps] | alternatives_rule[set_alternatives] | geometries_rule |
overview_rule | uturns_rule;
overview_rule | uturns_rule[set_uturns];
root_rule =
query_rule >> -qi::lit(".json") >> -(qi::lit("?") >> (route_rule | base_rule) % '&');
-1
View File
@@ -41,7 +41,6 @@ struct SharedDataLayout
DATASOURCE_NAME_DATA,
DATASOURCE_NAME_OFFSETS,
DATASOURCE_NAME_LENGTHS,
PROPERTIES,
NUM_BLOCKS
};
+4 -4
View File
@@ -1,24 +1,24 @@
#ifndef STORAGE_HPP
#define STORAGE_HPP
#include "storage/storage_config.hpp"
#include <boost/filesystem/path.hpp>
#include <unordered_map>
#include <string>
namespace osrm
{
namespace storage
{
using DataPaths = std::unordered_map<std::string, boost::filesystem::path>;
class Storage
{
public:
Storage(StorageConfig config);
Storage(const DataPaths &data_paths);
int Run();
private:
StorageConfig config;
DataPaths paths;
};
}
}
-32
View File
@@ -1,32 +0,0 @@
#ifndef STORAGE_CONFIG_HPP
#define STORAGE_CONFIG_HPP
#include <boost/filesystem/path.hpp>
namespace osrm
{
namespace storage
{
struct StorageConfig
{
StorageConfig() = default;
StorageConfig(const boost::filesystem::path &base);
bool IsValid() const;
boost::filesystem::path ram_index_path;
boost::filesystem::path file_index_path;
boost::filesystem::path hsgr_data_path;
boost::filesystem::path nodes_data_path;
boost::filesystem::path edges_data_path;
boost::filesystem::path core_data_path;
boost::filesystem::path geometries_path;
boost::filesystem::path timestamp_path;
boost::filesystem::path datasource_names_path;
boost::filesystem::path datasource_indexes_path;
boost::filesystem::path names_data_path;
boost::filesystem::path properties_path;
};
}
}
#endif
+2 -11
View File
@@ -18,19 +18,10 @@ namespace osrm
namespace util
{
struct LuaState
{
LuaState() : handle{::luaL_newstate(), &::lua_close} { luaL_openlibs(*this); }
operator lua_State *() { return handle.get(); }
operator lua_State const *() const { return handle.get(); }
using handle_type = std::unique_ptr<lua_State, decltype(&::lua_close)>;
handle_type handle;
};
template <typename T> void LUA_print(T output) { std::cout << "[LUA] " << output << std::endl; }
// Check if the lua function <name> is defined
inline bool luaFunctionExists(lua_State *lua_state, const char *name)
inline bool lua_function_exists(lua_State *lua_state, const char *name)
{
luabind::object globals_table = luabind::globals(lua_state);
luabind::object lua_function = globals_table[name];
+251
View File
@@ -0,0 +1,251 @@
#ifndef ROUTED_OPTIONS_HPP
#define ROUTED_OPTIONS_HPP
#include "util/version.hpp"
#include "util/exception.hpp"
#include "util/simple_logger.hpp"
#include <boost/any.hpp>
#include <boost/program_options.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/convenience.hpp>
#include <unordered_map>
#include <fstream>
#include <string>
namespace osrm
{
namespace util
{
const static unsigned INIT_OK_START_ENGINE = 0;
const static unsigned INIT_OK_DO_NOT_START_ENGINE = 1;
const static unsigned INIT_FAILED = -1;
inline void
populate_base_path(std::unordered_map<std::string, boost::filesystem::path> &server_paths)
{
// populate the server_path object
auto path_iterator = server_paths.find("base");
// if a base path has been set, we populate it.
if (path_iterator != server_paths.end())
{
const std::string base_string = path_iterator->second.string();
SimpleLogger().Write() << "populating base path: " << base_string;
server_paths["hsgrdata"] = base_string + ".hsgr";
BOOST_ASSERT(server_paths.find("hsgrdata") != server_paths.end());
server_paths["nodesdata"] = base_string + ".nodes";
BOOST_ASSERT(server_paths.find("nodesdata") != server_paths.end());
server_paths["coredata"] = base_string + ".core";
BOOST_ASSERT(server_paths.find("coredata") != server_paths.end());
server_paths["edgesdata"] = base_string + ".edges";
BOOST_ASSERT(server_paths.find("edgesdata") != server_paths.end());
server_paths["geometries"] = base_string + ".geometry";
BOOST_ASSERT(server_paths.find("geometries") != server_paths.end());
server_paths["ramindex"] = base_string + ".ramIndex";
BOOST_ASSERT(server_paths.find("ramindex") != server_paths.end());
server_paths["fileindex"] = base_string + ".fileIndex";
BOOST_ASSERT(server_paths.find("fileindex") != server_paths.end());
server_paths["namesdata"] = base_string + ".names";
BOOST_ASSERT(server_paths.find("namesdata") != server_paths.end());
server_paths["timestamp"] = base_string + ".timestamp";
BOOST_ASSERT(server_paths.find("timestamp") != server_paths.end());
server_paths["datasource_indexes"] = base_string + ".datasource_indexes";
BOOST_ASSERT(server_paths.find("timestamp") != server_paths.end());
server_paths["datasource_names"] = base_string + ".datasource_names";
BOOST_ASSERT(server_paths.find("timestamp") != server_paths.end());
}
// check if files are give and whether they exist at all
path_iterator = server_paths.find("hsgrdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".hsgr not found");
}
path_iterator = server_paths.find("nodesdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".nodes not found");
}
path_iterator = server_paths.find("edgesdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".edges not found");
}
path_iterator = server_paths.find("geometries");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".geometry not found");
}
path_iterator = server_paths.find("ramindex");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".ramIndex not found");
}
path_iterator = server_paths.find("fileindex");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".fileIndex not found");
}
path_iterator = server_paths.find("namesdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw exception(".namesIndex not found");
}
SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"];
SimpleLogger().Write(logDEBUG) << "Nodes file:\t" << server_paths["nodesdata"];
SimpleLogger().Write(logDEBUG) << "Edges file:\t" << server_paths["edgesdata"];
SimpleLogger().Write(logDEBUG) << "Geometry file:\t" << server_paths["geometries"];
SimpleLogger().Write(logDEBUG) << "RAM file:\t" << server_paths["ramindex"];
SimpleLogger().Write(logDEBUG) << "Index file:\t" << server_paths["fileindex"];
SimpleLogger().Write(logDEBUG) << "Names file:\t" << server_paths["namesdata"];
SimpleLogger().Write(logDEBUG) << "Timestamp file:\t" << server_paths["timestamp"];
}
// generate boost::program_options object for the routing part
inline unsigned
GenerateServerProgramOptions(const int argc,
const char *argv[],
std::unordered_map<std::string, boost::filesystem::path> &paths,
std::string &ip_address,
int &ip_port,
int &requested_num_threads,
bool &use_shared_memory,
bool &trial,
int &max_locations_trip,
int &max_locations_viaroute,
int &max_locations_distance_table,
int &max_locations_map_matching)
{
using boost::program_options::value;
using boost::filesystem::path;
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options() //
("version,v", "Show version")("help,h", "Show this help message") //
("config,c", value<boost::filesystem::path>(&paths["config"])->default_value("server.ini"),
"Path to a configuration file") //
("trial", value<bool>(&trial)->implicit_value(true), "Quit after initialization");
// declare a group of options that will be allowed on command line
boost::program_options::options_description config_options("Configuration");
config_options.add_options() //
("hsgrdata", value<boost::filesystem::path>(&paths["hsgrdata"]), ".hsgr file") //
("nodesdata", value<boost::filesystem::path>(&paths["nodesdata"]), ".nodes file") //
("edgesdata", value<boost::filesystem::path>(&paths["edgesdata"]), ".edges file") //
("geometry", value<boost::filesystem::path>(&paths["geometries"]), ".geometry file") //
("ramindex", value<boost::filesystem::path>(&paths["ramindex"]), ".ramIndex file") //
("fileindex", value<boost::filesystem::path>(&paths["fileindex"]),
"File index file") //
("namesdata", value<boost::filesystem::path>(&paths["namesdata"]),
".names file") //
("timestamp", value<boost::filesystem::path>(&paths["timestamp"]),
".timestamp file") //
("ip,i", value<std::string>(&ip_address)->default_value("0.0.0.0"),
"IP address") //
("port,p", value<int>(&ip_port)->default_value(5000),
"TCP/IP port") //
("threads,t", value<int>(&requested_num_threads)->default_value(8),
"Number of threads to use") //
("shared-memory,s",
value<bool>(&use_shared_memory)->implicit_value(true)->default_value(false),
"Load data from shared memory") //
("max-viaroute-size", value<int>(&max_locations_viaroute)->default_value(500),
"Max. locations supported in viaroute query") //
("max-trip-size", value<int>(&max_locations_trip)->default_value(100),
"Max. locations supported in trip query") //
("max-table-size", value<int>(&max_locations_distance_table)->default_value(100),
"Max. locations supported in distance table query") //
("max-matching-size", value<int>(&max_locations_map_matching)->default_value(100),
"Max. locations supported in map matching query");
// hidden options, will be allowed on command line, but will not be shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()("base,b", value<boost::filesystem::path>(&paths["base"]),
"base path to .osrm file");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("base", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
boost::filesystem::basename(argv[0]) + " <base.osrm> [<options>]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
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"))
{
SimpleLogger().Write() << OSRM_VERSION;
return INIT_OK_DO_NOT_START_ENGINE;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << visible_options;
return INIT_OK_DO_NOT_START_ENGINE;
}
boost::program_options::notify(option_variables);
if (1 > requested_num_threads)
{
throw exception("Number of threads must be a positive number");
}
if (2 > max_locations_distance_table)
{
throw exception("Max location for distance table must be at least two");
}
if (max_locations_map_matching > 0 && 2 > max_locations_map_matching)
{
throw exception("Max location for map matching must be at least two");
}
if (!use_shared_memory && option_variables.count("base"))
{
return INIT_OK_START_ENGINE;
}
else if (use_shared_memory && !option_variables.count("base"))
{
return INIT_OK_START_ENGINE;
}
else if (use_shared_memory && option_variables.count("base"))
{
SimpleLogger().Write(logWARNING) << "Shared memory settings conflict with path settings.";
}
SimpleLogger().Write() << visible_options;
return INIT_OK_DO_NOT_START_ENGINE;
}
}
}
#endif // ROUTED_OPTIONS_HPP
+3 -4
View File
@@ -91,10 +91,9 @@ surface_speeds = {
}
-- these need to be global because they are accesed externaly
properties.traffic_signal_penalty = 2
properties.use_turn_restrictions = false
properties.u_turn_penalty = 20
properties.allow_u_turn_at_via = true
traffic_signal_penalty = 2
use_turn_restrictions = false
u_turn_penalty = 20
local obey_oneway = true
local ignore_areas = true
+9 -9
View File
@@ -128,20 +128,20 @@ maxspeed_table = {
["uk:motorway"] = (70*1609)/1000
}
-- set profile properties
properties.u_turn_penalty = 20
properties.traffic_signal_penalty = 2
properties.use_turn_restrictions = true
-- these need to be global because they are accesed externaly
u_turn_penalty = 20
traffic_signal_penalty = 2
use_turn_restrictions = true
local side_road_speed_multiplier = 0.8
side_road_speed_multiplier = 0.8
local turn_penalty = 10
local turn_penalty = 10
-- Note: this biases right-side driving. Should be
-- inverted for left-driving countries.
local turn_bias = 1.2
local turn_bias = 1.2
local obey_oneway = true
local ignore_areas = true
local obey_oneway = true
local ignore_areas = true
local abs = math.abs
local min = math.min
+3 -5
View File
@@ -64,11 +64,9 @@ leisure_speeds = {
["track"] = walking_speed
}
properties.traffic_signal_penalty = 2
properties.u_turn_penalty = 2
properties.use_turn_restrictions = false
properties.allow_u_turn_at_via = true
traffic_signal_penalty = 2
u_turn_penalty = 2
use_turn_restrictions = false
local fallback_names = true
function get_exceptions(vector)
+4 -4
View File
@@ -32,15 +32,15 @@ end
function segment_function (source, target, distance, weight)
local sourceData = sources:interpolate(raster_source, source.lon, source.lat)
local targetData = sources:interpolate(raster_source, target.lon, target.lat)
io.write("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum .. "\n")
print ("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum)
local invalid = sourceData.invalid_data()
if sourceData.datum ~= invalid and targetData.datum ~= invalid then
local slope = math.abs(sourceData.datum - targetData.datum) / distance
io.write(" slope: " .. slope .. "\n")
io.write(" was speed: " .. weight.speed .. "\n")
print (" slope: " .. slope)
print (" was speed: " .. weight.speed)
weight.speed = weight.speed * (1 - (slope * 5))
io.write(" new speed: " .. weight.speed .. "\n")
print (" new speed: " .. weight.speed)
end
end
+4 -4
View File
@@ -32,15 +32,15 @@ end
function segment_function (source, target, distance, weight)
local sourceData = sources:query(raster_source, source.lon, source.lat)
local targetData = sources:query(raster_source, target.lon, target.lat)
io.write("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum .. "\n")
print ("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum)
local invalid = sourceData.invalid_data()
if sourceData.datum ~= invalid and targetData.datum ~= invalid then
local slope = math.abs(sourceData.datum - targetData.datum) / distance
io.write(" slope: " .. slope .. "\n")
io.write(" was speed: " .. weight.speed .. "\n")
print (" slope: " .. slope)
print (" was speed: " .. weight.speed)
weight.speed = weight.speed * (1 - (slope * 5))
io.write(" new speed: " .. weight.speed .. "\n")
print (" new speed: " .. weight.speed)
end
end
+7 -4
View File
@@ -16,10 +16,13 @@ speed_profile = {
-- these settings are read directly by osrm
properties.allow_u_turn_at_via = false
properties.use_turn_restrictions = true
properties.traffic_signal_penalty = 7 -- seconds
properties.u_turn_penalty = 20
take_minimum_of_speeds = true
obey_oneway = true
obey_barriers = true
use_turn_restrictions = true
ignore_areas = true -- future feature
traffic_signal_penalty = 7 -- seconds
u_turn_penalty = 20
function limit_speed(speed, limits)
-- don't use ipairs(), since it stops at the first nil value
+21 -28
View File
@@ -173,10 +173,6 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
std::unordered_map<std::pair<OSMNodeID, OSMNodeID>, std::pair<unsigned, uint8_t>>
segment_speed_lookup;
// If we update the edge weights, this file will hold the datasource information
// for each segment
std::vector<uint8_t> m_geometry_datasource;
if (update_edge_weights)
{
uint8_t file_id = 1;
@@ -268,7 +264,7 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
// CSV file that supplied the value that gets used for that segment, then
// we write out this list so that it can be returned by the debugging
// vector tiles later on.
m_geometry_datasource.resize(m_geometry_list.size(), 0);
std::vector<uint8_t> m_geometry_datasource(m_geometry_list.size(), 0);
// Now, we iterate over all the segments stored in the StaticRTree, updating
// the packed geometry weights in the `.geometries` file (note: we do not
@@ -406,36 +402,33 @@ std::size_t Contractor::LoadEdgeExpandedGraph(
number_of_compressed_geometries *
sizeof(extractor::CompressedEdgeContainer::CompressedEdge));
}
}
{
std::ofstream datasource_stream(datasource_indexes_filename, std::ios::binary);
if (!datasource_stream)
{
throw util::exception("Failed to open " + datasource_indexes_filename +
" for writing");
}
auto number_of_datasource_entries = m_geometry_datasource.size();
datasource_stream.write(reinterpret_cast<const char *>(&number_of_datasource_entries),
sizeof(number_of_datasource_entries));
if (number_of_datasource_entries > 0)
{
std::ofstream datasource_stream(datasource_indexes_filename, std::ios::binary);
if (!datasource_stream)
{
throw util::exception("Failed to open " + datasource_indexes_filename +
" for writing");
}
auto number_of_datasource_entries = m_geometry_datasource.size();
datasource_stream.write(reinterpret_cast<const char *>(&number_of_datasource_entries),
sizeof(number_of_datasource_entries));
datasource_stream.write(reinterpret_cast<char *>(&(m_geometry_datasource[0])),
number_of_datasource_entries * sizeof(uint8_t));
}
}
{
std::ofstream datasource_stream(datasource_names_filename, std::ios::binary);
if (!datasource_stream)
{
throw util::exception("Failed to open " + datasource_names_filename +
" for writing");
}
datasource_stream << "lua profile" << std::endl;
for (auto const &name : segment_speed_filenames)
{
datasource_stream << name << std::endl;
std::ofstream datasource_stream(datasource_names_filename, std::ios::binary);
if (!datasource_stream)
{
throw util::exception("Failed to open " + datasource_names_filename +
" for writing");
}
datasource_stream << "lua profile" << std::endl;
for (auto const &name : segment_speed_filenames)
{
datasource_stream << name << std::endl;
}
}
}
-6
View File
@@ -149,12 +149,6 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
step_maneuver.values["bearing_after"] = maneuver.bearing_after;
if (maneuver.exit != 0)
step_maneuver.values["exit"] = maneuver.exit;
// TODO currently we need this to comply with the api.
// We should move this to an additional entry, the moment we
// actually compute the correct locations of the intersections
if (!maneuver.intersections.empty() && maneuver.exit == 0)
step_maneuver.values["exit"] = maneuver.intersections.size();
return step_maneuver;
}
+3 -5
View File
@@ -18,6 +18,7 @@
#include "storage/shared_barriers.hpp"
#include "util/make_unique.hpp"
#include "util/routed_options.hpp"
#include "util/simple_logger.hpp"
#include <boost/assert.hpp>
@@ -135,11 +136,8 @@ Engine::Engine(EngineConfig &config)
}
else
{
if (!config.storage_config.IsValid())
{
throw util::exception("Invalid file paths given!");
}
query_data_facade = util::make_unique<datafacade::InternalDataFacade>(config.storage_config);
util::populate_base_path(config.server_paths);
query_data_facade = util::make_unique<datafacade::InternalDataFacade>(config.server_paths);
}
// Register plugins
-27
View File
@@ -1,27 +0,0 @@
#include "engine/engine_config.hpp"
namespace osrm
{
namespace engine
{
bool EngineConfig::IsValid() const
{
const bool all_path_are_empty =
storage_config.ram_index_path.empty() && storage_config.file_index_path.empty() &&
storage_config.hsgr_data_path.empty() && storage_config.nodes_data_path.empty() &&
storage_config.edges_data_path.empty() && storage_config.core_data_path.empty() &&
storage_config.geometries_path.empty() && storage_config.timestamp_path.empty() &&
storage_config.datasource_names_path.empty() &&
storage_config.datasource_indexes_path.empty() && storage_config.names_data_path.empty();
const bool limits_valid =
(max_locations_distance_table == -1 || max_locations_distance_table > 2) &&
(max_locations_map_matching == -1 || max_locations_map_matching > 2) &&
(max_locations_trip == -1 || max_locations_trip > 2) &&
(max_locations_viaroute == -1 || max_locations_viaroute > 2);
return ((use_shared_memory && all_path_are_empty) || storage_config.IsValid()) && limits_valid;
}
}
}
+4 -46
View File
@@ -12,49 +12,15 @@ namespace guidance
{
namespace detail
{
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const WaypointType waypoint_type,
const LegGeometry &leg_geometry)
{
BOOST_ASSERT(waypoint_type != WaypointType::None);
BOOST_ASSERT(leg_geometry.locations.size() >= 2);
double pre_turn_bearing = 0, post_turn_bearing = 0;
Coordinate turn_coordinate;
if (waypoint_type == WaypointType::Arrive)
{
turn_coordinate = leg_geometry.locations.front();
const auto post_turn_coordinate = *(leg_geometry.locations.begin() + 1);
post_turn_bearing =
util::coordinate_calculation::bearing(turn_coordinate, post_turn_coordinate);
}
else
{
BOOST_ASSERT(waypoint_type == WaypointType::Depart);
turn_coordinate = leg_geometry.locations.back();
const auto pre_turn_coordinate = *(leg_geometry.locations.end() - 2);
pre_turn_bearing =
util::coordinate_calculation::bearing(pre_turn_coordinate, turn_coordinate);
}
return StepManeuver{
std::move(turn_coordinate),
pre_turn_bearing,
post_turn_bearing,
std::move(instruction),
waypoint_type,
INVALID_EXIT_NR,
{} // no intermediate intersections
};
}
StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction,
const LegGeometry &leg_geometry,
const std::size_t segment_index)
const std::size_t segment_index,
const unsigned exit)
{
auto turn_index = leg_geometry.BackIndex(segment_index);
BOOST_ASSERT(turn_index > 0);
BOOST_ASSERT(turn_index + 1 < leg_geometry.locations.size());
BOOST_ASSERT(turn_index < leg_geometry.locations.size());
// TODO chose a bigger look-a-head to smooth complex geometry
const auto pre_turn_coordinate = leg_geometry.locations[turn_index - 1];
@@ -66,15 +32,7 @@ StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instr
const double post_turn_bearing =
util::coordinate_calculation::bearing(turn_coordinate, post_turn_coordinate);
return StepManeuver{
std::move(turn_coordinate),
pre_turn_bearing,
post_turn_bearing,
std::move(instruction),
WaypointType::None,
INVALID_EXIT_NR,
{} // no intermediate intersections
};
return StepManeuver{turn_coordinate, pre_turn_bearing, post_turn_bearing, instruction, waypoint_type, exit};
}
} // ns detail
} // ns engine
+139 -244
View File
@@ -4,11 +4,8 @@
#include "engine/guidance/toolkit.hpp"
#include <boost/assert.hpp>
#include <boost/range/algorithm_ext/erase.hpp>
#include <iostream>
#include <cstddef>
#include <utility>
#include <vector>
using TurnInstruction = osrm::extractor::guidance::TurnInstruction;
using TurnType = osrm::extractor::guidance::TurnType;
@@ -23,296 +20,194 @@ namespace guidance
namespace detail
{
bool canMergeTrivially(const RouteStep &destination, const RouteStep &source)
bool canMergeTrivially(const PathData &destination, const PathData &source)
{
return destination.maneuver.exit == 0 && destination.name_id == source.name_id &&
isSilent(source.maneuver.instruction);
return destination.exit == 0 && destination.name_id == source.name_id &&
destination.travel_mode == source.travel_mode && isSilent(source.turn_instruction);
}
RouteStep forwardInto(RouteStep destination, const RouteStep &source)
PathData forwardInto(PathData destination, const PathData &source)
{
// Merge a turn into a silent turn
// Overwrites turn instruction and increases exit NR
destination.duration += source.duration;
destination.distance += source.distance;
destination.geometry_begin = std::min(destination.geometry_begin, source.geometry_begin);
destination.geometry_end = std::max(destination.geometry_end, source.geometry_end);
destination.exit = source.exit;
return destination;
}
void fixFinalRoundabout(std::vector<RouteStep> &steps)
PathData accumulateInto(PathData destination, const PathData &source)
{
for (std::size_t propagation_index = steps.size() - 1; propagation_index > 0;
--propagation_index)
{
auto &propagation_step = steps[propagation_index];
if (entersRoundabout(propagation_step.maneuver.instruction))
{
propagation_step.maneuver.exit = 0;
propagation_step.geometry_end = steps.back().geometry_begin;
break;
}
else if (propagation_step.maneuver.instruction.type == TurnType::StayOnRoundabout)
{
// TODO this operates on the data that is in the instructions.
// We are missing out on the final segment after the last stay-on-roundabout
// instruction though. it is not contained somewhere until now
steps[propagation_index - 1] =
forwardInto(std::move(steps[propagation_index - 1]), propagation_step);
propagation_step.maneuver.instruction =
TurnInstruction::NO_TURN(); // mark intermediate instructions invalid
}
}
// Merge a turn into a silent turn
// Overwrites turn instruction and increases exit NR
BOOST_ASSERT(canMergeTrivially(destination, source));
destination.exit = source.exit + 1;
return destination;
}
bool setUpRoundabout(RouteStep &step)
PathData mergeInto(PathData destination, const PathData &source)
{
// basic entry into a roundabout
// Special case handling, if an entry is directly tied to an exit
const auto instruction = step.maneuver.instruction;
if (instruction.type == TurnType::EnterRotaryAtExit ||
instruction.type == TurnType::EnterRoundaboutAtExit)
if (source.turn_instruction == TurnInstruction::NO_TURN())
{
step.maneuver.exit = 1;
// prevent futher special case handling of these two.
if (instruction.type == TurnType::EnterRotaryAtExit)
step.maneuver.instruction = TurnType::EnterRotary;
else
step.maneuver.instruction = TurnType::EnterRoundabout;
BOOST_ASSERT(canMergeTrivially(destination, source));
return detail::forwardInto(destination, source);
}
if (leavesRoundabout(instruction))
if (source.turn_instruction.type == TurnType::Suppressed)
{
step.maneuver.exit = 1; // count the otherwise missing exit
if (instruction.type == TurnType::EnterRotaryAtExit)
step.maneuver.instruction = TurnType::EnterRotary;
else
step.maneuver.instruction = TurnType::EnterRoundabout;
return false;
return detail::forwardInto(destination, source);
}
else
if (source.turn_instruction.type == TurnType::StayOnRoundabout)
{
return true;
return detail::forwardInto(destination, source);
}
if (entersRoundabout(source.turn_instruction))
{
return detail::forwardInto(destination, source);
}
return destination;
}
void closeOffRoundabout(const bool on_roundabout,
std::vector<RouteStep> &steps,
const std::size_t step_index)
{
auto &step = steps[step_index];
step.maneuver.exit += 1;
if (!on_roundabout)
{
// We reached a special case that requires the addition of a special route step in
// the beginning.
// We started in a roundabout, so to announce the exit, we move use the exit
// instruction and
// move it right to the beginning to make sure to immediately announce the exit.
BOOST_ASSERT(leavesRoundabout(steps[1].maneuver.instruction) ||
steps[1].maneuver.instruction.type == TurnType::StayOnRoundabout);
steps[0].geometry_end = 1;
steps[1] = detail::forwardInto(steps[1], steps[0]);
steps[0].duration = 0;
steps[0].distance = 0;
steps[1].maneuver.instruction.type = step.maneuver.instruction.type == TurnType::ExitRotary
? TurnType::EnterRotary
: TurnType::EnterRoundabout;
}
// Normal exit from the roundabout, or exit from a previously fixed roundabout.
// Propagate the index back to the entering
// location and
// prepare the current silent set of instructions for removal.
if (step_index > 1)
{
// The very first route-step is head, so we cannot iterate past that one
for (std::size_t propagation_index = step_index - 1; propagation_index > 0;
--propagation_index)
{
auto &propagation_step = steps[propagation_index];
propagation_step = detail::forwardInto(propagation_step, steps[propagation_index + 1]);
if (entersRoundabout(propagation_step.maneuver.instruction))
{
// TODO at this point, we can remember the additional name for a rotary
// This requires some initial thought on the data format, though
propagation_step.maneuver.exit = step.maneuver.exit;
propagation_step.geometry_end = step.geometry_end;
propagation_step.name = step.name;
propagation_step.name_id = step.name_id;
break;
}
else
{
BOOST_ASSERT(propagation_step.maneuver.instruction.type =
TurnType::StayOnRoundabout);
propagation_step.maneuver.instruction =
TurnInstruction::NO_TURN(); // mark intermediate instructions invalid
}
}
// remove exit
step.maneuver.instruction = TurnInstruction::NO_TURN();
}
}
} // namespace detail
void print(const std::vector<RouteStep> &steps)
void print(const std::vector<std::vector<PathData>> &leg_data)
{
std::cout << "Path\n";
int segment = 0;
for (const auto &step : steps)
int legnr = 0;
for (const auto &leg : leg_data)
{
const auto type = static_cast<int>(step.maneuver.instruction.type);
const auto modifier = static_cast<int>(step.maneuver.instruction.direction_modifier);
std::cout << "\tLeg: " << ++legnr << "\n";
int segment = 0;
for (const auto &data : leg)
{
const auto type = static_cast<int>(data.turn_instruction.type);
const auto modifier = static_cast<int>(data.turn_instruction.direction_modifier);
std::cout << "\t[" << ++segment << "]: " << type << " " << modifier
<< " Duration: " << step.duration << " Distance: " << step.distance
<< " Geometry: " << step.geometry_begin << " " << step.geometry_end
<< " exit: " << step.maneuver.exit
<< " Intersections: " << step.maneuver.intersections.size() << " [";
for (auto intersection : step.maneuver.intersections)
std::cout << "(" << intersection.duration << " " << intersection.distance << ")";
std::cout << "] name[" << step.name_id << "]: " << step.name << std::endl;
std::cout << "\t\t[" << ++segment << "]: " << type << " " << modifier
<< " exit: " << data.exit << "\n";
}
}
std::cout << std::endl;
}
// Every Step Maneuver consists of the information until the turn.
// This list contains a set of instructions, called silent, which should
// not be part of the final output.
// They are required for maintenance purposes. We can calculate the number
// of exits to pass in a roundabout and the number of intersections
// that we come across.
std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>> leg_data)
{
// the steps should always include the first/last step in form of a location
BOOST_ASSERT(steps.size() >= 2);
if (steps.size() == 2)
return steps;
if (leg_data.empty())
return leg_data;
#define OSRM_POST_PROCESSING_PRINT_DEBUG 0
#if OSRM_POST_PROCESSING_PRINT_DEBUG
#define PRINT_DEBUG 0
unsigned carry_exit = 0;
#if PRINT_DEBUG
std::cout << "[POSTPROCESSING ITERATION]" << std::endl;
std::cout << "Input\n";
print(steps);
print(leg_data);
#endif
// Count Street Exits forward
bool on_roundabout = false;
// adds an intersection to the initial route step
// It includes the length of the last step, until the intersection
// Also updates the length of the respective segment
auto addIntersection =
[](RouteStep into, const RouteStep &last_step, const RouteStep &intersection)
for (auto &path_data : leg_data)
{
into.maneuver.intersections.push_back(
{last_step.duration, last_step.distance, intersection.maneuver.location});
if (not path_data.empty())
path_data[0].exit = carry_exit;
return detail::forwardInto(std::move(into), intersection);
};
// count the exits forward. if enter/exit roundabout happen both, no further treatment is
// required. We might end up with only one of them (e.g. starting within a roundabout)
// or having a via-point in the roundabout.
// In this case, exits are numbered from the start of the lag.
std::size_t last_valid_instruction = 0;
for (std::size_t step_index = 0; step_index < steps.size(); ++step_index)
{
auto &step = steps[step_index];
const auto instruction = step.maneuver.instruction;
if (entersRoundabout(instruction))
for (std::size_t data_index = 0; data_index + 1 < path_data.size(); ++data_index)
{
last_valid_instruction = step_index;
on_roundabout = detail::setUpRoundabout(step);
if (on_roundabout && step_index + 1 < steps.size())
steps[step_index + 1].maneuver.exit = step.maneuver.exit;
}
else if (instruction.type == TurnType::StayOnRoundabout)
{
// increase the exit number we require passing the exit
step.maneuver.exit += 1;
if (step_index + 1 < steps.size())
steps[step_index + 1].maneuver.exit = step.maneuver.exit;
}
else if (leavesRoundabout(instruction))
{
if (!on_roundabout)
if (entersRoundabout(path_data[data_index].turn_instruction))
{
// in case the we are not on a roundabout, the very first instruction
// after the depart will be transformed into a roundabout and become
// the first valid instruction
last_valid_instruction = 1;
path_data[data_index].exit += 1;
on_roundabout = true;
}
detail::closeOffRoundabout(on_roundabout, steps, step_index);
on_roundabout = false;
}
else if (instruction.type == TurnType::Suppressed)
{
// count intersections. We cannot use exit, since intersections can follow directly
// after a roundabout
steps[last_valid_instruction] = addIntersection(
std::move(steps[last_valid_instruction]), steps[step_index - 1], step);
step.maneuver.instruction = TurnInstruction::NO_TURN();
}
else if (!isSilent(instruction))
{
// Remember the last non silent instruction
last_valid_instruction = step_index;
if (isSilent(path_data[data_index].turn_instruction) &&
path_data[data_index].turn_instruction != TurnInstruction::NO_TURN())
{
path_data[data_index].exit += 1;
}
if (leavesRoundabout(path_data[data_index].turn_instruction))
{
if (!on_roundabout)
{
BOOST_ASSERT(leg_data[0][0].turn_instruction.type ==
TurnInstruction::NO_TURN());
if (path_data[data_index].turn_instruction.type == TurnType::ExitRoundabout)
leg_data[0][0].turn_instruction.type = TurnType::EnterRoundabout;
if (path_data[data_index].turn_instruction.type == TurnType::ExitRotary)
leg_data[0][0].turn_instruction.type = TurnType::EnterRotary;
path_data[data_index].exit += 1;
}
on_roundabout = false;
}
if (path_data[data_index].turn_instruction.type == TurnType::EnterRoundaboutAtExit)
{
path_data[data_index].exit += 1;
path_data[data_index].turn_instruction.type = TurnType::EnterRoundabout;
}
else if (path_data[data_index].turn_instruction.type == TurnType::EnterRotaryAtExit)
{
path_data[data_index].exit += 1;
path_data[data_index].turn_instruction.type = TurnType::EnterRotary;
}
if (isSilent(path_data[data_index].turn_instruction) ||
entersRoundabout(path_data[data_index].turn_instruction))
{
path_data[data_index + 1] =
detail::mergeInto(path_data[data_index + 1], path_data[data_index]);
}
carry_exit = path_data[data_index].exit;
}
}
// unterminated roundabout
// Move backwards through the instructions until the start and remove the exit number
// A roundabout without exit translates to enter-roundabout.
if (on_roundabout)
{
detail::fixFinalRoundabout(steps);
}
// finally clean up the post-processed instructions.
// Remove all invalid instructions from the set of instructions.
// An instruction is invalid, if its NO_TURN and has WaypointType::None.
// Two valid NO_TURNs exist in each leg in the form of Depart/Arrive
// keep valid instructions
const auto not_is_valid = [](const RouteStep &step)
{
return step.maneuver.instruction == TurnInstruction::NO_TURN() &&
step.maneuver.waypoint_type == WaypointType::None;
};
boost::remove_erase_if(steps, not_is_valid);
#if OSRM_POST_PROCESSING_PRINT_DEBUG
#if PRINT_DEBUG
std::cout << "Merged\n";
print(steps);
print(leg_data);
#endif
return steps;
}
LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep> &steps)
{
// The geometry uses an adjacency array-like structure for representation.
// To sync it back up with the steps, we cann add a segment for every step.
leg_geometry.segment_offsets.clear();
leg_geometry.segment_distances.clear();
leg_geometry.segment_offsets.push_back(0);
for (const auto &step : steps)
on_roundabout = false;
// Move Roundabout exit numbers to front
for (auto rev_itr = leg_data.rbegin(); rev_itr != leg_data.rend(); ++rev_itr)
{
leg_geometry.segment_distances.push_back(step.distance);
// the leg geometry does not follow the begin/end-convetion. So we have to subtract one
// to get the back-index.
leg_geometry.segment_offsets.push_back(step.geometry_end - 1);
auto &path_data = *rev_itr;
for (std::size_t data_index = path_data.size(); data_index > 1; --data_index)
{
if (entersRoundabout(path_data[data_index - 1].turn_instruction))
{
if (!on_roundabout && !leavesRoundabout(path_data[data_index - 1].turn_instruction))
path_data[data_index - 1].exit = 0;
on_roundabout = false;
}
if (on_roundabout)
{
path_data[data_index - 2].exit = path_data[data_index - 1].exit;
}
if (leavesRoundabout(path_data[data_index - 1].turn_instruction) &&
!entersRoundabout(path_data[data_index - 1].turn_instruction))
{
path_data[data_index - 2].exit = path_data[data_index - 1].exit;
on_roundabout = true;
}
}
auto prev_leg = std::next(rev_itr);
if (!path_data.empty() && prev_leg != leg_data.rend())
{
if (on_roundabout && path_data[0].exit)
prev_leg->back().exit = path_data[0].exit;
}
}
//remove the data fromt the reached-target step again
leg_geometry.segment_offsets.pop_back();
leg_geometry.segment_distances.pop_back();
#if PRINT_DEBUG
std::cout << "Move To Front\n";
print(leg_data);
#endif
// silence silent turns for good
for (auto &path_data : leg_data)
{
for (auto &data : path_data)
{
if (isSilent(data.turn_instruction) || (leavesRoundabout(data.turn_instruction) &&
!entersRoundabout(data.turn_instruction)))
{
data.turn_instruction = TurnInstruction::NO_TURN();
data.exit = 0;
}
}
}
return leg_geometry;
return leg_data;
}
} // namespace guidance
+5 -45
View File
@@ -1,60 +1,20 @@
#include "engine/hint.hpp"
#include "engine/base64.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "engine/object_encoder.hpp"
#include <boost/assert.hpp>
#include <iterator>
#include <algorithm>
#include <ostream>
#include <tuple>
namespace osrm
{
namespace engine
{
bool Hint::IsValid(const util::Coordinate new_input_coordinates,
const datafacade::BaseDataFacade &facade) const
{
auto is_same_input_coordinate = new_input_coordinates.lon == phantom.input_location.lon &&
new_input_coordinates.lat == phantom.input_location.lat;
return is_same_input_coordinate && phantom.IsValid(facade.GetNumberOfNodes()) &&
facade.GetCheckSum() == data_checksum;
}
std::string Hint::ToBase64() const
{
auto base64 = encodeBase64Bytewise(*this);
// Make safe for usage as GET parameter in URLs
std::replace(begin(base64), end(base64), '+', '-');
std::replace(begin(base64), end(base64), '/', '_');
return base64;
}
std::string Hint::ToBase64() const { return encodeBase64(*this); }
Hint Hint::FromBase64(const std::string &base64Hint)
{
BOOST_ASSERT_MSG(base64Hint.size() == ENCODED_HINT_SIZE, "Hint has invalid size");
// We need mutability but don't want to change the API
auto encoded = base64Hint;
// Reverses above encoding we need for GET parameters in URL
std::replace(begin(encoded), end(encoded), '-', '+');
std::replace(begin(encoded), end(encoded), '_', '/');
return decodeBase64Bytewise<Hint>(encoded);
auto decoded = decodeBase64<Hint>(base64Hint);
return decoded;
}
}
bool operator==(const Hint &lhs, const Hint &rhs)
{
return std::tie(lhs.phantom, lhs.data_checksum) ==
std::tie(rhs.phantom, rhs.data_checksum);
}
std::ostream &operator<<(std::ostream &out, const Hint &hint) { return out << hint.ToBase64(); }
} // ns engine
} // ns osrm
+1
View File
@@ -4,6 +4,7 @@
#include "engine/map_matching/bayes_classifier.hpp"
#include "engine/api/match_parameters.hpp"
#include "engine/api/match_api.hpp"
#include "engine/object_encoder.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/integer_range.hpp"
#include "util/json_logger.hpp"
+1
View File
@@ -2,6 +2,7 @@
#include "engine/api/table_parameters.hpp"
#include "engine/api/table_api.hpp"
#include "engine/object_encoder.hpp"
#include "engine/routing_algorithms/many_to_many.hpp"
#include "engine/search_engine_data.hpp"
#include "util/string_util.hpp"
+6 -50
View File
@@ -3,11 +3,6 @@
#include "util/coordinate_calculation.hpp"
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/multi/geometries/multi_linestring.hpp>
#include <protozero/varint.hpp>
#include <protozero/pbf_writer.hpp>
@@ -28,7 +23,6 @@ namespace detail
{
// Vector tiles are 4096 virtual pixels on each side
const constexpr double VECTOR_TILE_EXTENT = 4096.0;
const constexpr double VECTOR_TILE_BUFFER = 128.0;
// Simple container class for WSG84 coordinates
template <typename T> struct Point final
@@ -73,14 +67,6 @@ struct point_type_i final
using FixedLine = std::vector<detail::Point<std::int32_t>>;
using FloatLine = std::vector<detail::Point<double>>;
typedef boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> point_t;
typedef boost::geometry::model::linestring<point_t> linestring_t;
typedef boost::geometry::model::box<point_t> box_t;
typedef boost::geometry::model::multi_linestring<linestring_t> multi_linestring_t;
const static box_t clip_box(point_t(-detail::VECTOR_TILE_BUFFER, -detail::VECTOR_TILE_BUFFER),
point_t(detail::VECTOR_TILE_EXTENT + detail::VECTOR_TILE_BUFFER,
detail::VECTOR_TILE_EXTENT + detail::VECTOR_TILE_BUFFER));
// from mapnik-vector-tile
// Encodes a linestring using protobuf zigzag encoding
inline bool encodeLinestring(const FixedLine &line,
@@ -125,9 +111,7 @@ FixedLine coordinatesToTileLine(const util::Coordinate start,
static_cast<double>(util::toFloating(start.lat)));
geo_line.emplace_back(static_cast<double>(util::toFloating(target.lon)),
static_cast<double>(util::toFloating(target.lat)));
linestring_t unclipped_line;
FixedLine tile_line;
for (auto const &pt : geo_line)
{
double px_merc = pt.x * mercator::DEGREE_TO_PX;
@@ -139,29 +123,8 @@ FixedLine coordinatesToTileLine(const util::Coordinate start,
const auto py = std::round(
((tile_bbox.maxy - py_merc) * mercator::TILE_SIZE / tile_bbox.height()) *
detail::VECTOR_TILE_EXTENT / util::coordinate_calculation::mercator::TILE_SIZE);
boost::geometry::append(unclipped_line, point_t(px, py));
tile_line.emplace_back(px, py);
}
multi_linestring_t clipped_line;
boost::geometry::intersection(clip_box, unclipped_line, clipped_line);
FixedLine tile_line;
// b::g::intersection might return a line with one point if the
// original line was very short and coords were dupes
if (!clipped_line.empty() && clipped_line[0].size() == 2)
{
if (clipped_line[0].size() == 2)
{
for (const auto &p : clipped_line[0])
{
tile_line.emplace_back(p.get<0>(), p.get<1>());
}
}
}
return tile_line;
}
}
@@ -354,7 +317,6 @@ Status TilePlugin::HandleRequest(const api::TileParameters &parameters, std::str
duration); // duration value offset
}
{
// Encode the geometry for the feature
protozero::packed_field_uint32 geometry(feature_writer, 4);
encodeLinestring(tile_line, geometry, start_x, start_y);
@@ -372,11 +334,8 @@ Status TilePlugin::HandleRequest(const api::TileParameters &parameters, std::str
static_cast<std::uint32_t>(round(length / forward_weight * 10 * 3.6));
auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
if (!tile_line.empty())
{
encode_tile_line(tile_line, speed_kmh, weight_offsets[forward_weight],
forward_datasource, start_x, start_y);
}
encode_tile_line(tile_line, speed_kmh, weight_offsets[forward_weight],
forward_datasource, start_x, start_y);
}
// Repeat the above for the coordinates reversed and using the `reverse`
@@ -391,11 +350,8 @@ Status TilePlugin::HandleRequest(const api::TileParameters &parameters, std::str
static_cast<std::uint32_t>(round(length / reverse_weight * 10 * 3.6));
auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
if (!tile_line.empty())
{
encode_tile_line(tile_line, speed_kmh, weight_offsets[reverse_weight],
reverse_datasource, start_x, start_y);
}
encode_tile_line(tile_line, speed_kmh, weight_offsets[reverse_weight],
reverse_datasource, start_x, start_y);
}
}
}
+13 -1
View File
@@ -135,7 +135,19 @@ InternalRouteResult TripPlugin::ComputeRoute(const std::vector<PhantomNode> &sna
}
BOOST_ASSERT(min_route.segment_end_coordinates.size() == trip.size());
shortest_path(min_route.segment_end_coordinates, parameters.uturns, min_route);
std::vector<boost::optional<bool>> uturns;
if (parameters.uturns.size() > 0)
{
uturns.resize(trip.size() + 1);
std::transform(trip.begin(), trip.end(), uturns.begin(), [&parameters](const NodeID idx)
{
return parameters.uturns[idx];
});
BOOST_ASSERT(uturns.size() > 0);
uturns.back() = parameters.uturns[trip.front()];
}
shortest_path(min_route.segment_end_coordinates, uturns, min_route);
BOOST_ASSERT_MSG(min_route.shortest_path_length < INVALID_EDGE_WEIGHT, "unroutable route");
return min_route;
+1
View File
@@ -1,6 +1,7 @@
#include "engine/plugins/viaroute.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "engine/api/route_api.hpp"
#include "engine/object_encoder.hpp"
#include "engine/status.hpp"
#include "util/for_each_pair.hpp"
+22 -29
View File
@@ -12,7 +12,6 @@
#include "extractor/guidance/toolkit.hpp"
#include <boost/assert.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <algorithm>
#include <cmath>
@@ -35,13 +34,13 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
const std::unordered_set<NodeID> &traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<QueryNode> &node_info_list,
ProfileProperties profile_properties,
SpeedProfileProperties speed_profile,
const util::NameTable &name_table)
: m_max_edge_id(0), m_node_info_list(node_info_list),
m_node_based_graph(std::move(node_based_graph)),
m_restriction_map(std::move(restriction_map)), m_barrier_nodes(barrier_nodes),
m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container),
profile_properties(std::move(profile_properties)), name_table(name_table)
speed_profile(std::move(speed_profile)), name_table(name_table)
{
}
@@ -208,7 +207,7 @@ unsigned EdgeBasedGraphFactory::RenumberEdges()
// oneway streets always require this self-loop. Other streets only if a u-turn plus
// traversal
// of the street takes longer than the loop
m_edge_based_node_weights.push_back(edge_data.distance + profile_properties.u_turn_penalty);
m_edge_based_node_weights.push_back(edge_data.distance + speed_profile.u_turn_penalty);
BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges());
edge_data.edge_id = numbered_edges_count;
@@ -277,9 +276,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
{
util::SimpleLogger().Write() << "generating edge-expanded edges";
BOOST_ASSERT(lua_state != nullptr);
const bool use_turn_function = util::luaFunctionExists(lua_state, "turn_function");
std::size_t node_based_edge_counter = 0;
std::size_t original_edges_counter = 0;
restricted_turns_counter = 0;
@@ -296,10 +292,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
edge_penalty_file.open(edge_fixed_penalties_filename.c_str(), std::ios::binary);
}
// Writes a dummy value at the front that is updated later with the total length
const unsigned length_prefix_empty_space{0};
edge_data_file.write(reinterpret_cast<const char *>(&length_prefix_empty_space),
sizeof(length_prefix_empty_space));
// writes a dummy value that is updated later
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
std::vector<OriginalEdgeData> original_edge_data_vector;
original_edge_data_vector.reserve(1024 * 1024);
@@ -341,15 +335,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
unsigned distance = edge_data1.distance;
if (m_traffic_lights.find(node_v) != m_traffic_lights.end())
{
distance += profile_properties.traffic_signal_penalty;
distance += speed_profile.traffic_signal_penalty;
}
const int turn_penalty = use_turn_function ? GetTurnPenalty(turn_angle, lua_state) : 0;
const int turn_penalty = GetTurnPenalty(turn_angle, lua_state);
const auto turn_instruction = turn.instruction;
if (guidance::isUturn(turn_instruction))
{
distance += profile_properties.u_turn_penalty;
distance += speed_profile.u_turn_penalty;
}
distance += turn_penalty;
@@ -425,13 +419,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
FlushVectorToStream(edge_data_file, original_edge_data_vector);
// Finally jump back to the empty space at the beginning and write length prefix
edge_data_file.seekp(std::ios::beg);
const auto length_prefix = boost::numeric_cast<unsigned>(original_edges_counter);
static_assert(sizeof(length_prefix_empty_space) == sizeof(length_prefix), "type mismatch");
edge_data_file.write(reinterpret_cast<const char *>(&length_prefix), sizeof(length_prefix));
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
util::SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size()
<< " edge based nodes";
@@ -449,16 +438,20 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) const
{
BOOST_ASSERT(lua_state != nullptr);
try
if (speed_profile.has_turn_penalty_function)
{
// call lua profile to compute turn penalty
double penalty = luabind::call_function<double>(lua_state, "turn_function", 180. - angle);
return boost::numeric_cast<int>(penalty);
}
catch (const luabind::error &er)
{
util::SimpleLogger().Write(logWARNING) << er.what();
try
{
// call lua profile to compute turn penalty
double penalty =
luabind::call_function<double>(lua_state, "turn_function", 180. - angle);
return static_cast<int>(penalty);
}
catch (const luabind::error &er)
{
util::SimpleLogger().Write(logWARNING) << er.what();
}
}
return 0;
}
+1 -3
View File
@@ -288,8 +288,6 @@ void ExtractionContainers::PrepareEdges(lua_State *segment_state)
const auto all_edges_list_end_ = all_edges_list.end();
const auto all_nodes_list_end_ = all_nodes_list.end();
const auto has_segment_function = util::luaFunctionExists(segment_state, "segment_function");
while (edge_iterator != all_edges_list_end_ && node_iterator != all_nodes_list_end_)
{
// skip all invalid edges
@@ -325,7 +323,7 @@ void ExtractionContainers::PrepareEdges(lua_State *segment_state)
edge_iterator->source_coordinate,
util::Coordinate(node_iterator->lon, node_iterator->lat));
if (has_segment_function)
if (util::lua_function_exists(segment_state, "segment_function"))
{
luabind::call_function<void>(
segment_state, "segment_function", boost::cref(edge_iterator->source_coordinate),
+66 -32
View File
@@ -48,7 +48,6 @@
#include <unordered_map>
#include <vector>
#include <bitset>
#include <chrono>
namespace osrm
{
@@ -76,9 +75,6 @@ namespace extractor
*/
int Extractor::run()
{
// setup scripting environment
ScriptingEnvironment scripting_environment(config.profile_path.string().c_str());
try
{
util::LogPolicy::GetInstance().Unmute();
@@ -93,6 +89,9 @@ int Extractor::run()
util::SimpleLogger().Write() << "Profile: " << config.profile_path.filename().string();
util::SimpleLogger().Write() << "Threads: " << number_of_threads;
// setup scripting environment
ScriptingEnvironment scripting_environment(config.profile_path.string().c_str());
ExtractionContainers extraction_containers;
auto extractor_callbacks = util::make_unique<ExtractorCallbacks>(extraction_containers);
@@ -108,12 +107,15 @@ int Extractor::run()
util::SimpleLogger().Write() << "Parsing in progress..";
TIMER_START(parsing);
auto& main_context = scripting_environment.GetContex();
lua_State *segment_state = scripting_environment.GetLuaState();
// setup raster sources
if (util::luaFunctionExists(main_context.state, "source_function"))
if (util::lua_function_exists(segment_state, "source_function"))
{
luabind::call_function<void>(main_context.state, "source_function");
// bind a single instance of SourceContainer class to relevant lua state
SourceContainer sources;
luabind::globals(segment_state)["sources"] = sources;
luabind::call_function<void>(segment_state, "source_function");
}
std::string generator = header.get("generator");
@@ -140,7 +142,7 @@ int Extractor::run()
tbb::concurrent_vector<boost::optional<InputRestrictionContainer>> resulting_restrictions;
// setup restriction parser
const RestrictionParser restriction_parser(main_context.state, main_context.properties);
const RestrictionParser restriction_parser(scripting_environment.GetLuaState());
while (const osmium::memory::Buffer buffer = reader.read())
{
@@ -163,7 +165,7 @@ int Extractor::run()
{
ExtractionNode result_node;
ExtractionWay result_way;
auto& local_context = scripting_environment.GetContex();
lua_State *local_state = scripting_environment.GetLuaState();
for (auto x = range.begin(), end = range.end(); x != end; ++x)
{
@@ -175,7 +177,7 @@ int Extractor::run()
result_node.clear();
++number_of_nodes;
luabind::call_function<void>(
local_context.state, "node_function",
local_state, "node_function",
boost::cref(static_cast<const osmium::Node &>(*entity)),
boost::ref(result_node));
resulting_nodes.push_back(std::make_pair(x, result_node));
@@ -184,7 +186,7 @@ int Extractor::run()
result_way.clear();
++number_of_ways;
luabind::call_function<void>(
local_context.state, "way_function",
local_state, "way_function",
boost::cref(static_cast<const osmium::Way &>(*entity)),
boost::ref(result_way));
resulting_ways.push_back(std::make_pair(x, result_way));
@@ -236,29 +238,26 @@ int Extractor::run()
}
extraction_containers.PrepareData(config.output_file_name, config.restriction_file_name,
config.names_file_name, main_context.state);
WriteProfileProperties(config.profile_properties_output_path, main_context.properties);
config.names_file_name, segment_state);
TIMER_STOP(extracting);
util::SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting)
<< "s";
}
// we do this for scoping
// TODO move to own functions
catch (const std::exception &e)
{
util::SimpleLogger().Write(logWARNING) << e.what();
return 1;
}
try
{
// Transform the node-based graph that OSM is based on into an edge-based graph
// that is better for routing. Every edge becomes a node, and every valid
// movement (e.g. turn from A->B, and B->A) becomes an edge
//
auto& main_context = scripting_environment.GetContex();
//
// // Create a new lua state
util::SimpleLogger().Write() << "Generating edge-expanded graph representation";
@@ -269,9 +268,7 @@ int Extractor::run()
std::vector<bool> node_is_startpoint;
std::vector<EdgeWeight> edge_based_node_weights;
std::vector<QueryNode> internal_to_external_node_map;
auto graph_size = BuildEdgeExpandedGraph(main_context.state,
main_context.properties,
internal_to_external_node_map,
auto graph_size = BuildEdgeExpandedGraph(internal_to_external_node_map,
edge_based_node_list, node_is_startpoint,
edge_based_node_weights, edge_based_edge_list);
@@ -317,15 +314,46 @@ int Extractor::run()
return 0;
}
void Extractor::WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const
/**
\brief Setups scripting environment (lua-scripting)
Also initializes speed profile.
*/
void Extractor::SetupScriptingEnvironment(lua_State *lua_state,
SpeedProfileProperties &speed_profile)
{
boost::filesystem::ofstream out_stream(output_path);
if (!out_stream)
// open utility libraries string library;
luaL_openlibs(lua_state);
// adjust lua load path
util::luaAddScriptFolderToLoadPath(lua_state, config.profile_path.string().c_str());
// Now call our function in a lua script
if (0 != luaL_dofile(lua_state, config.profile_path.string().c_str()))
{
throw util::exception("Could not open " + output_path + " for writing.");
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occurred in scripting block";
throw util::exception(msg.str());
}
out_stream.write(reinterpret_cast<const char*>(&properties), sizeof(properties));
if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n"))
{
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occurred in scripting block";
throw util::exception(msg.str());
}
speed_profile.traffic_signal_penalty = 10 * lua_tointeger(lua_state, -1);
util::SimpleLogger().Write(logDEBUG) << "traffic_signal_penalty: "
<< speed_profile.traffic_signal_penalty;
if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n"))
{
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occurred in scripting block";
throw util::exception(msg.str());
}
speed_profile.u_turn_penalty = 10 * lua_tointeger(lua_state, -1);
speed_profile.has_turn_penalty_function = util::lua_function_exists(lua_state, "turn_function");
}
void Extractor::FindComponents(unsigned max_edge_id,
@@ -468,14 +496,18 @@ Extractor::LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes,
\brief Building an edge-expanded graph from node-based input and turn restrictions
*/
std::pair<std::size_t, std::size_t>
Extractor::BuildEdgeExpandedGraph(lua_State* lua_state,
const ProfileProperties& profile_properties,
std::vector<QueryNode> &internal_to_external_node_map,
Extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list)
{
lua_State *lua_state = luaL_newstate();
luabind::open(lua_state);
SpeedProfileProperties speed_profile;
SetupScriptingEnvironment(lua_state, speed_profile);
std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights;
@@ -484,7 +516,7 @@ Extractor::BuildEdgeExpandedGraph(lua_State* lua_state,
LoadNodeBasedGraph(barrier_nodes, traffic_lights, internal_to_external_node_map);
CompressedEdgeContainer compressed_edge_container;
GraphCompressor graph_compressor;
GraphCompressor graph_compressor(speed_profile);
graph_compressor.Compress(barrier_nodes, traffic_lights, *restriction_map, *node_based_graph,
compressed_edge_container);
@@ -495,12 +527,14 @@ Extractor::BuildEdgeExpandedGraph(lua_State* lua_state,
EdgeBasedGraphFactory edge_based_graph_factory(
node_based_graph, compressed_edge_container, barrier_nodes, traffic_lights,
std::const_pointer_cast<RestrictionMap const>(restriction_map),
internal_to_external_node_map, profile_properties, name_table);
internal_to_external_node_map, speed_profile, name_table);
edge_based_graph_factory.Run(config.edge_output_path, lua_state,
config.edge_segment_lookup_path, config.edge_penalty_path,
config.generate_edge_lookup);
lua_close(lua_state);
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list);
edge_based_graph_factory.GetStartPointMarkers(node_is_startpoint);
+5
View File
@@ -13,6 +13,11 @@ namespace osrm
namespace extractor
{
GraphCompressor::GraphCompressor(SpeedProfileProperties speed_profile)
: speed_profile(std::move(speed_profile))
{
}
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_lights,
RestrictionMap &restriction_map,
+43 -77
View File
@@ -268,9 +268,8 @@ TurnAnalysis::fallbackTurnAssignmentMotorway(std::vector<ConnectedRoad> intersec
return intersection;
}
std::vector<ConnectedRoad>
TurnAnalysis::handleFromMotorway(const EdgeID via_edge,
std::vector<ConnectedRoad> intersection) const
std::vector<ConnectedRoad> TurnAnalysis::handleFromMotorway(
const EdgeID via_edge, std::vector<ConnectedRoad> intersection) const
{
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
BOOST_ASSERT(detail::isMotorwayClass(in_data.road_classification.road_class));
@@ -520,9 +519,8 @@ TurnAnalysis::handleFromMotorway(const EdgeID via_edge,
return intersection;
}
std::vector<ConnectedRoad>
TurnAnalysis::handleMotorwayRamp(const EdgeID via_edge,
std::vector<ConnectedRoad> intersection) const
std::vector<ConnectedRoad> TurnAnalysis::handleMotorwayRamp(
const EdgeID via_edge, std::vector<ConnectedRoad> intersection) const
{
auto num_valid_turns = countValid(intersection);
// ramp straight into a motorway/ramp
@@ -661,9 +659,8 @@ TurnAnalysis::handleMotorwayRamp(const EdgeID via_edge,
return intersection;
}
std::vector<ConnectedRoad>
TurnAnalysis::handleMotorwayJunction(const EdgeID via_edge,
std::vector<ConnectedRoad> intersection) const
std::vector<ConnectedRoad> TurnAnalysis::handleMotorwayJunction(
const EdgeID via_edge, std::vector<ConnectedRoad> intersection) const
{
// BOOST_ASSERT(!intersection[0].entry_allowed); //This fails due to @themarex handling of dead
// end
@@ -801,8 +798,7 @@ TurnAnalysis::handleThreeWayTurn(const EdgeID via_edge,
{
return (angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
angularDeviation(other.turn.angle, STRAIGHT_ANGLE) > 85) ||
(angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <
std::numeric_limits<double>::epsilon()) ||
(angularDeviation(road.turn.angle,STRAIGHT_ANGLE) < std::numeric_limits<double>::epsilon()) ||
(angularDeviation(other.turn.angle, STRAIGHT_ANGLE) /
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) >
1.4);
@@ -1008,10 +1004,10 @@ TurnAnalysis::handleThreeWayTurn(const EdgeID via_edge,
getTurnDirection(intersection[2].turn.angle)};
}
}
// unnamed intersections or basic three way turn
// unnamed intersections or basic three way turn
// remain at basic turns
// TODO handle obviousness, Handle Merges
// remain at basic turns
// TODO handle obviousness, Handle Merges
return intersection;
}
@@ -1509,47 +1505,43 @@ void TurnAnalysis::assignFork(const EdgeID via_edge,
node_based_graph.GetEdgeData(left.turn.eid).road_classification.road_class);
const bool low_priority_right = isLowPriorityRoadClass(
node_based_graph.GetEdgeData(right.turn.eid).road_classification.road_class);
if ((angularDeviation(left.turn.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(right.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE))
{
// left side is actually straight
{ // left fork
const auto &out_data = node_based_graph.GetEdgeData(left.turn.eid);
if (requiresAnnouncement(in_data, out_data))
if ((angularDeviation(left.turn.angle, STRAIGHT_ANGLE) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(right.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE))
{
if (low_priority_right && !low_priority_left)
if (requiresAnnouncement(in_data, out_data))
{
left.turn.instruction = getInstructionForObvious(3, via_edge, left);
right.turn.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
if (low_priority_right && !low_priority_left)
left.turn.instruction = getInstructionForObvious(3, via_edge, left);
else
{
if (low_priority_left && !low_priority_right)
left.turn.instruction = {TurnType::Turn, DirectionModifier::SlightLeft};
else
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
}
else
{
if (low_priority_left && !low_priority_right)
{
left.turn.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.turn.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
else
{
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
}
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
}
}
else
{
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
right.turn.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
if (low_priority_right && !low_priority_left)
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
else
{
if (low_priority_left && !low_priority_right)
left.turn.instruction = {TurnType::Turn, DirectionModifier::SlightLeft};
else
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
}
}
else if (angularDeviation(right.turn.angle, STRAIGHT_ANGLE) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(left.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)
{
// right side is actually straight
{ // right fork
const auto &out_data = node_based_graph.GetEdgeData(right.turn.eid);
if (angularDeviation(right.turn.angle, STRAIGHT_ANGLE) <
MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
@@ -1558,57 +1550,31 @@ void TurnAnalysis::assignFork(const EdgeID via_edge,
if (requiresAnnouncement(in_data, out_data))
{
if (low_priority_left && !low_priority_right)
{
left.turn.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.turn.instruction = getInstructionForObvious(3, via_edge, right);
}
else
{
if (low_priority_right && !low_priority_left)
{
left.turn.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
right.turn.instruction = {findBasicTurnType(via_edge, right),
DirectionModifier::SlightRight};
}
right.turn.instruction = {TurnType::Turn, DirectionModifier::SlightRight};
else
{
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
}
}
else
{
right.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
left.turn.instruction = {findBasicTurnType(via_edge, left),
DirectionModifier::SlightLeft};
}
}
}
else
{
// left side of fork
if (low_priority_right && !low_priority_left)
left.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
else
{
if (low_priority_left && !low_priority_right)
left.turn.instruction = {TurnType::Turn, DirectionModifier::SlightLeft};
right.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
else
left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
}
// right side of fork
if (low_priority_left && !low_priority_right)
right.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft};
else
{
if (low_priority_right && !low_priority_left)
right.turn.instruction = {TurnType::Turn, DirectionModifier::SlightRight};
else
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
{
if (low_priority_right && !low_priority_left)
right.turn.instruction = {TurnType::Turn, DirectionModifier::SlightRight};
else
right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
}
}
}
}
+23 -4
View File
@@ -1,5 +1,5 @@
#include "extractor/restriction_parser.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/extraction_way.hpp"
#include "extractor/external_memory_node.hpp"
#include "util/lua_util.hpp"
@@ -33,18 +33,37 @@ int luaErrorCallback(lua_State *lua_state)
}
}
RestrictionParser::RestrictionParser(lua_State *lua_state, const ProfileProperties &properties)
: use_turn_restrictions(properties.use_turn_restrictions)
RestrictionParser::RestrictionParser(lua_State *lua_state) : use_turn_restrictions(true)
{
ReadUseRestrictionsSetting(lua_state);
if (use_turn_restrictions)
{
ReadRestrictionExceptions(lua_state);
}
}
void RestrictionParser::ReadUseRestrictionsSetting(lua_State *lua_state)
{
if (0 == luaL_dostring(lua_state, "return use_turn_restrictions\n") &&
lua_isboolean(lua_state, -1))
{
use_turn_restrictions = lua_toboolean(lua_state, -1);
}
if (use_turn_restrictions)
{
util::SimpleLogger().Write() << "Using turn restrictions";
}
else
{
util::SimpleLogger().Write() << "Ignoring turn restrictions";
}
}
void RestrictionParser::ReadRestrictionExceptions(lua_State *lua_state)
{
if (util::luaFunctionExists(lua_state, "get_exceptions"))
if (util::lua_function_exists(lua_state, "get_exceptions"))
{
luabind::set_pcall_callback(&luaErrorCallback);
// get list of turn restriction exceptions
+82 -93
View File
@@ -6,9 +6,7 @@
#include "extractor/internal_extractor_edge.hpp"
#include "extractor/external_memory_node.hpp"
#include "extractor/raster_source.hpp"
#include "extractor/profile_properties.hpp"
#include "util/lua_util.hpp"
#include "util/make_unique.hpp"
#include "util/exception.hpp"
#include "util/simple_logger.hpp"
#include "util/typedefs.hpp"
@@ -58,126 +56,117 @@ ScriptingEnvironment::ScriptingEnvironment(const std::string &file_name) : file_
util::SimpleLogger().Write() << "Using script " << file_name;
}
void ScriptingEnvironment::InitContext(ScriptingEnvironment::Context &context)
void ScriptingEnvironment::InitLuaState(lua_State *lua_state)
{
typedef double (osmium::Location::*location_member_ptr_type)() const;
luabind::open(context.state);
luabind::open(lua_state);
// open utility libraries string library;
luaL_openlibs(context.state);
luaL_openlibs(lua_state);
util::luaAddScriptFolderToLoadPath(context.state, file_name.c_str());
util::luaAddScriptFolderToLoadPath(lua_state, file_name.c_str());
// Add our function to the state's global scope
luabind::module(context.state)
[luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration),
luabind::class_<TravelMode>("mode")
.enum_("enums")[luabind::value("inaccessible", TRAVEL_MODE_INACCESSIBLE),
luabind::value("driving", TRAVEL_MODE_DRIVING),
luabind::value("cycling", TRAVEL_MODE_CYCLING),
luabind::value("walking", TRAVEL_MODE_WALKING),
luabind::value("ferry", TRAVEL_MODE_FERRY),
luabind::value("train", TRAVEL_MODE_TRAIN),
luabind::value("pushing_bike", TRAVEL_MODE_PUSHING_BIKE),
luabind::value("movable_bridge", TRAVEL_MODE_MOVABLE_BRIDGE),
luabind::value("steps_up", TRAVEL_MODE_STEPS_UP),
luabind::value("steps_down", TRAVEL_MODE_STEPS_DOWN),
luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
luabind::value("river_down", TRAVEL_MODE_RIVER_DOWN),
luabind::value("route", TRAVEL_MODE_ROUTE)],
luabind::class_<SourceContainer>("sources")
.def(luabind::constructor<>())
.def("load", &SourceContainer::loadRasterSource)
.def("query", &SourceContainer::getRasterDataFromSource)
.def("interpolate", &SourceContainer::getRasterInterpolateFromSource),
luabind::class_<const float>("constants")
.enum_("enums")[luabind::value("precision", COORDINATE_PRECISION)],
luabind::module(
lua_state)[luabind::def("print", util::LUA_print<std::string>),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration),
luabind::class_<TravelMode>("mode")
.enum_("enums")[luabind::value("inaccessible", TRAVEL_MODE_INACCESSIBLE),
luabind::value("driving", TRAVEL_MODE_DRIVING),
luabind::value("cycling", TRAVEL_MODE_CYCLING),
luabind::value("walking", TRAVEL_MODE_WALKING),
luabind::value("ferry", TRAVEL_MODE_FERRY),
luabind::value("train", TRAVEL_MODE_TRAIN),
luabind::value("pushing_bike", TRAVEL_MODE_PUSHING_BIKE),
luabind::value("movable_bridge", TRAVEL_MODE_MOVABLE_BRIDGE),
luabind::value("steps_up", TRAVEL_MODE_STEPS_UP),
luabind::value("steps_down", TRAVEL_MODE_STEPS_DOWN),
luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
luabind::value("river_down", TRAVEL_MODE_RIVER_DOWN),
luabind::value("route", TRAVEL_MODE_ROUTE)],
luabind::class_<SourceContainer>("sources")
.def(luabind::constructor<>())
.def("load", &SourceContainer::loadRasterSource)
.def("query", &SourceContainer::getRasterDataFromSource)
.def("interpolate", &SourceContainer::getRasterInterpolateFromSource),
luabind::class_<const float>("constants")
.enum_("enums")[luabind::value("precision", COORDINATE_PRECISION)],
luabind::class_<ProfileProperties>("ProfileProperties")
.def(luabind::constructor<>())
.property("traffic_signal_penalty", &ProfileProperties::GetTrafficSignalPenalty,
&ProfileProperties::SetTrafficSignalPenalty)
.property("u_turn_penalty", &ProfileProperties::GetUturnPenalty,
&ProfileProperties::SetUturnPenalty)
.def_readwrite("allow_u_turn_at_via", &ProfileProperties::allow_u_turn_at_via),
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)),
luabind::class_<osmium::Location>("Location")
.def<location_member_ptr_type>("lat", &osmium::Location::lat)
.def<location_member_ptr_type>("lon", &osmium::Location::lon),
luabind::class_<osmium::Location>("Location")
.def<location_member_ptr_type>("lat", &osmium::Location::lat)
.def<location_member_ptr_type>("lon", &osmium::Location::lon),
luabind::class_<osmium::Node>("Node")
// .def<node_member_ptr_type>("tags", &osmium::Node::tags)
.def("location", &osmium::Node::location)
.def("get_value_by_key", &osmium::Node::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Node>)
.def("id", &osmium::Node::id),
luabind::class_<osmium::Node>("Node")
// .def<node_member_ptr_type>("tags", &osmium::Node::tags)
.def("location", &osmium::Node::location)
.def("get_value_by_key", &osmium::Node::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Node>)
.def("id", &osmium::Node::id),
luabind::class_<ExtractionNode>("ResultNode")
.def_readwrite("traffic_lights", &ExtractionNode::traffic_lights)
.def_readwrite("barrier", &ExtractionNode::barrier),
luabind::class_<ExtractionNode>("ResultNode")
.def_readwrite("traffic_lights", &ExtractionNode::traffic_lights)
.def_readwrite("barrier", &ExtractionNode::barrier),
luabind::class_<ExtractionWay>("ResultWay")
// .def(luabind::constructor<>())
.def_readwrite("forward_speed", &ExtractionWay::forward_speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
.def_readwrite("is_startpoint", &ExtractionWay::is_startpoint)
.def_readwrite("duration", &ExtractionWay::duration)
.property("forward_mode", &ExtractionWay::get_forward_mode,
&ExtractionWay::set_forward_mode)
.property("backward_mode", &ExtractionWay::get_backward_mode,
&ExtractionWay::set_backward_mode),
luabind::class_<osmium::Way>("Way")
.def("get_value_by_key", &osmium::Way::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Way>)
.def("id", &osmium::Way::id),
luabind::class_<InternalExtractorEdge>("EdgeSource")
.def_readonly("source_coordinate", &InternalExtractorEdge::source_coordinate)
.def_readwrite("weight_data", &InternalExtractorEdge::weight_data),
luabind::class_<InternalExtractorEdge::WeightData>("WeightData")
.def_readwrite("speed", &InternalExtractorEdge::WeightData::speed),
luabind::class_<ExternalMemoryNode>("EdgeTarget")
.property("lon", &lonToDouble<ExternalMemoryNode>)
.property("lat", &latToDouble<ExternalMemoryNode>),
luabind::class_<util::Coordinate>("Coordinate")
.property("lon", &lonToDouble<util::Coordinate>)
.property("lat", &latToDouble<util::Coordinate>),
luabind::class_<RasterDatum>("RasterDatum")
.def_readonly("datum", &RasterDatum::datum)
.def("invalid_data", &RasterDatum::get_invalid)];
luabind::class_<ExtractionWay>("ResultWay")
// .def(luabind::constructor<>())
.def_readwrite("forward_speed", &ExtractionWay::forward_speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
.def_readwrite("is_startpoint", &ExtractionWay::is_startpoint)
.def_readwrite("duration", &ExtractionWay::duration)
.property("forward_mode", &ExtractionWay::get_forward_mode,
&ExtractionWay::set_forward_mode)
.property("backward_mode", &ExtractionWay::get_backward_mode,
&ExtractionWay::set_backward_mode),
luabind::class_<osmium::Way>("Way")
.def("get_value_by_key", &osmium::Way::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Way>)
.def("id", &osmium::Way::id),
luabind::class_<InternalExtractorEdge>("EdgeSource")
.def_readonly("source_coordinate", &InternalExtractorEdge::source_coordinate)
.def_readwrite("weight_data", &InternalExtractorEdge::weight_data),
luabind::class_<InternalExtractorEdge::WeightData>("WeightData")
.def_readwrite("speed", &InternalExtractorEdge::WeightData::speed),
luabind::class_<ExternalMemoryNode>("EdgeTarget")
.property("lon", &lonToDouble<ExternalMemoryNode>)
.property("lat", &latToDouble<ExternalMemoryNode>),
luabind::class_<util::Coordinate>("Coordinate")
.property("lon", &lonToDouble<util::Coordinate>)
.property("lat", &latToDouble<util::Coordinate>),
luabind::class_<RasterDatum>("RasterDatum")
.def_readonly("datum", &RasterDatum::datum)
.def("invalid_data", &RasterDatum::get_invalid)];
luabind::globals(context.state)["properties"] = &context.properties;
luabind::globals(context.state)["sources"] = &context.sources;
if (0 != luaL_dofile(context.state, file_name.c_str()))
if (0 != luaL_dofile(lua_state, file_name.c_str()))
{
luabind::object error_msg(luabind::from_stack(context.state, -1));
luabind::object error_msg(luabind::from_stack(lua_state, -1));
std::ostringstream error_stream;
error_stream << error_msg;
throw util::exception("ERROR occurred in profile script:\n" + error_stream.str());
}
}
ScriptingEnvironment::Context &ScriptingEnvironment::GetContex()
lua_State *ScriptingEnvironment::GetLuaState()
{
std::lock_guard<std::mutex> lock(init_mutex);
bool initialized = false;
auto &ref = script_contexts.local(initialized);
if (!initialized)
{
ref = util::make_unique<Context>();
InitContext(*ref);
std::shared_ptr<lua_State> state(luaL_newstate(), lua_close);
ref = state;
InitLuaState(ref.get());
}
luabind::set_pcall_callback(&luaErrorCallback);
return *ref;
return ref.get();
}
}
}
+3 -1
View File
@@ -25,7 +25,9 @@ std::string getWrongOptionHelp(const engine::api::RouteParameters &parameters)
constrainParamSize(PARAMETER_SIZE_MISMATCH_MSG, "bearings",
parameters.bearings, coord_size, help) ||
constrainParamSize(PARAMETER_SIZE_MISMATCH_MSG, "radiuses",
parameters.radiuses, coord_size, help);
parameters.radiuses, coord_size, help) ||
constrainParamSize(PARAMETER_SIZE_MISMATCH_MSG, "uturns",
parameters.uturns, coord_size, help);
if (!param_size_mismatch && parameters.coordinates.size() < 2)
{
+128 -69
View File
@@ -2,7 +2,6 @@
#include "util/range_table.hpp"
#include "contractor/query_edge.hpp"
#include "extractor/query_node.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/compressed_edge_container.hpp"
#include "util/shared_memory_vector_wrapper.hpp"
#include "util/static_graph.hpp"
@@ -73,12 +72,10 @@ void deleteRegion(const SharedDataType region)
}
}
Storage::Storage(StorageConfig config_) : config(std::move(config_)) {}
Storage::Storage(const DataPaths &paths_) : paths(paths_) {}
int Storage::Run()
{
BOOST_ASSERT_MSG(config.IsValid(), "Invalid storage config");
util::LogPolicy::GetInstance().Unmute();
SharedBarriers barrier;
@@ -102,6 +99,94 @@ int Storage::Run()
barrier.pending_update_mutex.unlock();
}
if (paths.find("hsgrdata") == paths.end())
{
throw util::exception("no hsgr file found");
}
if (paths.find("ramindex") == paths.end())
{
throw util::exception("no ram index file found");
}
if (paths.find("fileindex") == paths.end())
{
throw util::exception("no leaf index file found");
}
if (paths.find("nodesdata") == paths.end())
{
throw util::exception("no nodes file found");
}
if (paths.find("edgesdata") == paths.end())
{
throw util::exception("no edges file found");
}
if (paths.find("namesdata") == paths.end())
{
throw util::exception("no names file found");
}
if (paths.find("geometry") == paths.end())
{
throw util::exception("no geometry file found");
}
if (paths.find("core") == paths.end())
{
throw util::exception("no core file found");
}
if (paths.find("datasource_indexes") == paths.end())
{
throw util::exception("no datasource_indexes file found");
}
if (paths.find("datasource_names") == paths.end())
{
throw util::exception("no datasource_names file found");
}
auto paths_iterator = paths.find("hsgrdata");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &hsgr_path = paths_iterator->second;
paths_iterator = paths.find("timestamp");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &timestamp_path = paths_iterator->second;
paths_iterator = paths.find("ramindex");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &ram_index_path = paths_iterator->second;
paths_iterator = paths.find("fileindex");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path index_file_path_absolute =
boost::filesystem::canonical(paths_iterator->second);
const std::string &file_index_path = index_file_path_absolute.string();
paths_iterator = paths.find("nodesdata");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &nodes_data_path = paths_iterator->second;
paths_iterator = paths.find("edgesdata");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &edges_data_path = paths_iterator->second;
paths_iterator = paths.find("namesdata");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &names_data_path = paths_iterator->second;
paths_iterator = paths.find("geometry");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &geometries_data_path = paths_iterator->second;
paths_iterator = paths.find("core");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &core_marker_path = paths_iterator->second;
paths_iterator = paths.find("datasource_indexes");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &datasource_indexes_path = paths_iterator->second;
paths_iterator = paths.find("datasource_names");
BOOST_ASSERT(paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &datasource_names_path = paths_iterator->second;
// determine segment to use
bool segment2_in_use = SharedMemory::RegionExists(LAYOUT_2);
const storage::SharedDataType layout_region = [&]
@@ -124,19 +209,14 @@ int Storage::Run()
// Allocate a memory layout in shared memory, deallocate previous
auto *layout_memory = makeSharedMemory(layout_region, sizeof(SharedDataLayout));
auto shared_layout_ptr = new (layout_memory->Ptr()) SharedDataLayout();
auto absolute_file_index_path = boost::filesystem::absolute(config.file_index_path);
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::FILE_INDEX_PATH,
absolute_file_index_path.string().length() + 1);
file_index_path.length() + 1);
// collect number of elements to store in shared memory object
util::SimpleLogger().Write() << "load names from: " << config.names_data_path;
util::SimpleLogger().Write() << "load names from: " << names_data_path;
// number of entries in name index
boost::filesystem::ifstream name_stream(config.names_data_path, std::ios::binary);
if (!name_stream)
{
throw util::exception("Could not open " + config.names_data_path.string() + " for reading.");
}
boost::filesystem::ifstream name_stream(names_data_path, std::ios::binary);
unsigned name_blocks = 0;
name_stream.read((char *)&name_blocks, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::NAME_OFFSETS, name_blocks);
@@ -150,11 +230,7 @@ int Storage::Run()
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::NAME_CHAR_LIST, number_of_chars);
// Loading information for original edges
boost::filesystem::ifstream edges_input_stream(config.edges_data_path, std::ios::binary);
if (!edges_input_stream)
{
throw util::exception("Could not open " + config.edges_data_path.string() + " for reading.");
}
boost::filesystem::ifstream edges_input_stream(edges_data_path, std::ios::binary);
unsigned number_of_original_edges = 0;
edges_input_stream.read((char *)&number_of_original_edges, sizeof(unsigned));
@@ -168,11 +244,7 @@ int Storage::Run()
shared_layout_ptr->SetBlockSize<extractor::guidance::TurnInstruction>(
SharedDataLayout::TURN_INSTRUCTION, number_of_original_edges);
boost::filesystem::ifstream hsgr_input_stream(config.hsgr_data_path, std::ios::binary);
if (!hsgr_input_stream)
{
throw util::exception("Could not open " + config.hsgr_data_path.string() + " for reading.");
}
boost::filesystem::ifstream hsgr_input_stream(hsgr_path, std::ios::binary);
util::FingerPrint fingerprint_valid = util::FingerPrint::GetValid();
util::FingerPrint fingerprint_loaded;
@@ -207,27 +279,39 @@ int Storage::Run()
number_of_graph_edges);
// load rsearch tree size
boost::filesystem::ifstream tree_node_file(config.ram_index_path, std::ios::binary);
boost::filesystem::ifstream tree_node_file(ram_index_path, std::ios::binary);
uint32_t tree_size = 0;
tree_node_file.read((char *)&tree_size, sizeof(uint32_t));
shared_layout_ptr->SetBlockSize<RTreeNode>(SharedDataLayout::R_SEARCH_TREE, tree_size);
// load profile properties
shared_layout_ptr->SetBlockSize<extractor::ProfileProperties>(SharedDataLayout::PROPERTIES, 1);
// load timestamp size
boost::filesystem::ifstream timestamp_stream(config.timestamp_path);
std::string m_timestamp;
getline(timestamp_stream, m_timestamp);
if (boost::filesystem::exists(timestamp_path))
{
boost::filesystem::ifstream timestamp_stream(timestamp_path);
if (!timestamp_stream)
{
util::SimpleLogger().Write(logWARNING) << timestamp_path
<< " not found. setting to default";
}
else
{
getline(timestamp_stream, m_timestamp);
}
}
if (m_timestamp.empty())
{
m_timestamp = "n/a";
}
if (25 < m_timestamp.length())
{
m_timestamp.resize(25);
}
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::TIMESTAMP, m_timestamp.length());
// load core marker size
boost::filesystem::ifstream core_marker_file(config.core_data_path, std::ios::binary);
if (!core_marker_file)
{
throw util::exception("Could not open " + config.core_data_path.string() + " for reading.");
}
boost::filesystem::ifstream core_marker_file(core_marker_path, std::ios::binary);
uint32_t number_of_core_markers = 0;
core_marker_file.read((char *)&number_of_core_markers, sizeof(uint32_t));
@@ -235,22 +319,14 @@ int Storage::Run()
number_of_core_markers);
// load coordinate size
boost::filesystem::ifstream nodes_input_stream(config.nodes_data_path, std::ios::binary);
if (!nodes_input_stream)
{
throw util::exception("Could not open " + config.core_data_path.string() + " for reading.");
}
boost::filesystem::ifstream nodes_input_stream(nodes_data_path, std::ios::binary);
unsigned coordinate_list_size = 0;
nodes_input_stream.read((char *)&coordinate_list_size, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<util::Coordinate>(SharedDataLayout::COORDINATE_LIST,
coordinate_list_size);
// load geometries sizes
boost::filesystem::ifstream geometry_input_stream(config.geometries_path, std::ios::binary);
if (!geometry_input_stream)
{
throw util::exception("Could not open " + config.geometries_path.string() + " for reading.");
}
std::ifstream geometry_input_stream(geometries_data_path.string().c_str(), std::ios::binary);
unsigned number_of_geometries_indices = 0;
unsigned number_of_compressed_geometries = 0;
@@ -265,12 +341,8 @@ int Storage::Run()
// load datasource sizes. This file is optional, and it's non-fatal if it doesn't
// exist.
boost::filesystem::ifstream geometry_datasource_input_stream(config.datasource_indexes_path,
std::ios::binary);
if (!geometry_datasource_input_stream)
{
throw util::exception("Could not open " + config.datasource_indexes_path.string() + " for reading.");
}
std::ifstream geometry_datasource_input_stream(datasource_indexes_path.c_str(),
std::ios::binary);
std::size_t number_of_compressed_datasources = 0;
if (geometry_datasource_input_stream)
{
@@ -282,12 +354,7 @@ int Storage::Run()
// Load datasource name sizes. This file is optional, and it's non-fatal if it doesn't
// exist
boost::filesystem::ifstream datasource_names_input_stream(config.datasource_names_path,
std::ios::binary);
if (!datasource_names_input_stream)
{
throw util::exception("Could not open " + config.datasource_names_path.string() + " for reading.");
}
std::ifstream datasource_names_input_stream(datasource_names_path.c_str(), std::ios::binary);
std::vector<char> m_datasource_name_data;
std::vector<std::size_t> m_datasource_name_offsets;
std::vector<std::size_t> m_datasource_name_lengths;
@@ -303,11 +370,11 @@ int Storage::Run()
}
}
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::DATASOURCE_NAME_DATA,
m_datasource_name_data.size());
m_datasource_name_data.size());
shared_layout_ptr->SetBlockSize<std::size_t>(SharedDataLayout::DATASOURCE_NAME_OFFSETS,
m_datasource_name_offsets.size());
m_datasource_name_offsets.size());
shared_layout_ptr->SetBlockSize<std::size_t>(SharedDataLayout::DATASOURCE_NAME_LENGTHS,
m_datasource_name_lengths.size());
m_datasource_name_lengths.size());
// allocate shared memory block
util::SimpleLogger().Write() << "allocating shared memory of "
@@ -330,7 +397,7 @@ int Storage::Run()
file_index_path_ptr +
shared_layout_ptr->GetBlockSize(SharedDataLayout::FILE_INDEX_PATH),
0);
std::copy(absolute_file_index_path.string().begin(), absolute_file_index_path.string().end(), file_index_path_ptr);
std::copy(file_index_path.begin(), file_index_path.end(), file_index_path_ptr);
// Loading street names
unsigned *name_offsets_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
@@ -437,7 +504,8 @@ int Storage::Run()
shared_memory_ptr, SharedDataLayout::DATASOURCE_NAME_DATA);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::DATASOURCE_NAME_DATA) > 0)
{
std::cout << "Copying " << (m_datasource_name_data.end() - m_datasource_name_data.begin())
std::cout << "Copying "
<< (m_datasource_name_data.end() - m_datasource_name_data.begin())
<< " chars into name data ptr\n";
std::copy(m_datasource_name_data.begin(), m_datasource_name_data.end(),
datasource_name_data_ptr);
@@ -537,15 +605,6 @@ int Storage::Run()
}
hsgr_input_stream.close();
// load profile properties
auto profile_properties_ptr = shared_layout_ptr->GetBlockPtr<extractor::ProfileProperties, true>(shared_memory_ptr, SharedDataLayout::PROPERTIES);
boost::filesystem::ifstream profile_properties_stream(config.properties_path);
if (!profile_properties_stream)
{
util::exception("Could not open " + config.properties_path.string() + " for reading!");
}
profile_properties_stream.read(reinterpret_cast<char*>(profile_properties_ptr), sizeof(extractor::ProfileProperties));
// acquire lock
SharedMemory *data_type_memory =
makeSharedMemory(CURRENT_REGIONS, sizeof(SharedDataTimestamp), true, false);
-38
View File
@@ -1,38 +0,0 @@
#include "storage/storage_config.hpp"
#include <boost/filesystem/operations.hpp>
namespace osrm
{
namespace storage
{
StorageConfig::StorageConfig(const boost::filesystem::path &base)
: ram_index_path{base.string() + ".ramIndex"}, file_index_path{base.string() + ".fileIndex"},
hsgr_data_path{base.string() + ".hsgr"}, nodes_data_path{base.string() + ".nodes"},
edges_data_path{base.string() + ".edges"}, core_data_path{base.string() + ".core"},
geometries_path{base.string() + ".geometry"}, timestamp_path{base.string() + ".timestamp"},
datasource_names_path{base.string() + ".datasource_names"},
datasource_indexes_path{base.string() + ".datasource_indexes"},
names_data_path{base.string() + ".names"},
properties_path{base.string() + ".properties"}
{
}
bool StorageConfig::IsValid() const
{
return boost::filesystem::is_regular_file(ram_index_path) &&
boost::filesystem::is_regular_file(file_index_path) &&
boost::filesystem::is_regular_file(hsgr_data_path) &&
boost::filesystem::is_regular_file(nodes_data_path) &&
boost::filesystem::is_regular_file(edges_data_path) &&
boost::filesystem::is_regular_file(core_data_path) &&
boost::filesystem::is_regular_file(geometries_path) &&
boost::filesystem::is_regular_file(timestamp_path) &&
boost::filesystem::is_regular_file(datasource_names_path) &&
boost::filesystem::is_regular_file(datasource_indexes_path) &&
boost::filesystem::is_regular_file(names_data_path) &&
boost::filesystem::is_regular_file(properties_path);
}
}
}
+5 -132
View File
@@ -1,14 +1,10 @@
#include "server/server.hpp"
#include "util/routed_options.hpp"
#include "util/make_unique.hpp"
#include "util/simple_logger.hpp"
#include "util/version.hpp"
#include "osrm/osrm.hpp"
#include "osrm/engine_config.hpp"
#include "osrm/storage_config.hpp"
#include <boost/any.hpp>
#include <boost/program_options.hpp>
#ifdef __linux__
#include <sys/mman.h>
@@ -23,7 +19,6 @@
#include <iostream>
#include <new>
#include <thread>
#include <string>
#ifdef _WIN32
boost::function0<void> console_ctrl_function;
@@ -46,111 +41,6 @@ BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
using namespace osrm;
const static unsigned INIT_OK_START_ENGINE = 0;
const static unsigned INIT_OK_DO_NOT_START_ENGINE = 1;
const static unsigned INIT_FAILED = -1;
// generate boost::program_options object for the routing part
inline unsigned
generateServerProgramOptions(const int argc,
const char *argv[],
boost::filesystem::path &base_path,
std::string &ip_address,
int &ip_port,
int &requested_num_threads,
bool &use_shared_memory,
bool &trial,
int &max_locations_trip,
int &max_locations_viaroute,
int &max_locations_distance_table,
int &max_locations_map_matching)
{
using boost::program_options::value;
using boost::filesystem::path;
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options() //
("version,v", "Show version")("help,h", "Show this help message") //
("trial", value<bool>(&trial)->implicit_value(true), "Quit after initialization");
// declare a group of options that will be allowed on command line
boost::program_options::options_description config_options("Configuration");
config_options.add_options() //
("ip,i", value<std::string>(&ip_address)->default_value("0.0.0.0"),
"IP address") //
("port,p", value<int>(&ip_port)->default_value(5000),
"TCP/IP port") //
("threads,t", value<int>(&requested_num_threads)->default_value(8),
"Number of threads to use") //
("shared-memory,s",
value<bool>(&use_shared_memory)->implicit_value(true)->default_value(false),
"Load data from shared memory") //
("max-viaroute-size", value<int>(&max_locations_viaroute)->default_value(500),
"Max. locations supported in viaroute query") //
("max-trip-size", value<int>(&max_locations_trip)->default_value(100),
"Max. locations supported in trip query") //
("max-table-size", value<int>(&max_locations_distance_table)->default_value(100),
"Max. locations supported in distance table query") //
("max-matching-size", value<int>(&max_locations_map_matching)->default_value(100),
"Max. locations supported in map matching query");
// hidden options, will be allowed on command line, but will not be shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()("base,b", value<boost::filesystem::path>(&base_path),
"base path to .osrm file");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("base", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
boost::filesystem::path(argv[0]).stem().string() + " <base.osrm> [<options>]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
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"))
{
util::SimpleLogger().Write() << OSRM_VERSION;
return INIT_OK_DO_NOT_START_ENGINE;
}
if (option_variables.count("help"))
{
util::SimpleLogger().Write() << visible_options;
return INIT_OK_DO_NOT_START_ENGINE;
}
boost::program_options::notify(option_variables);
if (!use_shared_memory && option_variables.count("base"))
{
return INIT_OK_START_ENGINE;
}
else if (use_shared_memory && !option_variables.count("base"))
{
return INIT_OK_START_ENGINE;
}
else if (use_shared_memory && option_variables.count("base"))
{
util::SimpleLogger().Write(logWARNING) << "Shared memory settings conflict with path settings.";
}
util::SimpleLogger().Write() << visible_options;
return INIT_OK_DO_NOT_START_ENGINE;
}
int main(int argc, const char *argv[]) try
{
util::LogPolicy::GetInstance().Unmute();
@@ -160,36 +50,19 @@ int main(int argc, const char *argv[]) try
int ip_port, requested_thread_num;
EngineConfig config;
boost::filesystem::path base_path;
const unsigned init_result = generateServerProgramOptions(
argc, argv, base_path, ip_address, ip_port, requested_thread_num,
const unsigned init_result = util::GenerateServerProgramOptions(
argc, argv, config.server_paths, ip_address, ip_port, requested_thread_num,
config.use_shared_memory, trial_run, config.max_locations_trip,
config.max_locations_viaroute, config.max_locations_distance_table,
config.max_locations_map_matching);
if (init_result == INIT_OK_DO_NOT_START_ENGINE)
if (init_result == util::INIT_OK_DO_NOT_START_ENGINE)
{
return EXIT_SUCCESS;
}
if (init_result == INIT_FAILED)
if (init_result == util::INIT_FAILED)
{
return EXIT_FAILURE;
}
if (!base_path.empty())
{
config.storage_config = storage::StorageConfig(base_path);
}
if(!config.IsValid())
{
if (base_path.empty() != config.use_shared_memory)
{
util::SimpleLogger().Write(logWARNING) << "Path settings and shared memory conflicts.";
}
else
{
util::SimpleLogger().Write(logWARNING) << "Invalid config options.";
}
return EXIT_FAILURE;
}
#ifdef __linux__
struct MemoryLocker final
+157 -11
View File
@@ -10,7 +10,7 @@
using namespace osrm;
// generate boost::program_options object for the routing part
bool generateDataStoreOptions(const int argc, const char *argv[], boost::filesystem::path& base_path)
bool generateDataStoreOptions(const int argc, const char *argv[], storage::DataPaths &paths)
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
@@ -20,11 +20,36 @@ bool generateDataStoreOptions(const int argc, const char *argv[], boost::filesys
// declare a group of options that will be allowed both on command line
// as well as in a config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"hsgrdata", boost::program_options::value<boost::filesystem::path>(&paths["hsgrdata"]),
".hsgr file")("nodesdata",
boost::program_options::value<boost::filesystem::path>(&paths["nodesdata"]),
".nodes file")(
"edgesdata", boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
".edges file")("geometry",
boost::program_options::value<boost::filesystem::path>(&paths["geometry"]),
".geometry file")(
"ramindex", boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
".ramIndex file")(
"fileindex", boost::program_options::value<boost::filesystem::path>(&paths["fileindex"]),
".fileIndex file")("core",
boost::program_options::value<boost::filesystem::path>(&paths["core"]),
".core file")(
"namesdata", boost::program_options::value<boost::filesystem::path>(&paths["namesdata"]),
".names file")("timestamp",
boost::program_options::value<boost::filesystem::path>(&paths["timestamp"]),
".timestamp file")(
"datasource_names",
boost::program_options::value<boost::filesystem::path>(&paths["datasource_names"]),
".datasource_names file")(
"datasource_indexes",
boost::program_options::value<boost::filesystem::path>(&paths["datasource_indexes"]),
".datasource_indexes file");
// hidden options, will be allowed on command line but will not be shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"base,b", boost::program_options::value<boost::filesystem::path>(&base_path),
"base,b", boost::program_options::value<boost::filesystem::path>(&paths["base"]),
"base path to .osrm file");
// positional option
@@ -68,6 +93,132 @@ bool generateDataStoreOptions(const int argc, const char *argv[], boost::filesys
boost::program_options::notify(option_variables);
auto path_iterator = paths.find("base");
BOOST_ASSERT(paths.end() != path_iterator);
std::string base_string = path_iterator->second.string();
path_iterator = paths.find("hsgrdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".hsgr";
}
path_iterator = paths.find("nodesdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".nodes";
}
path_iterator = paths.find("edgesdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".edges";
}
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())
{
path_iterator->second = base_string + ".ramIndex";
}
path_iterator = paths.find("fileindex");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".fileIndex";
}
path_iterator = paths.find("core");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".core";
}
path_iterator = paths.find("namesdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".names";
}
path_iterator = paths.find("timestamp");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".timestamp";
}
path_iterator = paths.find("datasource_indexes");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".datasource_indexes";
}
path_iterator = paths.find("datasource_names");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".datasource_names";
}
path_iterator = paths.find("hsgrdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .hsgr file must be specified");
}
path_iterator = paths.find("nodesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .nodes file must be specified");
}
path_iterator = paths.find("edgesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .edges file must be specified");
}
path_iterator = paths.find("geometry");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .geometry file must be specified");
}
path_iterator = paths.find("ramindex");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .ramindex file must be specified");
}
path_iterator = paths.find("fileindex");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .fileindex file must be specified");
}
path_iterator = paths.find("namesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .names file must be specified");
}
path_iterator = paths.find("timestamp");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .timestamp file must be specified");
}
return true;
}
@@ -75,18 +226,13 @@ int main(const int argc, const char *argv[]) try
{
util::LogPolicy::GetInstance().Unmute();
boost::filesystem::path base_path;
if (!generateDataStoreOptions(argc, argv, base_path))
storage::DataPaths paths;
if (!generateDataStoreOptions(argc, argv, paths))
{
return EXIT_SUCCESS;
}
storage::StorageConfig config(base_path);
if (!config.IsValid())
{
util::SimpleLogger().Write(logWARNING) << "Invalid file path given!";
return EXIT_FAILURE;
}
storage::Storage storage(std::move(config));
storage::Storage storage(paths);
return storage.Run();
}
catch (const std::bad_alloc &e)
-74
View File
@@ -1,74 +0,0 @@
#include "engine/base64.hpp"
#include "engine/hint.hpp"
#include "mocks/mock_datafacade.hpp"
#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <iostream>
#include <algorithm>
// RFC 4648 "The Base16, Base32, and Base64 Data Encodings"
BOOST_AUTO_TEST_SUITE(base64)
// For test vectors see section 10: https://tools.ietf.org/html/rfc4648#section-10
BOOST_AUTO_TEST_CASE(rfc4648_test_vectors)
{
using namespace osrm::engine;
BOOST_CHECK_EQUAL(encodeBase64(""), "");
BOOST_CHECK_EQUAL(encodeBase64("f"), "Zg==");
BOOST_CHECK_EQUAL(encodeBase64("fo"), "Zm8=");
BOOST_CHECK_EQUAL(encodeBase64("foo"), "Zm9v");
BOOST_CHECK_EQUAL(encodeBase64("foob"), "Zm9vYg==");
BOOST_CHECK_EQUAL(encodeBase64("fooba"), "Zm9vYmE=");
BOOST_CHECK_EQUAL(encodeBase64("foobar"), "Zm9vYmFy");
}
BOOST_AUTO_TEST_CASE(rfc4648_test_vectors_roundtrip)
{
using namespace osrm::engine;
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("")), "");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("f")), "f");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("fo")), "fo");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("foo")), "foo");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("foob")), "foob");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("fooba")), "fooba");
BOOST_CHECK_EQUAL(decodeBase64(encodeBase64("foobar")), "foobar");
}
BOOST_AUTO_TEST_CASE(hint_encoding_decoding_roundtrip)
{
using namespace osrm::engine;
osrm::test::MockDataFacade facade;
Hint hint{{}, {}, facade.GetCheckSum()};
const auto base64 = hint.ToBase64();
BOOST_CHECK(0 == std::count(begin(base64), end(base64), '+'));
BOOST_CHECK(0 == std::count(begin(base64), end(base64), '/'));
const auto decoded = Hint::FromBase64(base64);
BOOST_CHECK_EQUAL(hint, decoded);
}
BOOST_AUTO_TEST_CASE(hint_encoding_decoding_roundtrip_bytewise)
{
using namespace osrm::engine;
osrm::test::MockDataFacade facade;
Hint hint{{}, {}, facade.GetCheckSum()};
const auto decoded = Hint::FromBase64(hint.ToBase64());
BOOST_CHECK(std::equal(reinterpret_cast<const unsigned char *>(&hint),
reinterpret_cast<const unsigned char *>(&hint) + sizeof(Hint),
reinterpret_cast<const unsigned char *>(&decoded)));
}
BOOST_AUTO_TEST_SUITE_END()
-1
View File
@@ -103,7 +103,6 @@ class MockDataFacadeT final : public osrm::engine::datafacade::BaseDataFacade<Ed
std::string get_name_for_id(const unsigned /* name_id */) const { return ""; }
std::size_t GetCoreSize() const { return 0; }
std::string GetTimestamp() const { return ""; }
bool GetUTurnsDefault() const override { return true; }
};
using MockDataFacade = MockDataFacadeT<contractor::QueryEdge::EdgeData>;
+13 -14
View File
@@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_1.alternatives, result_1->alternatives);
BOOST_CHECK_EQUAL(reference_1.geometries, result_1->geometries);
BOOST_CHECK_EQUAL(reference_1.overview, result_1->overview);
BOOST_CHECK_EQUAL(reference_1.uturns, result_1->uturns);
CHECK_EQUAL_RANGE(reference_1.uturns, result_1->uturns);
CHECK_EQUAL_RANGE(reference_1.bearings, result_1->bearings);
CHECK_EQUAL_RANGE(reference_1.radiuses, result_1->radiuses);
CHECK_EQUAL_RANGE(reference_1.coordinates, result_1->coordinates);
@@ -146,26 +146,25 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_2.alternatives, result_2->alternatives);
BOOST_CHECK_EQUAL(reference_2.geometries, result_2->geometries);
BOOST_CHECK_EQUAL(reference_2.overview, result_2->overview);
BOOST_CHECK_EQUAL(reference_2.uturns, result_2->uturns);
CHECK_EQUAL_RANGE(reference_2.uturns, result_2->uturns);
CHECK_EQUAL_RANGE(reference_2.bearings, result_2->bearings);
CHECK_EQUAL_RANGE(reference_2.radiuses, result_2->radiuses);
CHECK_EQUAL_RANGE(reference_2.coordinates, result_2->coordinates);
engine::api::RouteParameters reference_3{false,
false,
engine::api::RouteParameters::GeometriesType::GeoJSON,
engine::api::RouteParameters::OverviewType::False,
true};
std::vector<boost::optional<bool>> uturns_3 = {true, false, boost::none};
engine::api::RouteParameters reference_3{
false, false, engine::api::RouteParameters::GeometriesType::GeoJSON,
engine::api::RouteParameters::OverviewType::False, uturns_3};
reference_3.coordinates = coords_1;
auto result_3 = api::parseParameters<engine::api::RouteParameters>(
"1,2;3,4?steps=false&alternatives=false&geometries=geojson&overview=false&uturns=true"
"1,2;3,4?steps=false&alternatives=false&geometries=geojson&overview=false&uturns=true;"
"false;");
BOOST_CHECK(result_3);
BOOST_CHECK_EQUAL(reference_3.steps, result_3->steps);
BOOST_CHECK_EQUAL(reference_3.alternatives, result_3->alternatives);
BOOST_CHECK_EQUAL(reference_3.geometries, result_3->geometries);
BOOST_CHECK_EQUAL(reference_3.overview, result_3->overview);
BOOST_CHECK_EQUAL(reference_3.uturns, result_3->uturns);
CHECK_EQUAL_RANGE(reference_3.uturns, result_3->uturns);
CHECK_EQUAL_RANGE(reference_3.bearings, result_3->bearings);
CHECK_EQUAL_RANGE(reference_3.radiuses, result_3->radiuses);
CHECK_EQUAL_RANGE(reference_3.coordinates, result_3->coordinates);
@@ -181,7 +180,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
true,
engine::api::RouteParameters::GeometriesType::Polyline,
engine::api::RouteParameters::OverviewType::Simplified,
boost::optional<bool>{},
std::vector<boost::optional<bool>>{},
coords_1,
hints_4,
std::vector<boost::optional<double>>{},
@@ -197,7 +196,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_4.alternatives, result_4->alternatives);
BOOST_CHECK_EQUAL(reference_4.geometries, result_4->geometries);
BOOST_CHECK_EQUAL(reference_4.overview, result_4->overview);
BOOST_CHECK_EQUAL(reference_4.uturns, result_4->uturns);
CHECK_EQUAL_RANGE(reference_4.uturns, result_4->uturns);
CHECK_EQUAL_RANGE(reference_4.bearings, result_4->bearings);
CHECK_EQUAL_RANGE(reference_4.radiuses, result_4->radiuses);
CHECK_EQUAL_RANGE(reference_4.coordinates, result_4->coordinates);
@@ -209,7 +208,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
true,
engine::api::RouteParameters::GeometriesType::Polyline,
engine::api::RouteParameters::OverviewType::Simplified,
boost::optional<bool>{},
std::vector<boost::optional<bool>>{},
coords_1,
std::vector<boost::optional<engine::Hint>>{},
std::vector<boost::optional<double>>{},
@@ -221,7 +220,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_5.alternatives, result_5->alternatives);
BOOST_CHECK_EQUAL(reference_5.geometries, result_5->geometries);
BOOST_CHECK_EQUAL(reference_5.overview, result_5->overview);
BOOST_CHECK_EQUAL(reference_5.uturns, result_5->uturns);
CHECK_EQUAL_RANGE(reference_5.uturns, result_5->uturns);
CHECK_EQUAL_RANGE(reference_5.bearings, result_5->bearings);
CHECK_EQUAL_RANGE(reference_5.radiuses, result_5->radiuses);
CHECK_EQUAL_RANGE(reference_5.coordinates, result_5->coordinates);
@@ -239,7 +238,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
BOOST_CHECK_EQUAL(reference_6.alternatives, result_6->alternatives);
BOOST_CHECK_EQUAL(reference_6.geometries, result_6->geometries);
BOOST_CHECK_EQUAL(reference_6.overview, result_6->overview);
BOOST_CHECK_EQUAL(reference_6.uturns, result_6->uturns);
CHECK_EQUAL_RANGE(reference_6.uturns, result_6->uturns);
CHECK_EQUAL_RANGE(reference_6.bearings, result_6->bearings);
CHECK_EQUAL_RANGE(reference_6.radiuses, result_6->radiuses);
CHECK_EQUAL_RANGE(reference_6.coordinates, result_6->coordinates);