forked from organicmaps/organicmaps
[routing] Our fixes to OSRM
This commit is contained in:
parent
84db1d1338
commit
814526cd19
30 changed files with 1033 additions and 206 deletions
53
3party/osrm/osrm-backend/.clang-format
Normal file
53
3party/osrm/osrm-backend/.clang-format
Normal file
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: true
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
BreakBeforeBinaryOperators: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BinPackParameters: false
|
||||
ColumnLimit: 100
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
DerivePointerBinding: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
IndentCaseLabels: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
NamespaceIndentation: None
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyExcessCharacter: 1000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerBindsToType: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
Cpp11BracedListStyle: true
|
||||
Standard: Cpp11
|
||||
IndentWidth: 4
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
BreakBeforeBraces: Allman
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
ContinuationIndentWidth: 4
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
SpaceBeforeParens: ControlStatements
|
||||
...
|
93
3party/osrm/osrm-backend/.gitignore
vendored
Normal file
93
3party/osrm/osrm-backend/.gitignore
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
# Compiled source #
|
||||
###################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
|
||||
# Packages #
|
||||
############
|
||||
# it's better to unpack these files and commit the raw source
|
||||
# git has its own built in compression methods
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
|
||||
# Logs and databases #
|
||||
######################
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store
|
||||
ehthumbs.db
|
||||
Icon?
|
||||
Thumbs.db
|
||||
|
||||
# build related files #
|
||||
#######################
|
||||
/build/
|
||||
/Util/FingerPrint.cpp
|
||||
/Util/GitDescription.cpp
|
||||
|
||||
# Eclipse related files #
|
||||
#########################
|
||||
.setting*
|
||||
.scb
|
||||
.cproject
|
||||
.project
|
||||
|
||||
# stxxl related files #
|
||||
#######################
|
||||
.stxxl
|
||||
stxxl.log
|
||||
stxxl.errlog
|
||||
|
||||
# compiled protobuffers #
|
||||
#########################
|
||||
/DataStructures/pbf-proto/*.pb.h
|
||||
/DataStructures/pbf-proto/*.pb.cc
|
||||
|
||||
# External Libs #
|
||||
#################
|
||||
/lib/
|
||||
/win/lib
|
||||
|
||||
# Visual Studio Temp + build Files #
|
||||
####################################
|
||||
/win/*.user
|
||||
/win/*.ncb
|
||||
/win/*.suo
|
||||
/win/Debug/
|
||||
/win/Release/
|
||||
/win/bin/
|
||||
/win/bin-debug/
|
||||
/osrm-extract
|
||||
/osrm-io-benchmark
|
||||
/osrm-components
|
||||
/osrm-routed
|
||||
/osrm-datastore
|
||||
/osrm-prepare
|
||||
/osrm-unlock-all
|
||||
/osrm-cli
|
||||
/osrm-check-hsgr
|
||||
/nohup.out
|
||||
|
||||
# Sandbox folder #
|
||||
###################
|
||||
/sandbox/
|
||||
|
||||
/test/profile.lua
|
||||
|
||||
# Deprecated config file #
|
||||
##########################
|
||||
/server.ini
|
0
3party/osrm/osrm-backend/.gitmodules
vendored
Normal file
0
3party/osrm/osrm-backend/.gitmodules
vendored
Normal file
54
3party/osrm/osrm-backend/.travis.yml
Normal file
54
3party/osrm/osrm-backend/.travis.yml
Normal file
|
@ -0,0 +1,54 @@
|
|||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
# - clang
|
||||
# Make sure CMake is installed
|
||||
install:
|
||||
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo add-apt-repository -y ppa:boost-latest/ppa
|
||||
- sudo apt-get update >/dev/null
|
||||
- sudo apt-get -q install libprotoc-dev libprotobuf7 libprotobuf-dev libosmpbf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
|
||||
- sudo apt-get -q install g++-4.7
|
||||
- sudo apt-get install libboost1.54-all-dev
|
||||
#luabind
|
||||
- curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
|
||||
#osmosis
|
||||
- curl -s https://gist.githubusercontent.com/DennisOSRM/803a64a9178ec375069f/raw/ | sudo bash
|
||||
before_script:
|
||||
- rvm use 1.9.3
|
||||
- gem install bundler
|
||||
- bundle install
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake .. $CMAKEOPTIONS
|
||||
script:
|
||||
- make -j 2
|
||||
- cd ..
|
||||
- cucumber -p verify
|
||||
after_script:
|
||||
# - cd ..
|
||||
# - cucumber -p verify
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
cache:
|
||||
- bundler
|
||||
- apt
|
||||
env:
|
||||
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-4.7" OSRM_PORT=5000 OSRM_TIMEOUT=60
|
||||
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=g++-4.7" OSRM_PORT=5010 OSRM_TIMEOUT=60
|
||||
notifications:
|
||||
irc:
|
||||
channels:
|
||||
- irc.oftc.net#osrm
|
||||
on_success: change
|
||||
on_failure: always
|
||||
use_notice: true
|
||||
skip_join: false
|
||||
|
||||
recipients:
|
||||
- dennis@mapbox.com
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: always
|
|
@ -11,6 +11,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||
include(CheckCXXCompilerFlag)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
include(GetGitRevisionDescription)
|
||||
git_describe(GIT_DESCRIPTION)
|
||||
|
@ -41,28 +43,29 @@ add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp FingerPrint.c
|
|||
VERBATIM)
|
||||
|
||||
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp)
|
||||
add_custom_target(tests DEPENDS datastructure-tests)
|
||||
add_custom_target(benchmarks DEPENDS rtree-bench)
|
||||
|
||||
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
|
||||
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
|
||||
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp
|
||||
)
|
||||
file(GLOB ExtractorGlob Extractor/*.cpp)
|
||||
file(GLOB ExtractorGlobH Extractor/*.h)
|
||||
file(GLOB ImporterGlob DataStructures/Import*.cpp)
|
||||
add_library(IMPORT OBJECT ${ImporterGlob})
|
||||
add_library(LOGGER OBJECT Util/simple_logger.cpp)
|
||||
|
||||
set(ExtractorSources extractor.cpp ${ExtractorGlob})
|
||||
set(ExtractorSources extractor.cpp ${ExtractorGlob} ${ExtractorGlobH})
|
||||
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
|
||||
|
||||
file(GLOB PrepareGlobH Contractor/*.h DataStructures/*.h)
|
||||
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp DataStructures/RestrictionMap.cpp Util/compute_angle.cpp)
|
||||
set(PrepareSources prepare.cpp ${PrepareGlob})
|
||||
set(PrepareSources prepare.cpp ${PrepareGlob} ${PrepareGlobH})
|
||||
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
|
||||
|
||||
file(GLOB ServerGlob Server/*.cpp)
|
||||
file(GLOB RoutingAlgs RoutingAlgorithms/*.h)
|
||||
file(GLOB DescriptorGlob Descriptors/*.cpp)
|
||||
file(GLOB DatastructureGlob DataStructures/SearchEngineData.cpp DataStructures/RouteParameters.cpp)
|
||||
list(REMOVE_ITEM DatastructureGlob DataStructures/Coordinate.cpp)
|
||||
|
@ -70,7 +73,9 @@ file(GLOB CoordinateGlob DataStructures/Coordinate.cpp)
|
|||
file(GLOB AlgorithmGlob Algorithms/*.cpp)
|
||||
file(GLOB HttpGlob Server/Http/*.cpp)
|
||||
file(GLOB LibOSRMGlob Library/*.cpp)
|
||||
file(GLOB DataStructureTestsGlob UnitTests/DataStructures/*.cpp DataStructures/HilbertValue.cpp)
|
||||
|
||||
file(GLOB MapsMeSources mapsme/*.cpp)
|
||||
file(GLOB MapsMeHeaders mapsme/*.h)
|
||||
|
||||
set(
|
||||
OSRMSources
|
||||
|
@ -87,14 +92,10 @@ add_library(GITDESCRIPTION OBJECT Util/GitDescription.cpp)
|
|||
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
|
||||
add_dependencies(FINGERPRINT FingerPrintConfigure)
|
||||
|
||||
add_executable(osrm-routed routed.cpp ${ServerGlob})
|
||||
add_executable(osrm-routed routed.cpp ${ServerGlob} ${RoutingAlgs})
|
||||
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
|
||||
add_executable(osrm-mapsme ${MapsMeSources} ${MapsMeHeaders} "${CMAKE_SOURCE_DIR}/../../succinct/rs_bit_vector.cpp" $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE>)
|
||||
|
||||
# Unit tests
|
||||
add_executable(datastructure-tests EXCLUDE_FROM_ALL UnitTests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
|
||||
|
||||
# Benchmarks
|
||||
add_executable(rtree-bench EXCLUDE_FROM_ALL Benchmarks/StaticRTreeBench.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
|
||||
|
||||
# Check the release mode
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
|
@ -126,10 +127,6 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
|
|||
endif (HAS_LTO_FLAG)
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
add_definitions(-DBOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
|
||||
# Configuring compilers
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
# using Clang
|
||||
|
@ -141,6 +138,7 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
|||
add_definitions(-D_USE_MATH_DEFINES) # define M_PI, M_1_PI etc.
|
||||
add_definitions(-DWIN32)
|
||||
SET(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
|
||||
SET(OPTIONAL_OMP_LIB gomp)
|
||||
endif()
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
|
||||
# using Intel C++
|
||||
|
@ -193,16 +191,17 @@ target_link_libraries(osrm-extract ${Boost_LIBRARIES})
|
|||
target_link_libraries(osrm-prepare ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
|
||||
target_link_libraries(osrm-datastore ${Boost_LIBRARIES})
|
||||
target_link_libraries(datastructure-tests ${Boost_LIBRARIES})
|
||||
target_link_libraries(rtree-bench ${Boost_LIBRARIES})
|
||||
|
||||
target_link_libraries(osrm-mapsme ${Boost_LIBRARIES} OSRM
|
||||
debug "${CMAKE_SOURCE_DIR}/../../../../omim-build-debug/out/debug/libcoding.a"
|
||||
"${CMAKE_SOURCE_DIR}/../../../../omim-build-debug/out/debug/libbase.a"
|
||||
general "${CMAKE_SOURCE_DIR}/../../../../omim-build-release/out/release/libcoding.a"
|
||||
"${CMAKE_SOURCE_DIR}/../../../../omim-build-release/out/release/libbase.a")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT} ${OPTIONAL_OMP_LIB})
|
||||
target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(osrm-prepare ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(OSRM ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(datastructure-tests ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(rtree-bench ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
find_package(TBB REQUIRED)
|
||||
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
|
@ -212,8 +211,6 @@ target_link_libraries(osrm-datastore ${TBB_LIBRARIES})
|
|||
target_link_libraries(osrm-extract ${TBB_LIBRARIES})
|
||||
target_link_libraries(osrm-prepare ${TBB_LIBRARIES})
|
||||
target_link_libraries(osrm-routed ${TBB_LIBRARIES})
|
||||
target_link_libraries(datastructure-tests ${TBB_LIBRARIES})
|
||||
target_link_libraries(rtree-bench ${TBB_LIBRARIES})
|
||||
include_directories(${TBB_INCLUDE_DIR})
|
||||
|
||||
find_package( Luabind REQUIRED )
|
||||
|
@ -271,7 +268,6 @@ if(WITH_TOOLS OR BUILD_TOOLS)
|
|||
target_link_libraries(
|
||||
osrm-components
|
||||
${GDAL_LIBRARIES} ${Boost_LIBRARIES})
|
||||
install(TARGETS osrm-components DESTINATION bin)
|
||||
else()
|
||||
message(FATAL_ERROR "libgdal and/or development headers not found")
|
||||
endif()
|
||||
|
@ -285,16 +281,6 @@ if(WITH_TOOLS OR BUILD_TOOLS)
|
|||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(osrm-unlock-all rt)
|
||||
endif()
|
||||
add_executable(osrm-check-hsgr Tools/check-hsgr.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER>)
|
||||
target_link_libraries(osrm-check-hsgr ${Boost_LIBRARIES})
|
||||
add_executable(osrm-springclean Tools/springclean.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:GITDESCRIPTION>)
|
||||
target_link_libraries(osrm-springclean ${Boost_LIBRARIES})
|
||||
|
||||
install(TARGETS osrm-cli DESTINATION bin)
|
||||
install(TARGETS osrm-io-benchmark DESTINATION bin)
|
||||
install(TARGETS osrm-unlock-all DESTINATION bin)
|
||||
install(TARGETS osrm-check-hsgr DESTINATION bin)
|
||||
install(TARGETS osrm-springclean DESTINATION bin)
|
||||
endif()
|
||||
|
||||
file(GLOB InstallGlob Include/osrm/*.h Library/OSRM.h)
|
||||
|
|
|
@ -42,6 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
||||
const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
|
||||
const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph_origin,
|
||||
std::unique_ptr<RestrictionMap> restriction_map,
|
||||
std::vector<NodeID> &barrier_node_list,
|
||||
std::vector<NodeID> &traffic_light_node_list,
|
||||
|
@ -50,6 +51,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
|||
: speed_profile(speed_profile),
|
||||
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
|
||||
m_node_info_list(node_info_list), m_node_based_graph(node_based_graph),
|
||||
m_node_based_graph_origin(node_based_graph_origin),
|
||||
m_restriction_map(std::move(restriction_map)), max_id(0)
|
||||
{
|
||||
|
||||
|
@ -78,6 +80,11 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes)
|
|||
nodes.swap(m_edge_based_node_list);
|
||||
}
|
||||
|
||||
void EdgeBasedGraphFactory::GetEdgeBasedNodeData(osrm::NodeDataVectorT &data)
|
||||
{
|
||||
data.swap(m_edge_based_node_data);
|
||||
}
|
||||
|
||||
void
|
||||
EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID node_v, const bool belongs_to_tiny_cc)
|
||||
{
|
||||
|
@ -171,7 +178,9 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
|
|||
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
|
||||
|
||||
// build edges
|
||||
m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID,
|
||||
m_edge_based_node_list.emplace_back(forward_data.way_id,
|
||||
reverse_data.way_id,
|
||||
forward_data.edgeBasedNodeID,
|
||||
reverse_data.edgeBasedNodeID,
|
||||
current_edge_source_coordinate_id,
|
||||
current_edge_target_coordinate_id,
|
||||
|
@ -223,7 +232,9 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
|
|||
BOOST_ASSERT(forward_data.edgeBasedNodeID != SPECIAL_NODEID ||
|
||||
reverse_data.edgeBasedNodeID != SPECIAL_NODEID);
|
||||
|
||||
m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID,
|
||||
m_edge_based_node_list.emplace_back(forward_data.way_id,
|
||||
reverse_data.way_id,
|
||||
forward_data.edgeBasedNodeID,
|
||||
reverse_data.edgeBasedNodeID,
|
||||
node_u,
|
||||
node_v,
|
||||
|
@ -273,6 +284,10 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
|||
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state);
|
||||
TIMER_STOP(generate_edges);
|
||||
|
||||
TIMER_START(generate_node_data);
|
||||
GenerateEdgeBasedNodeData();
|
||||
TIMER_STOP(generate_node_data);
|
||||
|
||||
m_geometry_compressor.SerializeInternalVector(geometry_filename);
|
||||
|
||||
SimpleLogger().Write() << "Timing statistics for edge-expanded graph:";
|
||||
|
@ -280,6 +295,7 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
|||
SimpleLogger().Write() << "Renumbering edges: " << TIMER_SEC(renumber) << "s";
|
||||
SimpleLogger().Write() << "Generating nodes: " << TIMER_SEC(generate_nodes) << "s";
|
||||
SimpleLogger().Write() << "Generating edges: " << TIMER_SEC(generate_edges) << "s";
|
||||
SimpleLogger().Write() << "Generating node data: " << TIMER_SEC(generate_node_data) << "s";
|
||||
}
|
||||
|
||||
void EdgeBasedGraphFactory::CompressGeometry()
|
||||
|
@ -466,6 +482,104 @@ void EdgeBasedGraphFactory::RenumberEdges()
|
|||
m_number_of_edge_based_nodes = numbered_edges_count;
|
||||
}
|
||||
|
||||
void EdgeBasedGraphFactory::GenerateEdgeBasedNodeData()
|
||||
{
|
||||
BOOST_ASSERT(m_node_based_graph->GetNumberOfNodes() == m_node_based_graph_origin->GetNumberOfNodes());
|
||||
|
||||
m_edge_based_node_data.resize(m_number_of_edge_based_nodes);
|
||||
std::vector<bool> found;
|
||||
found.resize(m_number_of_edge_based_nodes, false);
|
||||
|
||||
for (NodeID current_node = 0; current_node < m_node_based_graph->GetNumberOfNodes();
|
||||
++current_node)
|
||||
{
|
||||
for (EdgeID current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node))
|
||||
{
|
||||
EdgeData & edge_data = m_node_based_graph->GetEdgeData(current_edge);
|
||||
if (!edge_data.forward)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
NodeID target = m_node_based_graph->GetTarget(current_edge);
|
||||
|
||||
osrm::NodeData data;
|
||||
if (m_geometry_compressor.HasEntryForID(current_edge))
|
||||
{
|
||||
const std::vector<GeometryCompressor::CompressedNode> & via_nodes = m_geometry_compressor.GetBucketReference(current_edge);
|
||||
assert(via_nodes.size() > 0);
|
||||
std::vector< std::pair< NodeID, FixedPointCoordinate > > nodes;
|
||||
if (via_nodes.front().first != current_node)
|
||||
nodes.emplace_back(current_node, FixedPointCoordinate(m_node_info_list[current_node].lat, m_node_info_list[current_node].lon));
|
||||
for (auto n : via_nodes)
|
||||
nodes.emplace_back(n.first, FixedPointCoordinate(m_node_info_list[n.first].lat, m_node_info_list[n.first].lon));
|
||||
if (via_nodes.back().first != target)
|
||||
nodes.emplace_back(target, FixedPointCoordinate(m_node_info_list[target].lat, m_node_info_list[target].lon));
|
||||
|
||||
for (uint32_t i = 1; i < nodes.size(); ++i)
|
||||
{
|
||||
auto n1 = nodes[i - 1];
|
||||
auto n2 = nodes[i];
|
||||
|
||||
if (n1.first == n2.first)
|
||||
{
|
||||
SimpleLogger().Write() << "Error: Equal values " << n1.first << " and " << n2.first;
|
||||
SimpleLogger().Write() << "i: "<< i << " nodes: " << nodes.size();
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
EdgeID e = m_node_based_graph_origin->FindEdge(n1.first, n2.first);
|
||||
if (e == SPECIAL_EDGEID)
|
||||
{
|
||||
SimpleLogger().Write() << "Error: Can't find edge between nodes " << n1.first << " and " << n2.first;
|
||||
continue;
|
||||
}
|
||||
|
||||
EdgeData &ed = m_node_based_graph_origin->GetEdgeData(e);
|
||||
|
||||
data.AddSegment(ed.way_id,
|
||||
m_node_info_list[n1.first].lat / COORDINATE_PRECISION,
|
||||
m_node_info_list[n1.first].lon / COORDINATE_PRECISION,
|
||||
m_node_info_list[n2.first].lat / COORDINATE_PRECISION,
|
||||
m_node_info_list[n2.first].lon / COORDINATE_PRECISION);
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
data.AddSegment(edge_data.way_id,
|
||||
m_node_info_list[current_node].lat / COORDINATE_PRECISION,
|
||||
m_node_info_list[current_node].lon / COORDINATE_PRECISION,
|
||||
m_node_info_list[target].lat / COORDINATE_PRECISION,
|
||||
m_node_info_list[target].lon / COORDINATE_PRECISION);
|
||||
}
|
||||
|
||||
if (found[edge_data.edgeBasedNodeID])
|
||||
{
|
||||
if (m_edge_based_node_data[edge_data.edgeBasedNodeID] != data)
|
||||
{
|
||||
std::cout << "Error!" << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
} else
|
||||
{
|
||||
found[edge_data.edgeBasedNodeID] = true;
|
||||
m_edge_based_node_data[edge_data.edgeBasedNodeID] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto v : found)
|
||||
{
|
||||
if (!v)
|
||||
{
|
||||
std::cout << "Error2" << std::endl;
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleLogger().Write() << "Edge based node data count: " << m_edge_based_node_data.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the nodes in the edge expanded graph from edges in the node-based graph.
|
||||
*/
|
||||
|
|
|
@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "../DataStructures/TurnInstructions.h"
|
||||
#include "../DataStructures/NodeBasedGraph.h"
|
||||
#include "../DataStructures/RestrictionMap.h"
|
||||
#include "../DataStructures/EdgeBasedNodeData.h"
|
||||
#include "GeometryCompressor.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -60,6 +61,7 @@ class EdgeBasedGraphFactory
|
|||
struct SpeedProfileProperties;
|
||||
|
||||
explicit EdgeBasedGraphFactory(const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
|
||||
const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph_origin,
|
||||
std::unique_ptr<RestrictionMap> restricion_map,
|
||||
std::vector<NodeID> &barrier_node_list,
|
||||
std::vector<NodeID> &traffic_light_node_list,
|
||||
|
@ -74,6 +76,8 @@ class EdgeBasedGraphFactory
|
|||
|
||||
void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes);
|
||||
|
||||
void GetEdgeBasedNodeData(osrm::NodeDataVectorT &data);
|
||||
|
||||
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, const double angle) const;
|
||||
|
||||
int GetTurnPenalty(double angle, lua_State *lua_state) const;
|
||||
|
@ -102,15 +106,18 @@ class EdgeBasedGraphFactory
|
|||
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
|
||||
|
||||
std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
|
||||
std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph_origin;
|
||||
std::unordered_set<NodeID> m_barrier_nodes;
|
||||
std::unordered_set<NodeID> m_traffic_lights;
|
||||
|
||||
std::unique_ptr<RestrictionMap> m_restriction_map;
|
||||
std::vector<osrm::NodeData> m_edge_based_node_data;
|
||||
|
||||
GeometryCompressor m_geometry_compressor;
|
||||
|
||||
void CompressGeometry();
|
||||
void RenumberEdges();
|
||||
void GenerateEdgeBasedNodeData();
|
||||
void GenerateEdgeExpandedNodes();
|
||||
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
|
||||
lua_State *lua_state);
|
||||
|
|
|
@ -117,6 +117,7 @@ int Prepare::Process(int argc, char *argv[])
|
|||
graph_out = input_path.string() + ".hsgr";
|
||||
rtree_nodes_path = input_path.string() + ".ramIndex";
|
||||
rtree_leafs_path = input_path.string() + ".fileIndex";
|
||||
node_data_filename = input_path.string() + ".nodeData";
|
||||
|
||||
/*** Setup Scripting Environment ***/
|
||||
// Create a new lua state
|
||||
|
@ -135,7 +136,7 @@ int Prepare::Process(int argc, char *argv[])
|
|||
#ifdef WIN32
|
||||
#pragma message("Memory consumption on Windows can be higher due to different bit packing")
|
||||
#else
|
||||
static_assert(sizeof(ImportEdge) == 20,
|
||||
static_assert(sizeof(ImportEdge) == 24,
|
||||
"changing ImportEdge type has influence on memory consumption!");
|
||||
#endif
|
||||
NodeID number_of_node_based_nodes =
|
||||
|
@ -504,8 +505,13 @@ Prepare::BuildEdgeExpandedGraph(lua_State *lua_state,
|
|||
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
|
||||
std::unique_ptr<RestrictionMap> restriction_map =
|
||||
std::unique_ptr<RestrictionMap>(new RestrictionMap(node_based_graph, restriction_list));
|
||||
|
||||
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph_origin =
|
||||
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
|
||||
|
||||
std::shared_ptr<EdgeBasedGraphFactory> edge_based_graph_factory =
|
||||
std::make_shared<EdgeBasedGraphFactory>(node_based_graph,
|
||||
node_based_graph_origin,
|
||||
std::move(restriction_map),
|
||||
barrier_node_list,
|
||||
traffic_light_list,
|
||||
|
@ -535,6 +541,14 @@ Prepare::BuildEdgeExpandedGraph(lua_State *lua_state,
|
|||
edge_based_graph_factory->GetEdgeBasedEdges(edge_based_edge_list);
|
||||
edge_based_graph_factory->GetEdgeBasedNodes(node_based_edge_list);
|
||||
|
||||
// serialize node data
|
||||
osrm::NodeDataVectorT data;
|
||||
edge_based_graph_factory->GetEdgeBasedNodeData(data);
|
||||
|
||||
SimpleLogger().Write() << "Serialize node data";
|
||||
|
||||
osrm::SaveNodeDataToFile(node_data_filename, data);
|
||||
|
||||
edge_based_graph_factory.reset();
|
||||
node_based_graph.reset();
|
||||
|
||||
|
@ -565,10 +579,10 @@ void Prepare::WriteNodeMapping()
|
|||
|
||||
Saves info to files: '.ramIndex' and '.fileIndex'.
|
||||
*/
|
||||
void Prepare::BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list)
|
||||
void Prepare::BuildRTree(std::vector<EdgeBasedNode> &edge_based_node_list)
|
||||
{
|
||||
SimpleLogger().Write() << "building r-tree ...";
|
||||
StaticRTree<EdgeBasedNode>(node_based_edge_list,
|
||||
StaticRTree<EdgeBasedNode>(edge_based_node_list,
|
||||
rtree_nodes_path.c_str(),
|
||||
rtree_leafs_path.c_str(),
|
||||
internal_to_external_node_map);
|
||||
|
|
|
@ -62,6 +62,7 @@ class Prepare
|
|||
std::string graph_out;
|
||||
std::string rtree_nodes_path;
|
||||
std::string rtree_leafs_path;
|
||||
std::string node_data_filename;
|
||||
};
|
||||
|
||||
#endif // PREPARE_H
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "../DataStructures/TravelMode.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
#include "../Include/osrm/Coordinate.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
|
@ -14,6 +14,8 @@ struct EdgeBasedNode
|
|||
{
|
||||
|
||||
EdgeBasedNode() :
|
||||
forward_way_id(-1),
|
||||
reverse_way_id(-1),
|
||||
forward_edge_based_node_id(SPECIAL_NODEID),
|
||||
reverse_edge_based_node_id(SPECIAL_NODEID),
|
||||
u(SPECIAL_NODEID),
|
||||
|
@ -31,6 +33,8 @@ struct EdgeBasedNode
|
|||
{ }
|
||||
|
||||
explicit EdgeBasedNode(
|
||||
unsigned forward_way_id,
|
||||
unsigned reverse_way_id,
|
||||
NodeID forward_edge_based_node_id,
|
||||
NodeID reverse_edge_based_node_id,
|
||||
NodeID u,
|
||||
|
@ -46,6 +50,8 @@ struct EdgeBasedNode
|
|||
TravelMode forward_travel_mode,
|
||||
TravelMode backward_travel_mode
|
||||
) :
|
||||
forward_way_id(forward_way_id),
|
||||
reverse_way_id(reverse_way_id),
|
||||
forward_edge_based_node_id(forward_edge_based_node_id),
|
||||
reverse_edge_based_node_id(reverse_edge_based_node_id),
|
||||
u(u),
|
||||
|
@ -79,6 +85,8 @@ struct EdgeBasedNode
|
|||
return packed_geometry_id != SPECIAL_EDGEID;
|
||||
}
|
||||
|
||||
unsigned forward_way_id;
|
||||
unsigned reverse_way_id;
|
||||
NodeID forward_edge_based_node_id; // needed for edge-expanded graph
|
||||
NodeID reverse_edge_based_node_id; // needed for edge-expanded graph
|
||||
NodeID u; // indices into the coordinates array
|
||||
|
|
123
3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h
Normal file
123
3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h
Normal file
|
@ -0,0 +1,123 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
|
||||
struct NodeData
|
||||
{
|
||||
#pragma pack (push, 1)
|
||||
struct SegmentInfo
|
||||
{
|
||||
uint64_t wayId;
|
||||
double lat1, lon1, lat2, lon2;
|
||||
|
||||
SegmentInfo()
|
||||
: wayId(-1), lat1(-10000), lon1(-10000), lat2(-10000), lon2(-10000)
|
||||
{
|
||||
}
|
||||
|
||||
SegmentInfo(uint64_t wayId, double lat1, double lon1, double lat2, double lon2)
|
||||
: wayId(wayId), lat1(lat1), lon1(lon1), lat2(lat2), lon2(lon2)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator != (SegmentInfo const & other) const
|
||||
{
|
||||
return wayId != other.wayId || lat1 != other.lat1 || lon1 != other.lon1 ||
|
||||
lat2 != other.lat2 || lon2 != other.lon2;
|
||||
}
|
||||
};
|
||||
#pragma pack (pop)
|
||||
|
||||
typedef std::vector<SegmentInfo> SegmentInfoVectorT;
|
||||
SegmentInfoVectorT m_segments;
|
||||
|
||||
NodeData()
|
||||
{
|
||||
}
|
||||
|
||||
NodeData(SegmentInfoVectorT & vec)
|
||||
{
|
||||
m_segments.swap(vec);
|
||||
}
|
||||
|
||||
bool operator == (NodeData const & other) const
|
||||
{
|
||||
if (m_segments.size() != other.m_segments.size())
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 0; i < m_segments.size(); ++i)
|
||||
if (m_segments[i] != other.m_segments[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator != (NodeData const & other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void AddSegment(uint64_t wayId, double lat1, double lon1, double lat2, double lon2)
|
||||
{
|
||||
m_segments.emplace_back(wayId, lat1, lon1, lat2, lon2);
|
||||
}
|
||||
|
||||
void SetSegments(SegmentInfoVectorT & segments)
|
||||
{
|
||||
m_segments.swap(segments);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<NodeData> NodeDataVectorT;
|
||||
|
||||
inline bool SaveNodeDataToFile(std::string const & filename, NodeDataVectorT const & data)
|
||||
{
|
||||
std::ofstream stream;
|
||||
stream.open(filename);
|
||||
if (!stream.is_open())
|
||||
return false;
|
||||
|
||||
uint32_t count = data.size();
|
||||
stream.write((char*)&count, sizeof(count));
|
||||
for (auto d : data)
|
||||
{
|
||||
uint32_t pc = d.m_segments.size();
|
||||
stream.write((char*)&pc, sizeof(pc));
|
||||
stream.write((char*)d.m_segments.data(), sizeof(NodeData::SegmentInfo) * pc);
|
||||
}
|
||||
stream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool LoadNodeDataFromFile(std::string const & filename, NodeDataVectorT & data)
|
||||
{
|
||||
std::ifstream stream;
|
||||
stream.open(filename);
|
||||
if (!stream.is_open())
|
||||
return false;
|
||||
|
||||
uint32_t count = 0;
|
||||
stream.read((char*)&count, sizeof(count));
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
uint32_t pc;
|
||||
stream.read((char*)&pc, sizeof(pc));
|
||||
NodeData::SegmentInfoVectorT segments;
|
||||
segments.resize(pc);
|
||||
stream.read((char*)segments.data(), sizeof(NodeData::SegmentInfo) * pc);
|
||||
|
||||
data.emplace_back(segments);
|
||||
}
|
||||
stream.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -46,7 +46,8 @@ bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const
|
|||
return source < other.source;
|
||||
}
|
||||
|
||||
NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
NodeBasedEdge::NodeBasedEdge(unsigned way_id,
|
||||
NodeID source,
|
||||
NodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
|
@ -57,7 +58,7 @@ NodeBasedEdge::NodeBasedEdge(NodeID source,
|
|||
bool access_restricted,
|
||||
TravelMode travel_mode,
|
||||
bool is_split)
|
||||
: source(source), target(target), name_id(name_id), weight(weight),
|
||||
: way_id(way_id), source(source), target(target), name_id(name_id), weight(weight),
|
||||
forward(forward), backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
|
||||
access_restricted(access_restricted), is_split(is_split), travel_mode(travel_mode)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,8 @@ struct NodeBasedEdge
|
|||
{
|
||||
bool operator<(const NodeBasedEdge &e) const;
|
||||
|
||||
explicit NodeBasedEdge(NodeID source,
|
||||
explicit NodeBasedEdge(unsigned way_id,
|
||||
NodeID source,
|
||||
NodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
|
@ -47,6 +48,7 @@ struct NodeBasedEdge
|
|||
TravelMode travel_mode,
|
||||
bool is_split);
|
||||
|
||||
unsigned way_id;
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
NodeID name_id;
|
||||
|
|
|
@ -12,13 +12,14 @@
|
|||
struct NodeBasedEdgeData
|
||||
{
|
||||
NodeBasedEdgeData()
|
||||
: distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID),
|
||||
: way_id(-1), distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID),
|
||||
nameID(std::numeric_limits<unsigned>::max()),
|
||||
isAccessRestricted(false), shortcut(false), forward(false), backward(false),
|
||||
roundabout(false), ignore_in_grid(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned way_id;
|
||||
int distance;
|
||||
unsigned edgeBasedNodeID;
|
||||
unsigned nameID;
|
||||
|
@ -58,7 +59,7 @@ using SimpleNodeBasedDynamicGraph = DynamicGraph<SimpleEdgeData>;
|
|||
inline std::shared_ptr<NodeBasedDynamicGraph>
|
||||
NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge> &input_edge_list)
|
||||
{
|
||||
static_assert(sizeof(NodeBasedEdgeData) == 16, "changing node based edge data size changes memory consumption");
|
||||
static_assert(sizeof(NodeBasedEdgeData) == 20, "changing node based edge data size changes memory consumption");
|
||||
|
||||
DeallocatingVector<NodeBasedDynamicGraph::InputEdge> edges_list;
|
||||
NodeBasedDynamicGraph::InputEdge edge;
|
||||
|
@ -79,6 +80,8 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge
|
|||
edge.data.forward = import_edge.backward;
|
||||
}
|
||||
|
||||
edge.data.way_id = import_edge.way_id;
|
||||
|
||||
if (edge.source == edge.target)
|
||||
{
|
||||
continue;
|
||||
|
@ -172,7 +175,7 @@ template<class SimpleEdgeT>
|
|||
inline std::shared_ptr<SimpleNodeBasedDynamicGraph>
|
||||
SimpleNodeBasedDynamicGraphFromEdges(int number_of_nodes, std::vector<SimpleEdgeT> &input_edge_list)
|
||||
{
|
||||
static_assert(sizeof(NodeBasedEdgeData) == 16, "changing node based edge data size changes memory consumption");
|
||||
static_assert(sizeof(NodeBasedEdgeData) == 20, "changing node based edge data size changes memory consumption");
|
||||
tbb::parallel_sort(input_edge_list.begin(), input_edge_list.end());
|
||||
|
||||
DeallocatingVector<SimpleNodeBasedDynamicGraph::InputEdge> edges_list;
|
||||
|
|
|
@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef PHANTOM_NODES_H
|
||||
#define PHANTOM_NODES_H
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
#include "../Include/osrm/Coordinate.h"
|
||||
#include "../DataStructures/TravelMode.h"
|
||||
#include "../Util/simple_logger.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
|
|
@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
#include "../Include/osrm/Coordinate.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef SEARCH_ENGINE_DATA_H
|
||||
#define SEARCH_ENGINE_DATA_H
|
||||
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "BinaryHeap.h"
|
||||
|
@ -42,7 +42,7 @@ struct HeapData
|
|||
struct SearchEngineData
|
||||
{
|
||||
using QueryHeap = BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>>;
|
||||
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
|
||||
using SearchEngineHeapPtr = boost::scoped_ptr<QueryHeap>;
|
||||
|
||||
static SearchEngineHeapPtr forwardHeap;
|
||||
static SearchEngineHeapPtr backwardHeap;
|
||||
|
|
|
@ -34,16 +34,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/interprocess/mapped_region.hpp>
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(__ANDROID__)
|
||||
#include <boost/interprocess/xsi_shared_memory.hpp>
|
||||
#else
|
||||
#include <boost/interprocess/shared_memory_object.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
//#ifdef __linux__
|
||||
//#include <sys/ipc.h>
|
||||
//#include <sys/shm.h>
|
||||
//#endif
|
||||
|
||||
// #include <cstring>
|
||||
#include <cstdint>
|
||||
|
@ -61,7 +61,7 @@ struct OSRMLockFile
|
|||
}
|
||||
};
|
||||
|
||||
#ifndef WIN32
|
||||
#if !defined(WIN32) && !defined(__ANDROID__)
|
||||
class SharedMemory
|
||||
{
|
||||
|
||||
|
|
|
@ -35,8 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
@ -88,7 +86,7 @@ template <typename EdgeDataT, bool UseSharedMemory = false> class StaticGraph
|
|||
|
||||
StaticGraph(const int nodes, std::vector<InputEdge> &graph)
|
||||
{
|
||||
tbb::parallel_sort(graph.begin(), graph.end());
|
||||
std::sort(graph.begin(), graph.end());
|
||||
number_of_nodes = nodes;
|
||||
number_of_edges = (EdgeIterator)graph.size();
|
||||
node_array.resize(number_of_nodes + 1);
|
||||
|
|
|
@ -50,9 +50,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
|
@ -354,38 +351,31 @@ class StaticRTree
|
|||
HilbertCode get_hilbert_number;
|
||||
|
||||
// generate auxiliary vector of hilbert-values
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<uint64_t>(0, m_element_count),
|
||||
[&input_data_vector, &input_wrapper_vector, &get_hilbert_number, &coordinate_list](
|
||||
const tbb::blocked_range<uint64_t> &range)
|
||||
{
|
||||
for (uint64_t element_counter = range.begin(); element_counter != range.end();
|
||||
++element_counter)
|
||||
{
|
||||
WrappedInputElement ¤t_wrapper = input_wrapper_vector[element_counter];
|
||||
current_wrapper.m_array_index = element_counter;
|
||||
for (uint64_t element_counter = 0; element_counter != m_element_count; ++element_counter)
|
||||
{
|
||||
WrappedInputElement ¤t_wrapper = input_wrapper_vector[element_counter];
|
||||
current_wrapper.m_array_index = element_counter;
|
||||
|
||||
EdgeDataT const ¤t_element = input_data_vector[element_counter];
|
||||
EdgeDataT const ¤t_element = input_data_vector[element_counter];
|
||||
|
||||
// Get Hilbert-Value for centroid in mercartor projection
|
||||
FixedPointCoordinate current_centroid = EdgeDataT::Centroid(
|
||||
FixedPointCoordinate(coordinate_list.at(current_element.u).lat,
|
||||
coordinate_list.at(current_element.u).lon),
|
||||
FixedPointCoordinate(coordinate_list.at(current_element.v).lat,
|
||||
coordinate_list.at(current_element.v).lon));
|
||||
current_centroid.lat =
|
||||
COORDINATE_PRECISION * lat2y(current_centroid.lat / COORDINATE_PRECISION);
|
||||
// Get Hilbert-Value for centroid in mercartor projection
|
||||
FixedPointCoordinate current_centroid = EdgeDataT::Centroid(
|
||||
FixedPointCoordinate(coordinate_list.at(current_element.u).lat,
|
||||
coordinate_list.at(current_element.u).lon),
|
||||
FixedPointCoordinate(coordinate_list.at(current_element.v).lat,
|
||||
coordinate_list.at(current_element.v).lon));
|
||||
current_centroid.lat =
|
||||
COORDINATE_PRECISION * lat2y(current_centroid.lat / COORDINATE_PRECISION);
|
||||
|
||||
current_wrapper.m_hilbert_value = get_hilbert_number(current_centroid);
|
||||
}
|
||||
});
|
||||
current_wrapper.m_hilbert_value = get_hilbert_number(current_centroid);
|
||||
}
|
||||
|
||||
// open leaf file
|
||||
boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
|
||||
leaf_node_file.write((char *)&m_element_count, sizeof(uint64_t));
|
||||
|
||||
// sort the hilbert-value representatives
|
||||
tbb::parallel_sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
|
||||
sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
|
||||
std::vector<TreeNode> tree_nodes_in_level;
|
||||
|
||||
// pack M elements into leaf node and write to leaf file
|
||||
|
@ -467,20 +457,17 @@ class StaticRTree
|
|||
std::reverse(m_search_tree.begin(), m_search_tree.end());
|
||||
|
||||
uint32_t search_tree_size = m_search_tree.size();
|
||||
tbb::parallel_for(tbb::blocked_range<uint32_t>(0, search_tree_size),
|
||||
[this, &search_tree_size](const tbb::blocked_range<uint32_t> &range)
|
||||
{
|
||||
for (uint32_t i = range.begin(); i != range.end(); ++i)
|
||||
{
|
||||
TreeNode ¤t_tree_node = this->m_search_tree[i];
|
||||
for (uint32_t j = 0; j < current_tree_node.child_count; ++j)
|
||||
{
|
||||
const uint32_t old_id = current_tree_node.children[j];
|
||||
const uint32_t new_id = search_tree_size - old_id - 1;
|
||||
current_tree_node.children[j] = new_id;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (uint32_t i = 0; i != search_tree_size; ++i)
|
||||
{
|
||||
TreeNode ¤t_tree_node = this->m_search_tree[i];
|
||||
for (uint32_t j = 0; j < current_tree_node.child_count; ++j)
|
||||
{
|
||||
const uint32_t old_id = current_tree_node.children[j];
|
||||
const uint32_t new_id = search_tree_size - old_id - 1;
|
||||
current_tree_node.children[j] = new_id;
|
||||
}
|
||||
}
|
||||
|
||||
// open tree file
|
||||
boost::filesystem::ofstream tree_node_file(tree_node_filename, std::ios::binary);
|
||||
|
|
|
@ -348,6 +348,7 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
|
|||
short zero = 0;
|
||||
short one = 1;
|
||||
|
||||
file_out_stream.write((char *)&edge_iterator->way_id, sizeof(unsigned));
|
||||
file_out_stream.write((char *)&edge_iterator->start, sizeof(unsigned));
|
||||
file_out_stream.write((char *)&edge_iterator->target, sizeof(unsigned));
|
||||
file_out_stream.write((char *)&integer_distance, sizeof(int));
|
||||
|
|
|
@ -128,6 +128,7 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
|
|||
for (unsigned n = 0; n < (parsed_way.path.size() - 1); ++n)
|
||||
{
|
||||
external_memory.all_edges_list.push_back(InternalExtractorEdge(
|
||||
parsed_way.id,
|
||||
parsed_way.path[n],
|
||||
parsed_way.path[n + 1],
|
||||
((split_edge || TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode) ? ExtractionWay::oneway
|
||||
|
@ -160,7 +161,8 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
|
|||
for (std::vector<NodeID>::size_type n = 0; n < parsed_way.path.size() - 1; ++n)
|
||||
{
|
||||
external_memory.all_edges_list.push_back(
|
||||
InternalExtractorEdge(parsed_way.path[n],
|
||||
InternalExtractorEdge(parsed_way.id,
|
||||
parsed_way.path[n],
|
||||
parsed_way.path[n + 1],
|
||||
ExtractionWay::oneway,
|
||||
parsed_way.backward_speed,
|
||||
|
|
|
@ -37,13 +37,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
struct InternalExtractorEdge
|
||||
{
|
||||
InternalExtractorEdge()
|
||||
: start(0), target(0), direction(0), speed(0), name_id(0), is_roundabout(false),
|
||||
: way_id(0), start(0), target(0), direction(0), speed(0), name_id(0), is_roundabout(false),
|
||||
is_in_tiny_cc(false), is_duration_set(false), is_access_restricted(false),
|
||||
travel_mode(TRAVEL_MODE_INACCESSIBLE), is_split(false)
|
||||
{
|
||||
}
|
||||
|
||||
explicit InternalExtractorEdge(NodeID start,
|
||||
explicit InternalExtractorEdge(unsigned id,
|
||||
NodeID start,
|
||||
NodeID target,
|
||||
short direction,
|
||||
double speed,
|
||||
|
@ -54,7 +55,7 @@ struct InternalExtractorEdge
|
|||
bool is_access_restricted,
|
||||
TravelMode travel_mode,
|
||||
bool is_split)
|
||||
: start(start), target(target), direction(direction), speed(speed),
|
||||
: way_id(id), start(start), target(target), direction(direction), speed(speed),
|
||||
name_id(name_id), is_roundabout(is_roundabout), is_in_tiny_cc(is_in_tiny_cc),
|
||||
is_duration_set(is_duration_set), is_access_restricted(is_access_restricted),
|
||||
travel_mode(travel_mode), is_split(is_split)
|
||||
|
@ -64,14 +65,15 @@ struct InternalExtractorEdge
|
|||
// necessary static util functions for stxxl's sorting
|
||||
static InternalExtractorEdge min_value()
|
||||
{
|
||||
return InternalExtractorEdge(0, 0, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
|
||||
return InternalExtractorEdge(0, 0, 0, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
|
||||
}
|
||||
static InternalExtractorEdge max_value()
|
||||
{
|
||||
return InternalExtractorEdge(
|
||||
SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
|
||||
SPECIAL_NODEID, SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
|
||||
}
|
||||
|
||||
unsigned way_id;
|
||||
NodeID start;
|
||||
NodeID target;
|
||||
short direction;
|
||||
|
|
|
@ -97,7 +97,7 @@ template <class DataFacadeT> class BasicRoutingInterface
|
|||
// Stalling
|
||||
for (const auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const EdgeData &data = facade->GetEdgeData(edge);
|
||||
const EdgeData &data = facade->GetEdgeData(edge, node);
|
||||
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
|
||||
if (reverse_flag)
|
||||
{
|
||||
|
@ -118,7 +118,7 @@ template <class DataFacadeT> class BasicRoutingInterface
|
|||
|
||||
for (const auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const EdgeData &data = facade->GetEdgeData(edge);
|
||||
const EdgeData &data = facade->GetEdgeData(edge, node);
|
||||
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
|
||||
if (forward_directionFlag)
|
||||
{
|
||||
|
@ -163,6 +163,7 @@ template <class DataFacadeT> class BasicRoutingInterface
|
|||
recursion_stack.emplace(packed_path[i - 1], packed_path[i]);
|
||||
}
|
||||
|
||||
unpacked_path.emplace_back(packed_path[0], INVALID_EDGE_WEIGHT, TurnInstruction::NoTurn, INVALID_EDGE_WEIGHT, TRAVEL_MODE_INACCESSIBLE);
|
||||
std::pair<NodeID, NodeID> edge;
|
||||
while (!recursion_stack.empty())
|
||||
{
|
||||
|
@ -179,14 +180,17 @@ template <class DataFacadeT> class BasicRoutingInterface
|
|||
// facade->FindEdge does not suffice here in case of shortcuts.
|
||||
// The above explanation unclear? Think!
|
||||
EdgeID smaller_edge_id = SPECIAL_EDGEID;
|
||||
NodeID smaller_node_id = SPECIAL_NODEID;
|
||||
int edge_weight = std::numeric_limits<EdgeWeight>::max();
|
||||
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first))
|
||||
{
|
||||
const int weight = facade->GetEdgeData(edge_id).distance;
|
||||
auto const & edgeData = facade->GetEdgeData(edge_id, edge.first);
|
||||
const int weight = edgeData.distance;
|
||||
if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
|
||||
facade->GetEdgeData(edge_id).forward)
|
||||
edgeData.forward)
|
||||
{
|
||||
smaller_edge_id = edge_id;
|
||||
smaller_node_id = edge.first;
|
||||
edge_weight = weight;
|
||||
}
|
||||
}
|
||||
|
@ -202,18 +206,20 @@ template <class DataFacadeT> class BasicRoutingInterface
|
|||
{
|
||||
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.second))
|
||||
{
|
||||
const int weight = facade->GetEdgeData(edge_id).distance;
|
||||
auto const & edgeData = facade->GetEdgeData(edge_id, edge.second);
|
||||
const int weight = edgeData.distance;
|
||||
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) &&
|
||||
facade->GetEdgeData(edge_id).backward)
|
||||
edgeData.backward)
|
||||
{
|
||||
smaller_edge_id = edge_id;
|
||||
smaller_node_id = edge.second;
|
||||
edge_weight = weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_ASSERT_MSG(edge_weight != INVALID_EDGE_WEIGHT, "edge id invalid");
|
||||
|
||||
const EdgeData &ed = facade->GetEdgeData(smaller_edge_id);
|
||||
const EdgeData &ed = facade->GetEdgeData(smaller_edge_id, smaller_node_id);
|
||||
if (ed.shortcut)
|
||||
{ // unpack
|
||||
const NodeID middle_node_id = ed.id;
|
||||
|
@ -223,89 +229,12 @@ template <class DataFacadeT> class BasicRoutingInterface
|
|||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
|
||||
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
|
||||
const TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
|
||||
const TravelMode travel_mode = facade->GetTravelModeForEdgeID(ed.id);
|
||||
|
||||
|
||||
if (!facade->EdgeIsCompressed(ed.id))
|
||||
{
|
||||
BOOST_ASSERT(!facade->EdgeIsCompressed(ed.id));
|
||||
unpacked_path.emplace_back(facade->GetGeometryIndexForEdgeID(ed.id),
|
||||
name_index,
|
||||
turn_instruction,
|
||||
ed.distance,
|
||||
travel_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<unsigned> id_vector;
|
||||
facade->GetUncompressedGeometry(facade->GetGeometryIndexForEdgeID(ed.id),
|
||||
id_vector);
|
||||
|
||||
const std::size_t start_index =
|
||||
(unpacked_path.empty()
|
||||
? ((start_traversed_in_reverse)
|
||||
? id_vector.size() -
|
||||
phantom_node_pair.source_phantom.fwd_segment_position - 1
|
||||
: phantom_node_pair.source_phantom.fwd_segment_position)
|
||||
: 0);
|
||||
const std::size_t end_index = id_vector.size();
|
||||
|
||||
BOOST_ASSERT(start_index >= 0);
|
||||
BOOST_ASSERT(start_index <= end_index);
|
||||
for (std::size_t i = start_index; i < end_index; ++i)
|
||||
{
|
||||
unpacked_path.emplace_back(id_vector[i], name_index, TurnInstruction::NoTurn, 0, travel_mode);
|
||||
}
|
||||
unpacked_path.back().turn_instruction = turn_instruction;
|
||||
unpacked_path.back().segment_duration = ed.distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SPECIAL_EDGEID != phantom_node_pair.target_phantom.packed_geometry_id)
|
||||
{
|
||||
std::vector<unsigned> id_vector;
|
||||
facade->GetUncompressedGeometry(phantom_node_pair.target_phantom.packed_geometry_id,
|
||||
id_vector);
|
||||
const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id ==
|
||||
phantom_node_pair.target_phantom.packed_geometry_id) &&
|
||||
unpacked_path.empty();
|
||||
|
||||
std::size_t start_index = 0;
|
||||
if (is_local_path)
|
||||
{
|
||||
start_index = phantom_node_pair.source_phantom.fwd_segment_position;
|
||||
if (target_traversed_in_reverse)
|
||||
{
|
||||
start_index =
|
||||
id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t end_index = phantom_node_pair.target_phantom.fwd_segment_position;
|
||||
if (target_traversed_in_reverse)
|
||||
{
|
||||
std::reverse(id_vector.begin(), id_vector.end());
|
||||
end_index =
|
||||
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
|
||||
}
|
||||
|
||||
if (start_index > end_index)
|
||||
{
|
||||
start_index = std::min(start_index, id_vector.size()-1);
|
||||
}
|
||||
|
||||
for (std::size_t i = start_index; i != end_index; (start_index < end_index ? ++i : --i))
|
||||
{
|
||||
BOOST_ASSERT(i < id_vector.size());
|
||||
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode>0 );
|
||||
unpacked_path.emplace_back(PathData{id_vector[i],
|
||||
phantom_node_pair.target_phantom.name_id,
|
||||
unpacked_path.emplace_back(edge.second,
|
||||
INVALID_EDGE_WEIGHT,
|
||||
TurnInstruction::NoTurn,
|
||||
0,
|
||||
phantom_node_pair.target_phantom.forward_travel_mode});
|
||||
ed.distance,
|
||||
travel_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,14 +271,17 @@ template <class DataFacadeT> class BasicRoutingInterface
|
|||
recursion_stack.pop();
|
||||
|
||||
EdgeID smaller_edge_id = SPECIAL_EDGEID;
|
||||
NodeID smaller_node_id = SPECIAL_NODEID;
|
||||
int edge_weight = std::numeric_limits<EdgeWeight>::max();
|
||||
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first))
|
||||
{
|
||||
const int weight = facade->GetEdgeData(edge_id).distance;
|
||||
auto const & edgeData = facade->GetEdgeData(edge_id, edge.first);
|
||||
const int weight = edgeData.distance;
|
||||
if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
|
||||
facade->GetEdgeData(edge_id).forward)
|
||||
edgeData.forward)
|
||||
{
|
||||
smaller_edge_id = edge_id;
|
||||
smaller_node_id = edge.first;
|
||||
edge_weight = weight;
|
||||
}
|
||||
}
|
||||
|
@ -358,18 +290,20 @@ template <class DataFacadeT> class BasicRoutingInterface
|
|||
{
|
||||
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.second))
|
||||
{
|
||||
const int weight = facade->GetEdgeData(edge_id).distance;
|
||||
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) &&
|
||||
facade->GetEdgeData(edge_id).backward)
|
||||
auto const & edgeData = facade->GetEdgeData(edge_id, edge.second);
|
||||
const int weight = edgeData.distance;
|
||||
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) &&
|
||||
edgeData.backward)
|
||||
{
|
||||
smaller_edge_id = edge_id;
|
||||
smaller_node_id = edge.second;
|
||||
edge_weight = weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_ASSERT_MSG(edge_weight != std::numeric_limits<EdgeWeight>::max(), "edge weight invalid");
|
||||
|
||||
const EdgeData &ed = facade->GetEdgeData(smaller_edge_id);
|
||||
const EdgeData &ed = facade->GetEdgeData(smaller_edge_id, smaller_node_id);
|
||||
if (ed.shortcut)
|
||||
{ // unpack
|
||||
const NodeID middle_node_id = ed.id;
|
||||
|
|
|
@ -39,7 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "../../Util/StringUtil.h"
|
||||
#include "../../typedefs.h"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
#include "../../Include/osrm/Coordinate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -62,6 +62,8 @@ template <class EdgeDataT> class BaseDataFacade
|
|||
|
||||
virtual NodeID GetTarget(const EdgeID e) const = 0;
|
||||
|
||||
//virtual EdgeDataT &GetEdgeData(const EdgeID e, NodeID node) { static EdgeDataT edge; return edge; }
|
||||
|
||||
// virtual EdgeDataT &GetEdgeData(const EdgeID e) = 0;
|
||||
|
||||
virtual EdgeDataT GetEdgeData(const EdgeID e, NodeID node)
|
||||
|
|
|
@ -41,8 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -130,8 +128,11 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
|
|||
int length;
|
||||
bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
|
||||
TravelMode travel_mode;
|
||||
unsigned way_id;
|
||||
|
||||
for (EdgeID i = 0; i < m; ++i)
|
||||
{
|
||||
input_stream.read((char *)&way_id, sizeof(unsigned));
|
||||
input_stream.read((char *)&source, sizeof(unsigned));
|
||||
input_stream.read((char *)&target, sizeof(unsigned));
|
||||
input_stream.read((char *)&length, sizeof(int));
|
||||
|
@ -186,7 +187,8 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
|
|||
std::swap(forward, backward);
|
||||
}
|
||||
|
||||
edge_list.emplace_back(source,
|
||||
edge_list.emplace_back(way_id,
|
||||
source,
|
||||
target,
|
||||
nameID,
|
||||
weight,
|
||||
|
@ -199,7 +201,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
|
|||
is_split);
|
||||
}
|
||||
|
||||
tbb::parallel_sort(edge_list.begin(), edge_list.end());
|
||||
std::sort(edge_list.begin(), edge_list.end());
|
||||
for (unsigned i = 1; i < edge_list.size(); ++i)
|
||||
{
|
||||
if ((edge_list[i - 1].target == edge_list[i].target) &&
|
||||
|
@ -300,11 +302,13 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
|
|||
EdgeWeight weight;
|
||||
NodeID nameID;
|
||||
int length;
|
||||
unsigned way_id;
|
||||
bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
|
||||
TravelMode travel_mode;
|
||||
|
||||
for (EdgeID i = 0; i < m; ++i)
|
||||
{
|
||||
input_stream.read((char *)&way_id, sizeof(unsigned));
|
||||
input_stream.read((char *)&source, sizeof(unsigned));
|
||||
input_stream.read((char *)&target, sizeof(unsigned));
|
||||
input_stream.read((char *)&length, sizeof(int));
|
||||
|
@ -351,7 +355,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
|
|||
target);
|
||||
}
|
||||
|
||||
tbb::parallel_sort(edge_list.begin(), edge_list.end());
|
||||
std::sort(edge_list.begin(), edge_list.end());
|
||||
for (unsigned i = 1; i < edge_list.size(); ++i)
|
||||
{
|
||||
if ((edge_list[i - 1].target == edge_list[i].target) &&
|
||||
|
|
389
3party/osrm/osrm-backend/mapsme/converter.cpp
Normal file
389
3party/osrm/osrm-backend/mapsme/converter.cpp
Normal file
|
@ -0,0 +1,389 @@
|
|||
#include "converter.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#include "../../../../base/bits.hpp"
|
||||
#include "../../../../base/logging.hpp"
|
||||
#include "../../../../base/scope_guard.hpp"
|
||||
|
||||
#include "../../../../coding/matrix_traversal.hpp"
|
||||
#include "../../../../coding/internal/file_data.hpp"
|
||||
|
||||
#include "../../../../routing/osrm_data_facade.hpp"
|
||||
|
||||
#include "../../../succinct/elias_fano.hpp"
|
||||
#include "../../../succinct/elias_fano_compressed_list.hpp"
|
||||
#include "../../../succinct/gamma_vector.hpp"
|
||||
#include "../../../succinct/rs_bit_vector.hpp"
|
||||
#include "../../../succinct/mapper.hpp"
|
||||
|
||||
#include "../Server/DataStructures/InternalDataFacade.h"
|
||||
|
||||
namespace mapsme
|
||||
{
|
||||
|
||||
typedef pair<NodeID, QueryEdge::EdgeData> EdgeOsrmT;
|
||||
|
||||
struct EdgeLess
|
||||
{
|
||||
bool operator () (EdgeOsrmT const & e1, EdgeOsrmT const & e2) const
|
||||
{
|
||||
if (e1.first != e2.first)
|
||||
return e1.first < e2.first;
|
||||
|
||||
QueryEdge::EdgeData const & d1 = e1.second;
|
||||
QueryEdge::EdgeData const & d2 = e2.second;
|
||||
|
||||
if (d1.distance != d2.distance)
|
||||
return d1.distance < d2.distance;
|
||||
|
||||
if (d1.shortcut != d2.shortcut)
|
||||
return d1.shortcut < d2.shortcut;
|
||||
|
||||
if (d1.forward != d2.forward)
|
||||
return d1.forward < d2.forward;
|
||||
|
||||
if (d1.backward != d2.backward)
|
||||
return e1.second.backward < d2.backward;
|
||||
|
||||
if (d1.id != d2.id)
|
||||
return d1.id < d2.id;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void PrintStatus(bool b)
|
||||
{
|
||||
std::cout << (b ? "[Ok]" : "[Fail]") << std::endl;
|
||||
}
|
||||
|
||||
string EdgeDataToString(EdgeOsrmT const & d)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "[" << d.first << ", " << d.second.distance << ", " << d.second.shortcut << ", " << d.second.forward << ", "
|
||||
<< d.second.backward << ", " << d.second.id << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GenerateRoutingIndex(const std::string & fPath)
|
||||
{
|
||||
ServerPaths server_paths;
|
||||
|
||||
server_paths["hsgrdata"] = boost::filesystem::path(fPath + ".hsgr");
|
||||
server_paths["ramindex"] = boost::filesystem::path(fPath + ".ramIndex");
|
||||
server_paths["fileindex"] = boost::filesystem::path(fPath + ".fileIndex");
|
||||
server_paths["geometries"] = boost::filesystem::path(fPath + ".geometry");
|
||||
server_paths["nodesdata"] = boost::filesystem::path(fPath + ".nodes");
|
||||
server_paths["edgesdata"] = boost::filesystem::path(fPath + ".edges");
|
||||
server_paths["namesdata"] = boost::filesystem::path(fPath + ".names");
|
||||
server_paths["timestamp"] = boost::filesystem::path(fPath + ".timestamp");
|
||||
|
||||
std::cout << "Create internal data facade for file: " << fPath << "...";
|
||||
InternalDataFacade<QueryEdge::EdgeData> facade(server_paths);
|
||||
PrintStatus(true);
|
||||
|
||||
uint32_t const nodeCount = facade.GetNumberOfNodes();
|
||||
|
||||
std::vector<uint64_t> edges;
|
||||
std::vector<uint32_t> edgesData;
|
||||
std::vector<bool> shortcuts;
|
||||
std::vector<uint64_t> edgeId;
|
||||
|
||||
std::cout << "Repack graph..." << std::endl;
|
||||
|
||||
typedef pair<uint64_t, QueryEdge::EdgeData> EdgeInfoT;
|
||||
typedef vector<EdgeInfoT> EdgeInfoVecT;
|
||||
|
||||
uint64_t copiedEdges = 0, ignoredEdges = 0;
|
||||
for (uint32_t node = 0; node < nodeCount; ++node)
|
||||
{
|
||||
EdgeInfoVecT edgesInfo;
|
||||
for (auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
uint64_t target = facade.GetTarget(edge);
|
||||
auto const & data = facade.GetEdgeData(edge);
|
||||
|
||||
edgesInfo.push_back(EdgeInfoT(target, data));
|
||||
}
|
||||
|
||||
sort(edgesInfo.begin(), edgesInfo.end(), [](EdgeInfoT const & a, EdgeInfoT const & b)
|
||||
{
|
||||
if (a.first != b.first)
|
||||
return a.first < b.first;
|
||||
|
||||
if (a.second.forward != b.second.forward)
|
||||
return a.second.forward > b.second.forward;
|
||||
|
||||
return a.second.id < b.second.id;
|
||||
});
|
||||
|
||||
uint64_t lastTarget = 0;
|
||||
for (auto edge : edgesInfo)
|
||||
{
|
||||
uint64_t const target = edge.first;
|
||||
auto const & data = edge.second;
|
||||
|
||||
if (target < lastTarget)
|
||||
LOG(LCRITICAL, ("Invalid order of target nodes", target, lastTarget));
|
||||
|
||||
lastTarget = target;
|
||||
assert(data.forward || data.backward);
|
||||
|
||||
auto addDataFn = [&](bool b)
|
||||
{
|
||||
uint64_t const e = TraverseMatrixInRowOrder<uint64_t>(nodeCount, node, target, b);
|
||||
|
||||
auto compressId = [&](uint64_t id)
|
||||
{
|
||||
return bits::ZigZagEncode(int64_t(node) - int64_t(id));
|
||||
};
|
||||
|
||||
if (!edges.empty())
|
||||
CHECK_GREATER_OR_EQUAL(e, edges.back(), ());
|
||||
|
||||
if (!edges.empty() && (edges.back() == e))
|
||||
{
|
||||
LOG(LWARNING, ("Invalid order of edges", e, edges.back(), nodeCount, node, target, b));
|
||||
CHECK(data.shortcut == shortcuts.back(), ());
|
||||
|
||||
auto const last = edgesData.back();
|
||||
if (data.distance <= last)
|
||||
{
|
||||
if (!edgeId.empty() && data.shortcut)
|
||||
{
|
||||
CHECK(shortcuts.back(), ());
|
||||
unsigned oldId = node - bits::ZigZagDecode(edgeId.back());
|
||||
|
||||
if (data.distance == last)
|
||||
edgeId.back() = compressId(min(oldId, data.id));
|
||||
else
|
||||
edgeId.back() = compressId(data.id);
|
||||
}
|
||||
|
||||
edgesData.back() = data.distance;
|
||||
}
|
||||
|
||||
++ignoredEdges;
|
||||
return;
|
||||
}
|
||||
|
||||
edges.push_back(e);
|
||||
edgesData.push_back(data.distance);
|
||||
shortcuts.push_back(data.shortcut);
|
||||
|
||||
if (data.shortcut)
|
||||
edgeId.push_back(compressId(data.id));
|
||||
};
|
||||
|
||||
if (data.forward && data.backward)
|
||||
{
|
||||
addDataFn(false);
|
||||
addDataFn(true);
|
||||
copiedEdges++;
|
||||
}
|
||||
else
|
||||
addDataFn(data.backward);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Edges count: " << edgeId.size() << std::endl;
|
||||
PrintStatus(true);
|
||||
|
||||
std::cout << "Sort edges...";
|
||||
std::sort(edges.begin(), edges.end());
|
||||
PrintStatus(true);
|
||||
|
||||
std::cout << "Edges count: " << edges.size() << std::endl;
|
||||
std::cout << "Nodes count: " << nodeCount << std::endl;
|
||||
|
||||
std::cout << "--- Save matrix" << std::endl;
|
||||
succinct::elias_fano::elias_fano_builder builder(edges.back(), edges.size());
|
||||
for (auto e : edges)
|
||||
builder.push_back(e);
|
||||
succinct::elias_fano matrix(&builder);
|
||||
|
||||
std::string fileName = fPath + "." + ROUTING_MATRIX_FILE_TAG;
|
||||
std::ofstream fout(fileName, std::ios::binary);
|
||||
fout.write((const char*)&nodeCount, sizeof(nodeCount));
|
||||
succinct::mapper::freeze(matrix, fout);
|
||||
fout.close();
|
||||
|
||||
std::cout << "--- Save edge data" << std::endl;
|
||||
succinct::elias_fano_compressed_list edgeVector(edgesData);
|
||||
fileName = fPath + "." + ROUTING_EDGEDATA_FILE_TAG;
|
||||
succinct::mapper::freeze(edgeVector, fileName.c_str());
|
||||
|
||||
succinct::elias_fano_compressed_list edgeIdVector(edgeId);
|
||||
fileName = fPath + "." + ROUTING_EDGEID_FILE_TAG;
|
||||
succinct::mapper::freeze(edgeIdVector, fileName.c_str());
|
||||
|
||||
std::cout << "--- Save edge shortcuts" << std::endl;
|
||||
succinct::rs_bit_vector shortcutsVector(shortcuts);
|
||||
fileName = fPath + "." + ROUTING_SHORTCUTS_FILE_TAG;
|
||||
succinct::mapper::freeze(shortcutsVector, fileName.c_str());
|
||||
|
||||
if (edgeId.size() != shortcutsVector.num_ones())
|
||||
LOG(LCRITICAL, ("Invalid data"));
|
||||
|
||||
std::cout << "--- Test packed data" << std::endl;
|
||||
std::string path = fPath + ".test";
|
||||
|
||||
{
|
||||
FilesContainerW routingCont(path);
|
||||
|
||||
auto appendFile = [&] (string const & tag)
|
||||
{
|
||||
string const fileName = fPath + "." + tag;
|
||||
routingCont.Write(fileName, tag);
|
||||
};
|
||||
|
||||
appendFile(ROUTING_SHORTCUTS_FILE_TAG);
|
||||
appendFile(ROUTING_EDGEDATA_FILE_TAG);
|
||||
appendFile(ROUTING_MATRIX_FILE_TAG);
|
||||
appendFile(ROUTING_EDGEID_FILE_TAG);
|
||||
|
||||
routingCont.Finish();
|
||||
}
|
||||
|
||||
MY_SCOPE_GUARD(testFileGuard, bind(&my::DeleteFileX, cref(path)));
|
||||
|
||||
FilesMappingContainer container;
|
||||
container.Open(path);
|
||||
typedef routing::OsrmDataFacade<QueryEdge::EdgeData> DataFacadeT;
|
||||
DataFacadeT facadeNew;
|
||||
facadeNew.Load(container);
|
||||
|
||||
uint64_t edgesCount = facadeNew.GetNumberOfEdges() - copiedEdges + ignoredEdges;
|
||||
std::cout << "Check node count " << facade.GetNumberOfNodes() << " == " << facadeNew.GetNumberOfNodes() << "..." << std::endl;
|
||||
CHECK_EQUAL(facade.GetNumberOfNodes(), facadeNew.GetNumberOfNodes(), ());
|
||||
std::cout << "Check edges count " << facade.GetNumberOfEdges() << " == " << edgesCount << "..." << std::endl;
|
||||
CHECK_EQUAL(facade.GetNumberOfEdges(), edgesCount, ());
|
||||
|
||||
std::cout << "Check edges data ...";
|
||||
bool error = false;
|
||||
|
||||
typedef vector<QueryEdge::EdgeData> EdgeDataT;
|
||||
assert(facade.GetNumberOfEdges() == facadeNew.GetNumberOfEdges());
|
||||
for (uint32_t i = 0; i < facade.GetNumberOfNodes(); ++i)
|
||||
{
|
||||
// get all edges from osrm datafacade and store just minimal weights for duplicates
|
||||
vector<EdgeOsrmT> edgesOsrm;
|
||||
for (auto e : facade.GetAdjacentEdgeRange(i))
|
||||
edgesOsrm.push_back(EdgeOsrmT(facade.GetTarget(e), facade.GetEdgeData(e)));
|
||||
|
||||
sort(edgesOsrm.begin(), edgesOsrm.end(), [](EdgeOsrmT const & a, EdgeOsrmT const & b)
|
||||
{
|
||||
if (a.first != b.first)
|
||||
return a.first < b.first;
|
||||
|
||||
QueryEdge::EdgeData const & d1 = a.second;
|
||||
QueryEdge::EdgeData const & d2 = b.second;
|
||||
|
||||
if (d1.forward != d2.forward)
|
||||
return d1.forward < d2.forward;
|
||||
|
||||
if (d1.backward != d2.backward)
|
||||
return d1.backward < d2.backward;
|
||||
|
||||
if (d1.distance != d2.distance)
|
||||
return d1.distance < d2.distance;
|
||||
|
||||
return d1.id < d2.id;
|
||||
});
|
||||
|
||||
for (size_t k = 1; k < edgesOsrm.size();)
|
||||
{
|
||||
auto const & e1 = edgesOsrm[k - 1];
|
||||
auto const & e2 = edgesOsrm[k];
|
||||
|
||||
if (e1.first != e2.first ||
|
||||
e1.second.forward != e2.second.forward ||
|
||||
e1.second.backward != e2.second.backward)
|
||||
{
|
||||
++k;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e1.second.distance > e2.second.distance)
|
||||
edgesOsrm.erase(edgesOsrm.begin() + k - 1);
|
||||
else
|
||||
edgesOsrm.erase(edgesOsrm.begin() + k);
|
||||
}
|
||||
|
||||
vector<EdgeOsrmT> v1, v2;
|
||||
for (auto e : edgesOsrm)
|
||||
{
|
||||
QueryEdge::EdgeData d = e.second;
|
||||
if (d.forward && d.backward)
|
||||
{
|
||||
d.backward = false;
|
||||
v1.push_back(EdgeOsrmT(e.first, d));
|
||||
d.forward = false;
|
||||
d.backward = true;
|
||||
}
|
||||
|
||||
v1.push_back(EdgeOsrmT(e.first, d));
|
||||
}
|
||||
|
||||
for (auto e : facadeNew.GetAdjacentEdgeRange(i))
|
||||
v2.push_back(EdgeOsrmT(facadeNew.GetTarget(e), facadeNew.GetEdgeData(e, i)));
|
||||
|
||||
if (v1.size() != v2.size())
|
||||
{
|
||||
auto printV = [](vector<EdgeOsrmT> const & v, stringstream & ss)
|
||||
{
|
||||
for (auto i : v)
|
||||
ss << EdgeDataToString(i) << std::endl;
|
||||
};
|
||||
|
||||
sort(v1.begin(), v1.end(), EdgeLess());
|
||||
sort(v2.begin(), v2.end(), EdgeLess());
|
||||
|
||||
stringstream ss;
|
||||
ss << "File name: " << fPath << std::endl;
|
||||
ss << "Not equal edges count for node: " << i << std::endl;
|
||||
ss << "v1: " << v1.size() << " v2: " << v2.size() << std::endl;
|
||||
ss << "--- v1 ---" << std::endl;
|
||||
printV(v1, ss);
|
||||
ss << "--- v2 ---" << std::endl;
|
||||
printV(v2, ss);
|
||||
|
||||
LOG(LCRITICAL, (ss.str()));
|
||||
}
|
||||
|
||||
sort(v1.begin(), v1.end(), EdgeLess());
|
||||
sort(v2.begin(), v2.end(), EdgeLess());
|
||||
|
||||
// compare vectors
|
||||
for (size_t k = 0; k < v1.size(); ++k)
|
||||
{
|
||||
EdgeOsrmT const & e1 = v1[k];
|
||||
EdgeOsrmT const & e2 = v2[k];
|
||||
|
||||
QueryEdge::EdgeData const & d1 = e1.second;
|
||||
QueryEdge::EdgeData const & d2 = e2.second;
|
||||
|
||||
if (e1.first != e2.first ||
|
||||
d1.backward != d2.backward ||
|
||||
d1.forward != d2.forward ||
|
||||
d1.distance != d2.distance ||
|
||||
(d1.id != d2.id && (d1.shortcut || d2.shortcut)) ||
|
||||
d1.shortcut != d2.shortcut)
|
||||
{
|
||||
std::cout << "--- " << std::endl;
|
||||
for (size_t j = 0; j < v1.size(); ++j)
|
||||
std::cout << EdgeDataToString(v1[j]) << " - " << EdgeDataToString(v2[j]) << std::endl;
|
||||
|
||||
LOG(LCRITICAL, ("File:", fPath, "Node:", i, EdgeDataToString(e1), EdgeDataToString(e2)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
PrintStatus(!error);
|
||||
}
|
||||
|
||||
}
|
13
3party/osrm/osrm-backend/mapsme/converter.hpp
Normal file
13
3party/osrm/osrm-backend/mapsme/converter.hpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../DataStructures/QueryEdge.h"
|
||||
|
||||
namespace mapsme
|
||||
{
|
||||
|
||||
|
||||
void GenerateRoutingIndex(const std::string & fPath);
|
||||
|
||||
}
|
29
3party/osrm/osrm-backend/mapsme/main.cpp
Normal file
29
3party/osrm/osrm-backend/mapsme/main.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/program_options.hpp>
|
||||
#include "converter.hpp"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
boost::program_options::options_description descr;
|
||||
|
||||
descr.add_options()
|
||||
("help", "h")
|
||||
("input,i", boost::program_options::value<std::string>(), "Path to input osrm file (belarus.osrm)");
|
||||
|
||||
boost::program_options::variables_map vm;
|
||||
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(descr).run(), vm);
|
||||
boost::program_options::notify(vm);
|
||||
if (vm.count("help") || !vm.count("input"))
|
||||
{
|
||||
std::cout << descr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
mapsme::GenerateRoutingIndex(vm["input"].as<std::string>());
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
#include "../3party/succinct/mapper.hpp"
|
||||
|
||||
#include "../3party/osrm/osrm-backend/Server/DataStructures/BaseDataFacade.h"
|
||||
#include "../3party/osrm/osrm-backend/DataStructures/TravelMode.h"
|
||||
|
||||
|
||||
namespace routing
|
||||
|
@ -131,6 +132,12 @@ public:
|
|||
return res;
|
||||
}
|
||||
|
||||
//! TODO: Make proper travelmode getter when we add it to routing file
|
||||
TravelMode GetTravelModeForEdgeID(const unsigned id) const
|
||||
{
|
||||
return TRAVEL_MODE_DEFAULT;
|
||||
}
|
||||
|
||||
EdgeID BeginEdges(const NodeID n) const
|
||||
{
|
||||
uint64_t idx = 2 * n * (uint64_t)GetNumberOfNodes();
|
||||
|
|
Loading…
Add table
Reference in a new issue