diff --git a/3party/osrm/osrm-backend/.clang-format b/3party/osrm/osrm-backend/.clang-format deleted file mode 100644 index 47429976bc..0000000000 --- a/3party/osrm/osrm-backend/.clang-format +++ /dev/null @@ -1,53 +0,0 @@ ---- -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 -... diff --git a/3party/osrm/osrm-backend/.gitignore b/3party/osrm/osrm-backend/.gitignore deleted file mode 100644 index 5e8c12d8bc..0000000000 --- a/3party/osrm/osrm-backend/.gitignore +++ /dev/null @@ -1,93 +0,0 @@ -# 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 diff --git a/3party/osrm/osrm-backend/.gitmodules b/3party/osrm/osrm-backend/.gitmodules deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/3party/osrm/osrm-backend/.travis.yml b/3party/osrm/osrm-backend/.travis.yml deleted file mode 100644 index 8817e38747..0000000000 --- a/3party/osrm/osrm-backend/.travis.yml +++ /dev/null @@ -1,54 +0,0 @@ -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 diff --git a/3party/osrm/osrm-backend/Algorithms/StronglyConnectedComponents.h b/3party/osrm/osrm-backend/Algorithms/StronglyConnectedComponents.h deleted file mode 100644 index 681f78fa3b..0000000000 --- a/3party/osrm/osrm-backend/Algorithms/StronglyConnectedComponents.h +++ /dev/null @@ -1,459 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef STRONGLYCONNECTEDCOMPONENTS_H_ -#define STRONGLYCONNECTEDCOMPONENTS_H_ - -#include "../typedefs.h" -#include "../DataStructures/DeallocatingVector.h" -#include "../DataStructures/DynamicGraph.h" -#include "../DataStructures/ImportEdge.h" -#include "../DataStructures/QueryNode.h" -#include "../DataStructures/Percent.h" -#include "../DataStructures/Range.h" -#include "../DataStructures/Restriction.h" -#include "../DataStructures/TurnInstructions.h" - -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" -#include "../Util/StdHashExtensions.h" -#include "../Util/TimingUtil.h" - -#include - -#include -#include - -#include - -#ifdef __APPLE__ -#include -#include -#else -#include -#include -#endif - -#include - -#include -#include -#include -#include -#include - -class TarjanSCC -{ - private: - struct TarjanNode - { - TarjanNode() : index(SPECIAL_NODEID), low_link(SPECIAL_NODEID), on_stack(false) {} - unsigned index; - unsigned low_link; - bool on_stack; - }; - - struct TarjanEdgeData - { - TarjanEdgeData() : distance(INVALID_EDGE_WEIGHT), name_id(INVALID_NAMEID) {} - TarjanEdgeData(int distance, unsigned name_id) : distance(distance), name_id(name_id) {} - int distance; - unsigned name_id; - }; - - struct TarjanStackFrame - { - explicit TarjanStackFrame(NodeID v, NodeID parent) : v(v), parent(parent) {} - NodeID v; - NodeID parent; - }; - - using TarjanDynamicGraph = DynamicGraph; - using TarjanEdge = TarjanDynamicGraph::InputEdge; - using RestrictionSource = std::pair; - using RestrictionTarget = std::pair; - using EmanatingRestrictionsVector = std::vector; - using RestrictionMap = std::unordered_map; - - std::vector m_coordinate_list; - std::vector m_restriction_bucket_list; - std::shared_ptr m_node_based_graph; - std::unordered_set barrier_node_list; - std::unordered_set traffic_light_list; - unsigned m_restriction_counter; - RestrictionMap m_restriction_map; - - public: - TarjanSCC(int number_of_nodes, - std::vector &input_edges, - std::vector &bn, - std::vector &tl, - std::vector &irs, - std::vector &nI) - : m_coordinate_list(nI), m_restriction_counter(irs.size()) - { - TIMER_START(SCC_LOAD); - for (const TurnRestriction &restriction : irs) - { - std::pair restriction_source = {restriction.fromNode, - restriction.viaNode}; - unsigned index = 0; - const auto restriction_iterator = m_restriction_map.find(restriction_source); - if (restriction_iterator == m_restriction_map.end()) - { - index = m_restriction_bucket_list.size(); - m_restriction_bucket_list.resize(index + 1); - m_restriction_map.emplace(restriction_source, index); - } - else - { - index = restriction_iterator->second; - // Map already contains an is_only_*-restriction - if (m_restriction_bucket_list.at(index).begin()->second) - { - continue; - } - else if (restriction.flags.isOnly) - { - // We are going to insert an is_only_*-restriction. There can be only one. - m_restriction_bucket_list.at(index).clear(); - } - } - - m_restriction_bucket_list.at(index) - .emplace_back(restriction.toNode, restriction.flags.isOnly); - } - - barrier_node_list.insert(bn.begin(), bn.end()); - traffic_light_list.insert(tl.begin(), tl.end()); - - DeallocatingVector edge_list; - for (const NodeBasedEdge &input_edge : input_edges) - { - if (input_edge.source == input_edge.target) - { - continue; - } - - if (input_edge.forward) - { - edge_list.emplace_back(input_edge.source, - input_edge.target, - (std::max)((int)input_edge.weight, 1), - input_edge.name_id); - } - if (input_edge.backward) - { - edge_list.emplace_back(input_edge.target, - input_edge.source, - (std::max)((int)input_edge.weight, 1), - input_edge.name_id); - } - } - input_edges.clear(); - input_edges.shrink_to_fit(); - BOOST_ASSERT_MSG(0 == input_edges.size() && 0 == input_edges.capacity(), - "input edge vector not properly deallocated"); - - tbb::parallel_sort(edge_list.begin(), edge_list.end()); - m_node_based_graph = std::make_shared(number_of_nodes, edge_list); - TIMER_STOP(SCC_LOAD); - SimpleLogger().Write() << "Loading data into SCC took " << TIMER_MSEC(SCC_LOAD)/1000. << "s"; - } - - ~TarjanSCC() { m_node_based_graph.reset(); } - - void Run() - { - TIMER_START(SCC_RUN_SETUP); - // remove files from previous run if exist - DeleteFileIfExists("component.dbf"); - DeleteFileIfExists("component.shx"); - DeleteFileIfExists("component.shp"); - - Percent p(m_node_based_graph->GetNumberOfNodes()); - - OGRRegisterAll(); - - const char *pszDriverName = "ESRI Shapefile"; - OGRSFDriver *poDriver = - OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName); - if (nullptr == poDriver) - { - throw OSRMException("ESRI Shapefile driver not available"); - } - OGRDataSource *poDS = poDriver->CreateDataSource("component.shp", nullptr); - - if (nullptr == poDS) - { - throw OSRMException("Creation of output file failed"); - } - - OGRSpatialReference *poSRS = new OGRSpatialReference(); - poSRS->importFromEPSG(4326); - - OGRLayer *poLayer = poDS->CreateLayer("component", poSRS, wkbLineString, nullptr); - - if (nullptr == poLayer) - { - throw OSRMException("Layer creation failed."); - } - TIMER_STOP(SCC_RUN_SETUP); - SimpleLogger().Write() << "shapefile setup took " << TIMER_MSEC(SCC_RUN_SETUP)/1000. << "s"; - - TIMER_START(SCC_RUN); - // The following is a hack to distinguish between stuff that happens - // before the recursive call and stuff that happens after - std::stack recursion_stack; - // true = stuff before, false = stuff after call - std::stack tarjan_stack; - std::vector components_index(m_node_based_graph->GetNumberOfNodes(), - SPECIAL_NODEID); - std::vector component_size_vector; - std::vector tarjan_node_list(m_node_based_graph->GetNumberOfNodes()); - unsigned component_index = 0, size_of_current_component = 0; - int index = 0; - const NodeID last_node = m_node_based_graph->GetNumberOfNodes(); - std::vector processing_node_before_recursion(m_node_based_graph->GetNumberOfNodes(), true); - for(const NodeID node : osrm::irange(0u, last_node)) - { - if (SPECIAL_NODEID == components_index[node]) - { - recursion_stack.emplace(TarjanStackFrame(node, node)); - } - - while (!recursion_stack.empty()) - { - TarjanStackFrame currentFrame = recursion_stack.top(); - const NodeID v = currentFrame.v; - recursion_stack.pop(); - const bool before_recursion = processing_node_before_recursion[v]; - - if (before_recursion && tarjan_node_list[v].index != UINT_MAX) - { - continue; - } - - if (before_recursion) - { - // Mark frame to handle tail of recursion - recursion_stack.emplace(currentFrame); - processing_node_before_recursion[v] = false; - - // Mark essential information for SCC - tarjan_node_list[v].index = index; - tarjan_node_list[v].low_link = index; - tarjan_stack.push(v); - tarjan_node_list[v].on_stack = true; - ++index; - - // Traverse outgoing edges - for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v)) - { - const TarjanDynamicGraph::NodeIterator vprime = - m_node_based_graph->GetTarget(current_edge); - if (SPECIAL_NODEID == tarjan_node_list[vprime].index) - { - recursion_stack.emplace(TarjanStackFrame(vprime, v)); - } - else - { - if (tarjan_node_list[vprime].on_stack && - tarjan_node_list[vprime].index < tarjan_node_list[v].low_link) - { - tarjan_node_list[v].low_link = tarjan_node_list[vprime].index; - } - } - } - } - else - { - processing_node_before_recursion[v] = true; - tarjan_node_list[currentFrame.parent].low_link = - std::min(tarjan_node_list[currentFrame.parent].low_link, - tarjan_node_list[v].low_link); - // after recursion, lets do cycle checking - // Check if we found a cycle. This is the bottom part of the recursion - if (tarjan_node_list[v].low_link == tarjan_node_list[v].index) - { - NodeID vprime; - do - { - vprime = tarjan_stack.top(); - tarjan_stack.pop(); - tarjan_node_list[vprime].on_stack = false; - components_index[vprime] = component_index; - ++size_of_current_component; - } while (v != vprime); - - component_size_vector.emplace_back(size_of_current_component); - - if (size_of_current_component > 1000) - { - SimpleLogger().Write() << "large component [" << component_index - << "]=" << size_of_current_component; - } - - ++component_index; - size_of_current_component = 0; - } - } - } - } - - TIMER_STOP(SCC_RUN); - SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN)/1000. << "s"; - SimpleLogger().Write() << "identified: " << component_size_vector.size() - << " many components, marking small components"; - - TIMER_START(SCC_OUTPUT); - - const unsigned size_one_counter = std::count_if(component_size_vector.begin(), - component_size_vector.end(), - [](unsigned value) - { - return 1 == value; - }); - - SimpleLogger().Write() << "identified " << size_one_counter << " SCCs of size 1"; - - uint64_t total_network_distance = 0; - p.reinit(m_node_based_graph->GetNumberOfNodes()); - // const NodeID last_u_node = m_node_based_graph->GetNumberOfNodes(); - for (const NodeID source : osrm::irange(0u, last_node)) - { - p.printIncrement(); - for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(source)) - { - const TarjanDynamicGraph::NodeIterator target = - m_node_based_graph->GetTarget(current_edge); - - if (source < target || - m_node_based_graph->EndEdges(target) == - m_node_based_graph->FindEdge(target, source)) - { - total_network_distance += - 100 * FixedPointCoordinate::ApproximateEuclideanDistance( - m_coordinate_list[source].lat, - m_coordinate_list[source].lon, - m_coordinate_list[target].lat, - m_coordinate_list[target].lon); - - BOOST_ASSERT(current_edge != SPECIAL_EDGEID); - BOOST_ASSERT(source != SPECIAL_NODEID); - BOOST_ASSERT(target != SPECIAL_NODEID); - - const unsigned size_of_containing_component = - std::min(component_size_vector[components_index[source]], - component_size_vector[components_index[target]]); - - // edges that end on bollard nodes may actually be in two distinct components - if (size_of_containing_component < 10) - { - OGRLineString lineString; - lineString.addPoint(m_coordinate_list[source].lon / COORDINATE_PRECISION, - m_coordinate_list[source].lat / COORDINATE_PRECISION); - lineString.addPoint(m_coordinate_list[target].lon / COORDINATE_PRECISION, - m_coordinate_list[target].lat / COORDINATE_PRECISION); - - OGRFeature *poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn()); - - poFeature->SetGeometry(&lineString); - if (OGRERR_NONE != poLayer->CreateFeature(poFeature)) - { - throw OSRMException("Failed to create feature in shapefile."); - } - OGRFeature::DestroyFeature(poFeature); - } - } - } - } - OGRDataSource::DestroyDataSource(poDS); - component_size_vector.clear(); - component_size_vector.shrink_to_fit(); - BOOST_ASSERT_MSG(0 == component_size_vector.size() && 0 == component_size_vector.capacity(), - "component_size_vector not properly deallocated"); - - components_index.clear(); - components_index.shrink_to_fit(); - BOOST_ASSERT_MSG(0 == components_index.size() && 0 == components_index.capacity(), - "components_index not properly deallocated"); - TIMER_STOP(SCC_OUTPUT); - SimpleLogger().Write() << "generating output took: " << TIMER_MSEC(SCC_OUTPUT)/1000. << "s"; - - SimpleLogger().Write() << "total network distance: " - << (uint64_t)total_network_distance / 100 / 1000. << " km"; - } - - private: - unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const - { - std::pair restriction_source = {u, v}; - const auto restriction_iterator = m_restriction_map.find(restriction_source); - if (restriction_iterator != m_restriction_map.end()) - { - const unsigned index = restriction_iterator->second; - for (const RestrictionSource &restriction_target : m_restriction_bucket_list.at(index)) - { - if (restriction_target.second) - { - return restriction_target.first; - } - } - } - return SPECIAL_NODEID; - } - - bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const - { - // only add an edge if turn is not a U-turn except it is the end of dead-end street. - std::pair restriction_source = {u, v}; - const auto restriction_iterator = m_restriction_map.find(restriction_source); - if (restriction_iterator != m_restriction_map.end()) - { - const unsigned index = restriction_iterator->second; - for (const RestrictionTarget &restriction_target : m_restriction_bucket_list.at(index)) - { - if (w == restriction_target.first) - { - return true; - } - } - } - return false; - } - - void DeleteFileIfExists(const std::string &file_name) const - { - if (boost::filesystem::exists(file_name)) - { - boost::filesystem::remove(file_name); - } - } -}; - -#endif /* STRONGLYCONNECTEDCOMPONENTS_H_ */ diff --git a/3party/osrm/osrm-backend/Benchmarks/StaticRTreeBench.cpp b/3party/osrm/osrm-backend/Benchmarks/StaticRTreeBench.cpp deleted file mode 100644 index b0b34fb6e0..0000000000 --- a/3party/osrm/osrm-backend/Benchmarks/StaticRTreeBench.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include "../DataStructures/OriginalEdgeData.h" -#include "../DataStructures/QueryNode.h" -#include "../DataStructures/SharedMemoryVectorWrapper.h" -#include "../DataStructures/StaticRTree.h" -#include "../Util/BoostFileSystemFix.h" -#include "../DataStructures/EdgeBasedNode.h" - -#include - -#include - -// Choosen by a fair W20 dice roll (this value is completely arbitrary) -constexpr unsigned RANDOM_SEED = 13; -constexpr int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION; -constexpr int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION; -constexpr int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION; -constexpr int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION; - -using RTreeLeaf = EdgeBasedNode; -using FixedPointCoordinateListPtr = std::shared_ptr>; -using BenchStaticRTree = StaticRTree::vector, false>; - -FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file) -{ - boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary); - - NodeInfo current_node; - unsigned number_of_coordinates = 0; - nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned)); - auto coords = std::make_shared>(number_of_coordinates); - for (unsigned i = 0; i < number_of_coordinates; ++i) - { - nodes_input_stream.read((char *)¤t_node, sizeof(NodeInfo)); - coords->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon); - BOOST_ASSERT((std::abs(coords->at(i).lat) >> 30) == 0); - BOOST_ASSERT((std::abs(coords->at(i).lon) >> 30) == 0); - } - nodes_input_stream.close(); - return coords; -} - -void Benchmark(BenchStaticRTree &rtree, unsigned num_queries) -{ - std::mt19937 mt_rand(RANDOM_SEED); - std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT); - std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON); - std::vector queries; - for (unsigned i = 0; i < num_queries; i++) - { - queries.emplace_back(FixedPointCoordinate(lat_udist(mt_rand), lon_udist(mt_rand))); - } - - const unsigned num_results = 5; - std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results - << " phantom nodes" - << "\n"; - - TIMER_START(query_phantom); - std::vector resulting_phantom_node_vector; - for (const auto &q : queries) - { - resulting_phantom_node_vector.clear(); - rtree.IncrementalFindPhantomNodeForCoordinate( - q, resulting_phantom_node_vector, 3, num_results); - resulting_phantom_node_vector.clear(); - rtree.IncrementalFindPhantomNodeForCoordinate( - q, resulting_phantom_node_vector, 17, num_results); - } - TIMER_STOP(query_phantom); - - std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries << " queries." - << "\n"; - std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query." - << "\n"; - - std::cout << "#### LocateClosestEndPointForCoordinate" - << "\n"; - - TIMER_START(query_endpoint); - FixedPointCoordinate result; - for (const auto &q : queries) - { - rtree.LocateClosestEndPointForCoordinate(q, result, 3); - } - TIMER_STOP(query_endpoint); - - std::cout << "Took " << TIMER_MSEC(query_endpoint) << " msec for " << num_queries << " queries." - << "\n"; - std::cout << TIMER_MSEC(query_endpoint) / ((double)num_queries) << " msec/query." - << "\n"; - - std::cout << "#### FindPhantomNodeForCoordinate" - << "\n"; - - TIMER_START(query_phantomnode); - for (const auto &q : queries) - { - PhantomNode phantom; - rtree.FindPhantomNodeForCoordinate(q, phantom, 3); - } - TIMER_STOP(query_phantomnode); - - std::cout << "Took " << TIMER_MSEC(query_phantomnode) << " msec for " << num_queries - << " queries." - << "\n"; - std::cout << TIMER_MSEC(query_phantomnode) / ((double)num_queries) << " msec/query." - << "\n"; -} - -int main(int argc, char **argv) -{ - if (argc < 4) - { - std::cout << "./rtree-bench file.ramIndex file.fileIndx file.nodes" - << "\n"; - return 1; - } - - const char *ramPath = argv[1]; - const char *filePath = argv[2]; - const char *nodesPath = argv[3]; - - auto coords = LoadCoordinates(nodesPath); - - BenchStaticRTree rtree(ramPath, filePath, coords); - - Benchmark(rtree, 10000); - - return 0; -} diff --git a/3party/osrm/osrm-backend/CMakeLists.txt b/3party/osrm/osrm-backend/CMakeLists.txt old mode 100644 new mode 100755 index 49af1e6f77..503171a599 --- a/3party/osrm/osrm-backend/CMakeLists.txt +++ b/3party/osrm/osrm-backend/CMakeLists.txt @@ -1,22 +1,17 @@ cmake_minimum_required(VERSION 2.8.8) -if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE ) +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR AND NOT MSVC_IDE) message(FATAL_ERROR "In-source builds are not allowed. Please create a directory and run cmake from there, passing the path to this source directory as the last argument. This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them.") endif() -project(OSRM) +project(OSRM C CXX) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include(CheckCXXCompilerFlag) include(FindPackageHandleStandardArgs) -set(OMIM_STORAGE_PATH "../../../storage/") -set(OMIM_DEBUG_PATH "${CMAKE_SOURCE_DIR}/../../../../omim-build-debug/out/debug") -set(OMIM_RELEASE_PATH "${CMAKE_SOURCE_DIR}/../../../../omim-build-release/out/release") -set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) - -list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(GetGitRevisionDescription) git_describe(GIT_DESCRIPTION) @@ -28,76 +23,89 @@ else() message(WARNING "Building on a 32 bit system is unsupported") endif() -if (WIN32 AND MSVC_VERSION LESS 1800) +if(WIN32 AND MSVC_VERSION LESS 1800) message(FATAL_ERROR "Building with Microsoft compiler needs Visual Studio 2013 or later (Express version works too)") endif() -OPTION(WITH_TOOLS "Build OSRM tools" OFF) -OPTION(BUILD_TOOLS "Build OSRM tools" OFF) +option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF) +option(WITH_TOOLS "Build OSRM tools" OFF) +option(BUILD_TOOLS "Build OSRM tools" OFF) -include_directories(${CMAKE_SOURCE_DIR}/Include/) -include_directories(${CMAKE_SOURCE_DIR}/../../jansson/src/) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include/) add_custom_target(FingerPrintConfigure ALL ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake - COMMENT "Configuring FingerPrint.cpp" + COMMENT "Configuring revision fingerprint" VERBATIM) -set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread) +add_custom_target(tests DEPENDS datastructure-tests algorithm-tests) +add_custom_target(benchmarks DEPENDS rtree-bench) + +set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework) configure_file( - ${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in - ${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/util/git_sha.cpp.in + ${CMAKE_CURRENT_SOURCE_DIR}/util/git_sha.cpp ) -file(GLOB ExtractorGlob Extractor/*.cpp) -file(GLOB ExtractorGlobH Extractor/*.h) -file(GLOB ImporterGlob DataStructures/Import*.cpp) +file(GLOB ExtractorGlob extractor/*.cpp) +file(GLOB ImporterGlob data_structures/import_edge.cpp data_structures/external_memory_node.cpp) add_library(IMPORT OBJECT ${ImporterGlob}) -add_library(LOGGER OBJECT Util/simple_logger.cpp) +add_library(LOGGER OBJECT util/simple_logger.cpp) +add_library(PHANTOMNODE OBJECT data_structures/phantom_node.cpp) +add_library(EXCEPTION OBJECT util/osrm_exception.cpp) +add_library(MERCATOR OBJECT util/mercator.cpp) +add_library(ANGLE OBJECT util/compute_angle.cpp) -set(ExtractorSources extractor.cpp ${ExtractorGlob} ${ExtractorGlobH}) -add_executable(osrm-extract ${ExtractorSources} $ $ $ $ $) +set(ExtractorSources extract.cpp ${ExtractorGlob}) +add_executable(osrm-extract ${ExtractorSources} $ $ $ $ $ $ $) -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} ${PrepareGlobH}) -add_executable(osrm-prepare ${PrepareSources} $ $ $ $ $) +add_library(RESTRICTION OBJECT data_structures/restriction_map.cpp) -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) -file(GLOB CoordinateGlob DataStructures/Coordinate.cpp) -file(GLOB AlgorithmGlob Algorithms/*.cpp) -file(GLOB HttpGlob Server/Http/*.cpp) -file(GLOB LibOSRMGlob Library/*.cpp) +file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp {RestrictionMapGlob}) +set(PrepareSources prepare.cpp ${PrepareGlob}) +add_executable(osrm-prepare ${PrepareSources} $ $ $ $ $ $ $ $ $) -file(GLOB MapsMeSources mapsme/*.cpp) -file(GLOB MapsMeHeaders mapsme/*.h) -file(GLOB MapsMeGenerator "${OMIM_STORAGE_PATH}/country.cpp" "${OMIM_STORAGE_PATH}/country_decl.cpp" "${OMIM_STORAGE_PATH}/country_info.cpp") +file(GLOB ServerGlob server/*.cpp) +file(GLOB DescriptorGlob descriptors/*.cpp) +file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp util/bearing.cpp) +list(REMOVE_ITEM DatastructureGlob data_structures/Coordinate.cpp) +file(GLOB CoordinateGlob data_structures/coordinate*.cpp) +file(GLOB AlgorithmGlob algorithms/*.cpp) +file(GLOB HttpGlob server/http/*.cpp) +file(GLOB LibOSRMGlob library/*.cpp) +file(GLOB DataStructureTestsGlob unit_tests/data_structures/*.cpp data_structures/hilbert_value.cpp) +file(GLOB AlgorithmTestsGlob unit_tests/algorithms/*.cpp) set( OSRMSources ${LibOSRMGlob} ${DescriptorGlob} ${DatastructureGlob} - ${CoordinateGlob} ${AlgorithmGlob} ${HttpGlob} - ${MapsMeGenerator} ) + add_library(COORDINATE OBJECT ${CoordinateGlob}) -add_library(FINGERPRINT OBJECT Util/FingerPrint.cpp) -add_library(GITDESCRIPTION OBJECT Util/GitDescription.cpp) -add_library(OSRM ${OSRMSources} $ $ $ $) +add_library(GITDESCRIPTION OBJECT util/git_sha.cpp) +add_library(OSRM ${OSRMSources} $ $ $ $ $ $ $ $ $) + +add_library(FINGERPRINT OBJECT util/fingerprint.cpp) add_dependencies(FINGERPRINT FingerPrintConfigure) +add_dependencies(OSRM FingerPrintConfigure) +set_target_properties(FINGERPRINT PROPERTIES LINKER_LANGUAGE CXX) -add_executable(osrm-routed routed.cpp ${ServerGlob} ${RoutingAlgs}) -add_executable(osrm-datastore datastore.cpp $ $ $ $) -add_executable(osrm-mapsme ${MapsMeSources} ${MapsMeHeaders} "${CMAKE_SOURCE_DIR}/../../succinct/rs_bit_vector.cpp" $ $ $) +add_executable(osrm-routed routed.cpp ${ServerGlob} $) +add_executable(osrm-datastore datastore.cpp $ $ $ $ $ $) +# Unit tests +add_executable(datastructure-tests EXCLUDE_FROM_ALL unit_tests/datastructure_tests.cpp ${DataStructureTestsGlob} $ $ $ $ $) +add_executable(algorithm-tests EXCLUDE_FROM_ALL unit_tests/algorithm_tests.cpp ${AlgorithmTestsGlob} $ $ $ $) + +# Benchmarks +add_executable(rtree-bench EXCLUDE_FROM_ALL benchmarks/static_rtree.cpp $ $ $ $ $) # Check the release mode if(NOT CMAKE_BUILD_TYPE MATCHES Debug) @@ -105,7 +113,7 @@ if(NOT CMAKE_BUILD_TYPE MATCHES Debug) endif() if(CMAKE_BUILD_TYPE MATCHES Debug) message(STATUS "Configuring OSRM in debug mode") - if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") message(STATUS "adding profiling flags") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline") set(CMAKE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline") @@ -115,48 +123,68 @@ if(CMAKE_BUILD_TYPE MATCHES Release) message(STATUS "Configuring OSRM in release mode") # Check if LTO is available set(LTO_FLAGS "") - CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG) - if (HAS_LTO_FLAG) - set(LTO_FLAGS "${LTO_FLAGS} -flto") + check_cxx_compiler_flag("-flto" LTO_AVAILABLE) + if(LTO_AVAILABLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") + set(CHECK_LTO_SRC "int main(){return 0;}") + check_cxx_source_compiles("${CHECK_LTO_SRC}" LTO_WORKS) + if(LTO_WORKS) + message(STATUS "LTO working") + else() + message(STATUS "LTO broken") + set(CMAKE_CXX_FLAGS "${OLD_CXX_FLAGS}") + endif() # Since gcc 4.9 the LTO format is non-standart ('slim'), so we need to use the build-in tools - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0" AND NOT MINGW) message(STATUS "Using gcc specific binutils for LTO.") set(CMAKE_AR "/usr/bin/gcc-ar") set(CMAKE_RANLIB "/usr/bin/gcc-ranlib") endif() - endif (HAS_LTO_FLAG) + endif() +endif() + +if(NOT WIN32) + add_definitions(-DBOOST_TEST_DYN_LINK) endif() # Configuring compilers -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") +if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") # using Clang + # -Weverything -Wno-c++98-compat -Wno-shadow -Wno-exit-time-destructors set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -pedantic -fPIC") -elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") +elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + set(COLOR_FLAG "-fdiagnostics-color=auto") + check_cxx_compiler_flag("-fdiagnostics-color=auto" HAS_COLOR_FLAG) + if(NOT HAS_COLOR_FLAG) + set(COLOR_FLAG "") + endif() # using GCC - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC") - if (WIN32) # using mingw + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC ${COLOR_FLAG}") + if(WIN32) # using mingw 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) + set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32) endif() -elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") +elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel") # using Intel C++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -ipo -fPIC") -elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") +elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") # using Visual Studio C++ set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib) add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation add_definitions(-D_USE_MATH_DEFINES) # define M_PI add_definitions(-D_WIN32_WINNT=0x0501) + add_definitions(-DXML_STATIC) + find_library(ws2_32_LIBRARY_PATH ws2_32) + target_link_libraries(osrm-extract wsock32 ws2_32) endif() # Activate C++11 -if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - ADD_DEFINITIONS(-std=c++11) +if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ") endif() # Configuring other platform dependencies @@ -191,35 +219,20 @@ include_directories(${Boost_INCLUDE_DIRS}) target_link_libraries(OSRM ${Boost_LIBRARIES}) 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 - debug "${OMIM_DEBUG_PATH}/libcoding.a" - "${OMIM_DEBUG_PATH}/libbase.a" - "${OMIM_DEBUG_PATH}/libgeometry.a" - "${OMIM_DEBUG_PATH}/libindexer.a" - "${OMIM_DEBUG_PATH}/libjansson.a" - general "${OMIM_RELEASE_PATH}/libcoding.a" - "${OMIM_RELEASE_PATH}/libgeometry.a" - "${OMIM_RELEASE_PATH}/libindexer.a" - "${OMIM_RELEASE_PATH}/libjansson.a" - "${OMIM_RELEASE_PATH}/libbase.a") +target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM) target_link_libraries(osrm-datastore ${Boost_LIBRARIES}) - -target_link_libraries(osrm-mapsme ${Boost_LIBRARIES} OSRM - debug "${OMIM_DEBUG_PATH}/libcoding.a" - "${OMIM_DEBUG_PATH}/libbase.a" - "${OMIM_DEBUG_PATH}/librouting.a" - "${OMIM_DEBUG_PATH}/libgeometry.a" - "${OMIM_DEBUG_PATH}/libindexer.a" - general "${OMIM_RELEASE_PATH}/libcoding.a" - "${OMIM_RELEASE_PATH}/libbase.a" - "${OMIM_RELEASE_PATH}/librouting.a" - "${OMIM_RELEASE_PATH}/libgeometry.a" - "${OMIM_RELEASE_PATH}/libindexer.a") +target_link_libraries(datastructure-tests ${Boost_LIBRARIES}) +target_link_libraries(algorithm-tests ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM) +target_link_libraries(rtree-bench ${Boost_LIBRARIES}) find_package(Threads REQUIRED) -target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT} ${OPTIONAL_OMP_LIB}) +target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT}) 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(algorithm-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) @@ -229,6 +242,9 @@ 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(algorithm-tests ${TBB_LIBRARIES}) +target_link_libraries(rtree-bench ${TBB_LIBRARIES}) include_directories(${TBB_INCLUDE_DIR}) find_package( Luabind REQUIRED ) @@ -238,7 +254,7 @@ include_directories(${LUABIND_INCLUDE_DIR}) target_link_libraries(osrm-extract ${LUABIND_LIBRARY}) target_link_libraries(osrm-prepare ${LUABIND_LIBRARY}) -if( LUAJIT_FOUND ) +if(LUAJIT_FOUND) target_link_libraries(osrm-extract ${LUAJIT_LIBRARIES}) target_link_libraries(osrm-prepare ${LUAJIT_LIBRARIES}) else() @@ -247,17 +263,24 @@ else() endif() include_directories(${LUA_INCLUDE_DIR}) -find_package(LibXml2 REQUIRED) -include_directories(${LIBXML2_INCLUDE_DIR}) -target_link_libraries(osrm-extract ${LIBXML2_LIBRARIES}) +find_package(EXPAT REQUIRED) +include_directories(${EXPAT_INCLUDE_DIRS}) +target_link_libraries(osrm-extract ${EXPAT_LIBRARIES}) -find_package( STXXL REQUIRED ) +find_package(STXXL REQUIRED) include_directories(${STXXL_INCLUDE_DIR}) target_link_libraries(OSRM ${STXXL_LIBRARY}) target_link_libraries(osrm-extract ${STXXL_LIBRARY}) target_link_libraries(osrm-prepare ${STXXL_LIBRARY}) -find_package( OSMPBF REQUIRED ) +set(OpenMP_FIND_QUIETLY ON) +find_package(OpenMP) +if(OPENMP_FOUND) + message(STATUS "OpenMP support found. Linking just in case for stxxl") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") +endif() + +find_package(OSMPBF REQUIRED) include_directories(${OSMPBF_INCLUDE_DIR}) target_link_libraries(osrm-extract ${OSMPBF_LIBRARY}) target_link_libraries(osrm-prepare ${OSMPBF_LIBRARY}) @@ -276,32 +299,51 @@ include_directories(${ZLIB_INCLUDE_DIRS}) target_link_libraries(osrm-extract ${ZLIB_LIBRARY}) target_link_libraries(osrm-routed ${ZLIB_LIBRARY}) +if (ENABLE_JSON_LOGGING) + message(STATUS "Enabling json logging") + add_definitions(-DENABLE_JSON_LOGGING) +endif() + if(WITH_TOOLS OR BUILD_TOOLS) message(STATUS "Activating OSRM internal tools") find_package(GDAL) if(GDAL_FOUND) - add_executable(osrm-components Tools/components.cpp $ $ $ $) + add_executable(osrm-components tools/components.cpp $ $ $ $ $ $ $) target_link_libraries(osrm-components ${TBB_LIBRARIES}) include_directories(${GDAL_INCLUDE_DIR}) 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() - add_executable(osrm-cli Tools/simpleclient.cpp $) + add_executable(osrm-cli tools/simpleclient.cpp $ $ $) target_link_libraries(osrm-cli ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM) target_link_libraries(osrm-cli ${TBB_LIBRARIES}) - add_executable(osrm-io-benchmark Tools/io-benchmark.cpp $ $) + add_executable(osrm-io-benchmark tools/io-benchmark.cpp $ $ $) target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES}) - add_executable(osrm-unlock-all Tools/unlock_all_mutexes.cpp $ $) + add_executable(osrm-unlock-all tools/unlock_all_mutexes.cpp $ $ $) target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) if(UNIX AND NOT APPLE) target_link_libraries(osrm-unlock-all rt) endif() + add_executable(osrm-check-hsgr tools/check-hsgr.cpp $ $ $) + target_link_libraries(osrm-check-hsgr ${Boost_LIBRARIES}) + add_executable(osrm-springclean tools/springclean.cpp $ $ $ $) + target_link_libraries(osrm-springclean ${Boost_LIBRARIES}) + add_executable(osrm-graph-compare tools/graph_compare.cpp $ $ $ $ $ $ $) + target_link_libraries(osrm-graph-compare ${Boost_LIBRARIES} ${TBB_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) +file(GLOB InstallGlob include/osrm/*.hpp library/osrm.hpp) +file(GLOB VariantGlob third_party/variant/*.hpp) # Add RPATH info to executables so that when they are run after being installed # (i.e., from /usr/local/bin/) the linker can find library dependencies. For @@ -312,6 +354,7 @@ set_property(TARGET osrm-datastore PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE) set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE) install(FILES ${InstallGlob} DESTINATION include/osrm) +install(FILES ${VariantGlob} DESTINATION include/variant) install(TARGETS osrm-extract DESTINATION bin) install(TARGETS osrm-prepare DESTINATION bin) install(TARGETS osrm-datastore DESTINATION bin) @@ -320,13 +363,13 @@ install(TARGETS OSRM DESTINATION lib) list(GET Boost_LIBRARIES 1 BOOST_LIBRARY_FIRST) get_filename_component(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_FIRST}" PATH) set(BOOST_LIBRARY_LISTING "-L${BOOST_LIBRARY_LISTING}") -foreach (lib ${Boost_LIBRARIES}) +foreach(lib ${Boost_LIBRARIES}) get_filename_component(BOOST_LIBRARY_NAME "${lib}" NAME_WE) string(REPLACE "lib" "" BOOST_LIBRARY_NAME ${BOOST_LIBRARY_NAME}) set(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_LISTING} -l${BOOST_LIBRARY_NAME}") -endforeach () +endforeach() -configure_file(${CMAKE_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY) install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig) if(BUILD_DEBIAN_PACKAGE) diff --git a/3party/osrm/osrm-backend/DataStructures/Coordinate.cpp b/3party/osrm/osrm-backend/DataStructures/Coordinate.cpp deleted file mode 100644 index fee8c9648f..0000000000 --- a/3party/osrm/osrm-backend/DataStructures/Coordinate.cpp +++ /dev/null @@ -1,465 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include - -#include "../Util/MercatorUtil.h" -#include "../Util/StringUtil.h" - -#include - -#include -#include - - -FixedPointCoordinate::FixedPointCoordinate() - : lat(std::numeric_limits::min()), lon(std::numeric_limits::min()) -{ -} - -FixedPointCoordinate::FixedPointCoordinate(int lat, int lon) : lat(lat), lon(lon) -{ -} - -void FixedPointCoordinate::Reset() -{ - lat = std::numeric_limits::min(); - lon = std::numeric_limits::min(); -} -bool FixedPointCoordinate::isSet() const -{ - return (std::numeric_limits::min() != lat) && (std::numeric_limits::min() != lon); -} -bool FixedPointCoordinate::isValid() const -{ - if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION || - lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION) - { - return false; - } - return true; -} -bool FixedPointCoordinate::operator==(const FixedPointCoordinate &other) const -{ - return lat == other.lat && lon == other.lon; -} - -double FixedPointCoordinate::ApproximateDistance(const int lat1, - const int lon1, - const int lat2, - const int lon2) -{ - BOOST_ASSERT(lat1 != std::numeric_limits::min()); - BOOST_ASSERT(lon1 != std::numeric_limits::min()); - BOOST_ASSERT(lat2 != std::numeric_limits::min()); - BOOST_ASSERT(lon2 != std::numeric_limits::min()); - double RAD = 0.017453292519943295769236907684886; - double lt1 = lat1 / COORDINATE_PRECISION; - double ln1 = lon1 / COORDINATE_PRECISION; - double lt2 = lat2 / COORDINATE_PRECISION; - double ln2 = lon2 / COORDINATE_PRECISION; - double dlat1 = lt1 * (RAD); - - double dlong1 = ln1 * (RAD); - double dlat2 = lt2 * (RAD); - double dlong2 = ln2 * (RAD); - - double dLong = dlong1 - dlong2; - double dLat = dlat1 - dlat2; - - double aHarv = pow(sin(dLat / 2.0), 2.0) + cos(dlat1) * cos(dlat2) * pow(sin(dLong / 2.), 2); - double cHarv = 2. * atan2(sqrt(aHarv), sqrt(1.0 - aHarv)); - // earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi) - // The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles) - const double earth = 6372797.560856; - return earth * cHarv; -} - -double FixedPointCoordinate::ApproximateDistance(const FixedPointCoordinate &coordinate_1, - const FixedPointCoordinate &coordinate_2) -{ - return ApproximateDistance( - coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon); -} - -float FixedPointCoordinate::ApproximateEuclideanDistance(const FixedPointCoordinate &coordinate_1, - const FixedPointCoordinate &coordinate_2) -{ - return ApproximateEuclideanDistance( - coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon); -} - -float FixedPointCoordinate::ApproximateEuclideanDistance(const int lat1, - const int lon1, - const int lat2, - const int lon2) -{ - BOOST_ASSERT(lat1 != std::numeric_limits::min()); - BOOST_ASSERT(lon1 != std::numeric_limits::min()); - BOOST_ASSERT(lat2 != std::numeric_limits::min()); - BOOST_ASSERT(lon2 != std::numeric_limits::min()); - - const float RAD = 0.017453292519943295769236907684886f; - const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD; - const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD; - const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD; - const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD; - - const float x_value = (float_lon2 - float_lon1) * cos((float_lat1 + float_lat2) / 2.f); - const float y_value = float_lat2 - float_lat1; - const float earth_radius = 6372797.560856f; - return sqrt(x_value * x_value + y_value * y_value) * earth_radius; -} - -float -FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &source_coordinate, - const FixedPointCoordinate &target_coordinate, - const FixedPointCoordinate &point) -{ - // initialize values - const float x_value = static_cast(lat2y(point.lat / COORDINATE_PRECISION)); - const float y_value = point.lon / COORDINATE_PRECISION; - float a = static_cast(lat2y(source_coordinate.lat / COORDINATE_PRECISION)); - float b = source_coordinate.lon / COORDINATE_PRECISION; - float c = static_cast(lat2y(target_coordinate.lat / COORDINATE_PRECISION)); - float d = target_coordinate.lon / COORDINATE_PRECISION; - float p, q; - if (std::abs(a - c) > std::numeric_limits::epsilon()) - { - const float slope = (d - b) / (c - a); // slope - // Projection of (x,y) on line joining (a,b) and (c,d) - p = ((x_value + (slope * y_value)) + (slope * slope * a - slope * b)) / - (1.f + slope * slope); - q = b + slope * (p - a); - } - else - { - p = c; - q = y_value; - } - - float ratio; - bool inverse_ratio = false; - - // straight line segment on equator - if (std::abs(c) < std::numeric_limits::epsilon() && - std::abs(a) < std::numeric_limits::epsilon()) - { - ratio = (q - b) / (d - b); - } - else - { - if (std::abs(c) < std::numeric_limits::epsilon()) - { - // swap start/end - std::swap(a, c); - std::swap(b, d); - inverse_ratio = true; - } - - float nY = (d * p - c * q) / (a * d - b * c); - // discretize the result to coordinate precision. it's a hack! - if (std::abs(nY) < (1.f / COORDINATE_PRECISION)) - { - nY = 0.f; - } - - // compute ratio - ratio = (p - nY * a) / c; - } - - if (std::isnan(ratio)) - { - ratio = (target_coordinate == point ? 1.f : 0.f); - } - else if (std::abs(ratio) <= std::numeric_limits::epsilon()) - { - ratio = 0.f; - } - else if (std::abs(ratio - 1.f) <= std::numeric_limits::epsilon()) - { - ratio = 1.f; - } - - // we need to do this, if we switched start/end coordinates - if (inverse_ratio) - { - ratio = 1.0f - ratio; - } - - // compute the nearest location - FixedPointCoordinate nearest_location; - BOOST_ASSERT(!std::isnan(ratio)); - if (ratio <= 0.f) - { // point is "left" of edge - nearest_location = source_coordinate; - } - else if (ratio >= 1.f) - { // point is "right" of edge - nearest_location = target_coordinate; - } - else - { // point lies in between - nearest_location.lat = static_cast(y2lat(p) * COORDINATE_PRECISION); - nearest_location.lon = static_cast(q * COORDINATE_PRECISION); - } - - BOOST_ASSERT(nearest_location.isValid()); - return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location); -} - -float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &segment_source, - const FixedPointCoordinate &segment_target, - const FixedPointCoordinate &query_location, - FixedPointCoordinate &nearest_location, - float &ratio) -{ - BOOST_ASSERT(query_location.isValid()); - - // initialize values - const double x = lat2y(query_location.lat / COORDINATE_PRECISION); - const double y = query_location.lon / COORDINATE_PRECISION; - const double a = lat2y(segment_source.lat / COORDINATE_PRECISION); - const double b = segment_source.lon / COORDINATE_PRECISION; - const double c = lat2y(segment_target.lat / COORDINATE_PRECISION); - const double d = segment_target.lon / COORDINATE_PRECISION; - double p, q /*,mX*/, nY; - if (std::abs(a - c) > std::numeric_limits::epsilon()) - { - const double m = (d - b) / (c - a); // slope - // Projection of (x,y) on line joining (a,b) and (c,d) - p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m); - q = b + m * (p - a); - } - else - { - p = c; - q = y; - } - nY = (d * p - c * q) / (a * d - b * c); - - // discretize the result to coordinate precision. it's a hack! - if (std::abs(nY) < (1.f / COORDINATE_PRECISION)) - { - nY = 0.f; - } - - // compute ratio - ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need - // not calculate the explicit values of m an n as we - // are just interested in the ratio - if (std::isnan(ratio)) - { - ratio = (segment_target == query_location ? 1.f : 0.f); - } - else if (std::abs(ratio) <= std::numeric_limits::epsilon()) - { - ratio = 0.f; - } - else if (std::abs(ratio - 1.f) <= std::numeric_limits::epsilon()) - { - ratio = 1.f; - } - - // compute nearest location - BOOST_ASSERT(!std::isnan(ratio)); - if (ratio <= 0.f) - { - nearest_location = segment_source; - } - else if (ratio >= 1.f) - { - nearest_location = segment_target; - } - else - { - // point lies in between - nearest_location.lat = static_cast(y2lat(p) * COORDINATE_PRECISION); - nearest_location.lon = static_cast(q * COORDINATE_PRECISION); - } - BOOST_ASSERT(nearest_location.isValid()); - - const float approximate_distance = - FixedPointCoordinate::ApproximateEuclideanDistance(query_location, nearest_location); - BOOST_ASSERT(0. <= approximate_distance); - return approximate_distance; -} - -void FixedPointCoordinate::convertInternalLatLonToString(const int value, std::string &output) -{ - char buffer[12]; - buffer[11] = 0; // zero termination - output = printInt<11, 6>(buffer, value); -} - -void FixedPointCoordinate::convertInternalCoordinateToString(const FixedPointCoordinate &coord, - std::string &output) -{ - std::string tmp; - tmp.reserve(23); - convertInternalLatLonToString(coord.lon, tmp); - output = tmp; - output += ","; - convertInternalLatLonToString(coord.lat, tmp); - output += tmp; -} - -void -FixedPointCoordinate::convertInternalReversedCoordinateToString(const FixedPointCoordinate &coord, - std::string &output) -{ - std::string tmp; - tmp.reserve(23); - convertInternalLatLonToString(coord.lat, tmp); - output = tmp; - output += ","; - convertInternalLatLonToString(coord.lon, tmp); - output += tmp; -} - -void FixedPointCoordinate::Output(std::ostream &out) const -{ - out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")"; -} - -float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &first_coordinate, - const FixedPointCoordinate &second_coordinate) -{ - const float lon_diff = - second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION; - const float lon_delta = DegreeToRadian(lon_diff); - const float lat1 = DegreeToRadian(first_coordinate.lat / COORDINATE_PRECISION); - const float lat2 = DegreeToRadian(second_coordinate.lat / COORDINATE_PRECISION); - const float y = sin(lon_delta) * cos(lat2); - const float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon_delta); - float result = RadianToDegree(std::atan2(y, x)); - while (result < 0.f) - { - result += 360.f; - } - - while (result >= 360.f) - { - result -= 360.f; - } - return result; -} - -float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &other) const -{ - const float lon_delta = - DegreeToRadian(lon / COORDINATE_PRECISION - other.lon / COORDINATE_PRECISION); - const float lat1 = DegreeToRadian(other.lat / COORDINATE_PRECISION); - const float lat2 = DegreeToRadian(lat / COORDINATE_PRECISION); - const float y_value = std::sin(lon_delta) * std::cos(lat2); - const float x_value = - std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta); - float result = RadianToDegree(std::atan2(y_value, x_value)); - - while (result < 0.f) - { - result += 360.f; - } - - while (result >= 360.f) - { - result -= 360.f; - } - return result; -} - -float FixedPointCoordinate::DegreeToRadian(const float degree) -{ - return degree * (static_cast(M_PI) / 180.f); -} - -float FixedPointCoordinate::RadianToDegree(const float radian) -{ - return radian * (180.f * static_cast(M_1_PI)); -} - -// This distance computation does integer arithmetic only and is a lot faster than -// the other distance function which are numerically correct('ish). -// It preserves some order among the elements that make it useful for certain purposes -int FixedPointCoordinate::OrderedPerpendicularDistanceApproximation( - const FixedPointCoordinate &input_point, - const FixedPointCoordinate &segment_source, - const FixedPointCoordinate &segment_target) -{ - // initialize values - const float x = static_cast(lat2y(input_point.lat / COORDINATE_PRECISION)); - const float y = input_point.lon / COORDINATE_PRECISION; - const float a = static_cast(lat2y(segment_source.lat / COORDINATE_PRECISION)); - const float b = segment_source.lon / COORDINATE_PRECISION; - const float c = static_cast(lat2y(segment_target.lat / COORDINATE_PRECISION)); - const float d = segment_target.lon / COORDINATE_PRECISION; - - float p, q; - if (a == c) - { - p = c; - q = y; - } - else - { - const float m = (d - b) / (c - a); // slope - // Projection of (x,y) on line joining (a,b) and (c,d) - p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m); - q = b + m * (p - a); - } - - const float nY = (d * p - c * q) / (a * d - b * c); - float ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need - // not calculate the explicit values of m an n as we - // are just interested in the ratio - if (std::isnan(ratio)) - { - ratio = (segment_target == input_point) ? 1.f : 0.f; - } - - // compute target quasi-location - int dx, dy; - if (ratio < 0.f) - { - dx = input_point.lon - segment_source.lon; - dy = input_point.lat - segment_source.lat; - } - else if (ratio > 1.f) - { - dx = input_point.lon - segment_target.lon; - dy = input_point.lat - segment_target.lat; - } - else - { - // point lies in between - dx = input_point.lon - static_cast(q * COORDINATE_PRECISION); - dy = input_point.lat - static_cast(y2lat(p) * COORDINATE_PRECISION); - } - - // return an approximation in the plane - return static_cast(sqrt(dx * dx + dy * dy)); -} diff --git a/3party/osrm/osrm-backend/DataStructures/EdgeBasedNode.h b/3party/osrm/osrm-backend/DataStructures/EdgeBasedNode.h deleted file mode 100644 index 869ed5bdc9..0000000000 --- a/3party/osrm/osrm-backend/DataStructures/EdgeBasedNode.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef EDGE_BASED_NODE_H -#define EDGE_BASED_NODE_H - -#include "../DataStructures/TravelMode.h" -#include "../typedefs.h" - -#include "../Include/osrm/Coordinate.h" - -#include - -#include - -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), - v(SPECIAL_NODEID), - name_id(0), - forward_weight(INVALID_EDGE_WEIGHT >> 1), - reverse_weight(INVALID_EDGE_WEIGHT >> 1), - forward_offset(0), - reverse_offset(0), - packed_geometry_id(SPECIAL_EDGEID), - fwd_segment_position( std::numeric_limits::max() ), - is_in_tiny_cc(false), - forward_travel_mode(TRAVEL_MODE_INACCESSIBLE), - backward_travel_mode(TRAVEL_MODE_INACCESSIBLE) - { } - - explicit EdgeBasedNode( - unsigned forward_way_id, - unsigned reverse_way_id, - NodeID forward_edge_based_node_id, - NodeID reverse_edge_based_node_id, - NodeID u, - NodeID v, - unsigned name_id, - int forward_weight, - int reverse_weight, - int forward_offset, - int reverse_offset, - unsigned packed_geometry_id, - unsigned short fwd_segment_position, - bool belongs_to_tiny_component, - 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), - v(v), - name_id(name_id), - forward_weight(forward_weight), - reverse_weight(reverse_weight), - forward_offset(forward_offset), - reverse_offset(reverse_offset), - packed_geometry_id(packed_geometry_id), - fwd_segment_position(fwd_segment_position), - is_in_tiny_cc(belongs_to_tiny_component), - forward_travel_mode(forward_travel_mode), - backward_travel_mode(backward_travel_mode) - { - BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) || - (reverse_edge_based_node_id != SPECIAL_NODEID)); - } - - static inline FixedPointCoordinate Centroid(const FixedPointCoordinate & a, const FixedPointCoordinate & b) - { - FixedPointCoordinate centroid; - //The coordinates of the midpoint are given by: - centroid.lat = (a.lat + b.lat)/2; - centroid.lon = (a.lon + b.lon)/2; - return centroid; - } - - bool IsCompressed() const - { - 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 - NodeID v; // indices into the coordinates array - unsigned name_id; // id of the edge name - int forward_weight; // weight of the edge - int reverse_weight; // weight in the other direction (may be different) - int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice - int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice - unsigned packed_geometry_id; // if set, then the edge represents a packed geometry - unsigned short fwd_segment_position; // segment id in a compressed geometry - bool is_in_tiny_cc; - TravelMode forward_travel_mode : 4; - TravelMode backward_travel_mode : 4; -}; - -#endif //EDGE_BASED_NODE_H diff --git a/3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h b/3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h deleted file mode 100644 index dbcadfe01b..0000000000 --- a/3party/osrm/osrm-backend/DataStructures/EdgeBasedNodeData.h +++ /dev/null @@ -1,123 +0,0 @@ -#pragma once - -#include -#include -#include - - -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 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 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; -} - -} diff --git a/3party/osrm/osrm-backend/DataStructures/InputReaderFactory.h b/3party/osrm/osrm-backend/DataStructures/InputReaderFactory.h deleted file mode 100644 index 3f6aa3c63b..0000000000 --- a/3party/osrm/osrm-backend/DataStructures/InputReaderFactory.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef INPUT_READER_FACTORY_H -#define INPUT_READER_FACTORY_H - -#include - -#include -#include - -struct BZ2Context -{ - FILE *file; - BZFILE *bz2; - int error; - int nUnused; - char unused[BZ_MAX_UNUSED]; -}; - -int readFromBz2Stream(void *pointer, char *buffer, int len) -{ - void *unusedTmpVoid = nullptr; - char *unusedTmp = nullptr; - BZ2Context *context = (BZ2Context *)pointer; - int read = 0; - while (0 == read && - !(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file))) - { - read = BZ2_bzRead(&context->error, context->bz2, buffer, len); - if (BZ_OK == context->error) - { - return read; - } - else if (BZ_STREAM_END == context->error) - { - BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused); - BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused"); - unusedTmp = (char *)unusedTmpVoid; - for (int i = 0; i < context->nUnused; i++) - { - context->unused[i] = unusedTmp[i]; - } - BZ2_bzReadClose(&context->error, context->bz2); - BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose"); - context->error = BZ_STREAM_END; // set to the stream end for next call to this function - if (0 == context->nUnused && feof(context->file)) - { - return read; - } - else - { - context->bz2 = BZ2_bzReadOpen( - &context->error, context->file, 0, 0, context->unused, context->nUnused); - BOOST_ASSERT_MSG(nullptr != context->bz2, "Could not open file"); - } - } - else - { - BOOST_ASSERT_MSG(false, "Could not read bz2 file"); - } - } - return read; -} - -int closeBz2Stream(void *pointer) -{ - BZ2Context *context = (BZ2Context *)pointer; - fclose(context->file); - delete context; - return 0; -} - -xmlTextReaderPtr inputReaderFactory(const char *name) -{ - std::string inputName(name); - - if (inputName.find(".osm.bz2") != std::string::npos) - { - BZ2Context *context = new BZ2Context(); - context->error = false; - context->file = fopen(name, "r"); - int error; - context->bz2 = - BZ2_bzReadOpen(&error, context->file, 0, 0, context->unused, context->nUnused); - if (context->bz2 == nullptr || context->file == nullptr) - { - delete context; - return nullptr; - } - return xmlReaderForIO(readFromBz2Stream, closeBz2Stream, (void *)context, nullptr, nullptr, 0); - } - else - { - return xmlNewTextReaderFilename(name); - } -} - -#endif // INPUT_READER_FACTORY_H diff --git a/3party/osrm/osrm-backend/DataStructures/PhantomNodes.h b/3party/osrm/osrm-backend/DataStructures/PhantomNodes.h deleted file mode 100644 index 88028a67be..0000000000 --- a/3party/osrm/osrm-backend/DataStructures/PhantomNodes.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef PHANTOM_NODES_H -#define PHANTOM_NODES_H - -#include "../Include/osrm/Coordinate.h" -#include "../DataStructures/TravelMode.h" -#include "../Util/simple_logger.hpp" -#include "../typedefs.h" - -#include - -struct PhantomNode -{ - PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id, - int forward_weight, int reverse_weight, int forward_offset, int reverse_offset, - unsigned packed_geometry_id, FixedPointCoordinate &location, - unsigned short fwd_segment_position, - TravelMode forward_travel_mode, TravelMode backward_travel_mode) : - forward_node_id(forward_node_id), - reverse_node_id(reverse_node_id), - name_id(name_id), - forward_weight(forward_weight), - reverse_weight(reverse_weight), - forward_offset(forward_offset), - reverse_offset(reverse_offset), - packed_geometry_id(packed_geometry_id), - location(location), - fwd_segment_position(fwd_segment_position), - forward_travel_mode(forward_travel_mode), - backward_travel_mode(backward_travel_mode) - { } - - PhantomNode() : - forward_node_id(SPECIAL_NODEID), - reverse_node_id(SPECIAL_NODEID), - name_id(std::numeric_limits::max()), - forward_weight(INVALID_EDGE_WEIGHT), - reverse_weight(INVALID_EDGE_WEIGHT), - forward_offset(0), - reverse_offset(0), - packed_geometry_id(SPECIAL_EDGEID), - fwd_segment_position(0), - forward_travel_mode(TRAVEL_MODE_INACCESSIBLE), - backward_travel_mode(TRAVEL_MODE_INACCESSIBLE) - { } - - NodeID forward_node_id; - NodeID reverse_node_id; - unsigned name_id; - int forward_weight; - int reverse_weight; - int forward_offset; - int reverse_offset; - unsigned packed_geometry_id; - FixedPointCoordinate location; - unsigned short fwd_segment_position; - TravelMode forward_travel_mode : 4; - TravelMode backward_travel_mode : 4; - - int GetForwardWeightPlusOffset() const - { - if (SPECIAL_NODEID == forward_node_id) - { - return 0; - } - const int result = (forward_offset + forward_weight); - return result; - } - - int GetReverseWeightPlusOffset() const - { - if (SPECIAL_NODEID == reverse_node_id) - { - return 0; - } - const int result = (reverse_offset + reverse_weight); - return result; - } - - bool isBidirected() const - { - return (forward_node_id != SPECIAL_NODEID) && - (reverse_node_id != SPECIAL_NODEID); - } - - bool IsCompressed() const - { - return (forward_offset != 0) || (reverse_offset != 0); - } - - bool isValid(const unsigned numberOfNodes) const - { - return - location.isValid() && - ( - (forward_node_id < numberOfNodes) || - (reverse_node_id < numberOfNodes) - ) && - ( - (forward_weight != INVALID_EDGE_WEIGHT) || - (reverse_weight != INVALID_EDGE_WEIGHT) - ) && - (name_id != std::numeric_limits::max() - ); - } - - bool isValid() const - { - return location.isValid() && - (name_id != std::numeric_limits::max()); - } - - bool operator==(const PhantomNode & other) const - { - return location == other.location; - } -}; - -using PhantomNodeArray = std::vector>; - -struct PhantomNodeLists -{ - std::vector source_phantom_list; - std::vector target_phantom_list; -}; - -struct PhantomNodes -{ - PhantomNode source_phantom; - PhantomNode target_phantom; -}; - -inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn) -{ - out << "source_coord: " << pn.source_phantom.location << "\n"; - out << "target_coord: " << pn.target_phantom.location << std::endl; - return out; -} - -inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn) -{ - out << "node1: " << pn.forward_node_id << ", " << - "node2: " << pn.reverse_node_id << ", " << - "name: " << pn.name_id << ", " << - "fwd-w: " << pn.forward_weight << ", " << - "rev-w: " << pn.reverse_weight << ", " << - "fwd-o: " << pn.forward_offset << ", " << - "rev-o: " << pn.reverse_offset << ", " << - "geom: " << pn.packed_geometry_id << ", " << - "pos: " << pn.fwd_segment_position << ", " << - "loc: " << pn.location; - return out; -} - -#endif // PHANTOM_NODES_H diff --git a/3party/osrm/osrm-backend/Descriptors/DescriptionFactory.cpp b/3party/osrm/osrm-backend/Descriptors/DescriptionFactory.cpp deleted file mode 100644 index 715bf69037..0000000000 --- a/3party/osrm/osrm-backend/Descriptors/DescriptionFactory.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "DescriptionFactory.h" - -#include - -#include "../typedefs.h" -#include "../Algorithms/PolylineCompressor.h" -#include "../DataStructures/PhantomNodes.h" -#include "../DataStructures/RawRouteData.h" -#include "../DataStructures/SegmentInformation.h" -#include "../DataStructures/TurnInstructions.h" - -DescriptionFactory::DescriptionFactory() : entireLength(0) { via_indices.push_back(0); } - -std::vector const &DescriptionFactory::GetViaIndices() const { return via_indices; } - -void DescriptionFactory::SetStartSegment(const PhantomNode &source, const bool traversed_in_reverse) -{ - start_phantom = source; - const EdgeWeight segment_duration = - (traversed_in_reverse ? source.reverse_weight : source.forward_weight); - const TravelMode travel_mode = - (traversed_in_reverse ? source.backward_travel_mode : source.forward_travel_mode); - AppendSegment( - source.location, - PathData(0, source.name_id, TurnInstruction::HeadOn, segment_duration, travel_mode)); - BOOST_ASSERT(path_description.back().duration == segment_duration); -} - -void DescriptionFactory::SetEndSegment(const PhantomNode &target, - const bool traversed_in_reverse, - const bool is_via_location) -{ - target_phantom = target; - const EdgeWeight segment_duration = - (traversed_in_reverse ? target.reverse_weight : target.forward_weight); - const TravelMode travel_mode = - (traversed_in_reverse ? target.backward_travel_mode : target.forward_travel_mode); - path_description.emplace_back(target.location, - target.name_id, - segment_duration, - 0.f, - is_via_location ? TurnInstruction::ReachViaLocation - : TurnInstruction::NoTurn, - true, - true, - travel_mode); - BOOST_ASSERT(path_description.back().duration == segment_duration); -} - -void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate, - const PathData &path_point) -{ - // if the start location is on top of a node, the first movement might be zero-length, - // in which case we dont' add a new description, but instead update the existing one - if ((1 == path_description.size()) && (path_description.front().location == coordinate)) - { - if (path_point.segment_duration > 0) - { - path_description.front().name_id = path_point.name_id; - path_description.front().travel_mode = path_point.travel_mode; - } - return; - } - - // make sure mode changes are announced, even when there otherwise is no turn - const TurnInstruction turn = [&]() -> TurnInstruction - { - if (TurnInstruction::NoTurn == path_point.turn_instruction && - path_description.front().travel_mode != path_point.travel_mode && - path_point.segment_duration > 0) - { - return TurnInstruction::GoStraight; - } - return path_point.turn_instruction; - }(); - - path_description.emplace_back(coordinate, - path_point.name_id, - path_point.segment_duration, - 0.f, - turn, - path_point.travel_mode); -} - -JSON::Value DescriptionFactory::AppendGeometryString(const bool return_encoded) -{ - if (return_encoded) - { - return polyline_compressor.printEncodedString(path_description); - } - return polyline_compressor.printUnencodedString(path_description); -} - -void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time) -{ - summary.source_name_id = start_phantom.name_id; - summary.target_name_id = target_phantom.name_id; - summary.BuildDurationAndLengthStrings(distance, time); -} diff --git a/3party/osrm/osrm-backend/Descriptors/DescriptionFactory.h b/3party/osrm/osrm-backend/Descriptors/DescriptionFactory.h deleted file mode 100644 index ac4c70234f..0000000000 --- a/3party/osrm/osrm-backend/Descriptors/DescriptionFactory.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef DESCRIPTIONFACTORY_H_ -#define DESCRIPTIONFACTORY_H_ - -#include "../Algorithms/DouglasPeucker.h" -#include "../Algorithms/PolylineCompressor.h" -#include "../DataStructures/PhantomNodes.h" -#include "../DataStructures/SegmentInformation.h" -#include "../DataStructures/TurnInstructions.h" -#include "../typedefs.h" - -#include - -#include -#include - -struct PathData; -/* This class is fed with all way segments in consecutive order - * and produces the description plus the encoded polyline */ - -class DescriptionFactory -{ - DouglasPeucker polyline_generalizer; - PolylineCompressor polyline_compressor; - PhantomNode start_phantom, target_phantom; - - double DegreeToRadian(const double degree) const; - double RadianToDegree(const double degree) const; - - std::vector via_indices; - - public: - struct RouteSummary - { - unsigned distance; - EdgeWeight duration; - unsigned source_name_id; - unsigned target_name_id; - RouteSummary() : distance(0), duration(0), source_name_id(0), target_name_id(0) {} - - void BuildDurationAndLengthStrings(const double raw_distance, const unsigned raw_duration) - { - // compute distance/duration for route summary - distance = static_cast(round(raw_distance)); - duration = static_cast(round(raw_duration / 10.)); - } - } summary; - - double entireLength; - - // I know, declaring this public is considered bad. I'm lazy - std::vector path_description; - DescriptionFactory(); - void AppendSegment(const FixedPointCoordinate &coordinate, const PathData &data); - void BuildRouteSummary(const double distance, const unsigned time); - void SetStartSegment(const PhantomNode &start_phantom, const bool traversed_in_reverse); - void SetEndSegment(const PhantomNode &start_phantom, - const bool traversed_in_reverse, - const bool is_via_location = false); - JSON::Value AppendGeometryString(const bool return_encoded); - std::vector const &GetViaIndices() const; - - template void Run(const DataFacadeT *facade, const unsigned zoomLevel) - { - if (path_description.empty()) - { - return; - } - - /** starts at index 1 */ - path_description[0].length = 0; - for (unsigned i = 1; i < path_description.size(); ++i) - { - // move down names by one, q&d hack - path_description[i - 1].name_id = path_description[i].name_id; - path_description[i].length = FixedPointCoordinate::ApproximateEuclideanDistance( - path_description[i - 1].location, path_description[i].location); - } - - /*Simplify turn instructions - Input : - 10. Turn left on B 36 for 20 km - 11. Continue on B 35; B 36 for 2 km - 12. Continue on B 36 for 13 km - - becomes: - 10. Turn left on B 36 for 35 km - */ - // TODO: rework to check only end and start of string. - // stl string is way to expensive - - // unsigned lastTurn = 0; - // for(unsigned i = 1; i < path_description.size(); ++i) { - // string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id); - // if(TurnInstruction::GoStraight == path_description[i].turn_instruction) { - // if(std::string::npos != string0.find(string1+";") - // || std::string::npos != string0.find(";"+string1) - // || std::string::npos != string0.find(string1+" ;") - // || std::string::npos != string0.find("; "+string1) - // ){ - // SimpleLogger().Write() << "->next correct: " << string0 << " contains " << - // string1; - // for(; lastTurn != i; ++lastTurn) - // path_description[lastTurn].name_id = path_description[i].name_id; - // path_description[i].turn_instruction = TurnInstruction::NoTurn; - // } else if(std::string::npos != string1.find(string0+";") - // || std::string::npos != string1.find(";"+string0) - // || std::string::npos != string1.find(string0+" ;") - // || std::string::npos != string1.find("; "+string0) - // ){ - // SimpleLogger().Write() << "->prev correct: " << string1 << " contains " << - // string0; - // path_description[i].name_id = path_description[i-1].name_id; - // path_description[i].turn_instruction = TurnInstruction::NoTurn; - // } - // } - // if (TurnInstruction::NoTurn != path_description[i].turn_instruction) { - // lastTurn = i; - // } - // string0 = string1; - // } - - float segment_length = 0.; - unsigned segment_duration = 0; - unsigned segment_start_index = 0; - - for (unsigned i = 1; i < path_description.size(); ++i) - { - entireLength += path_description[i].length; - segment_length += path_description[i].length; - segment_duration += path_description[i].duration; - path_description[segment_start_index].length = segment_length; - path_description[segment_start_index].duration = segment_duration; - - if (TurnInstruction::NoTurn != path_description[i].turn_instruction) - { - BOOST_ASSERT(path_description[i].necessary); - segment_length = 0; - segment_duration = 0; - segment_start_index = i; - } - } - - // Post-processing to remove empty or nearly empty path segments - if (std::numeric_limits::epsilon() > path_description.back().length) - { - if (path_description.size() > 2) - { - path_description.pop_back(); - path_description.back().necessary = true; - path_description.back().turn_instruction = TurnInstruction::NoTurn; - target_phantom.name_id = (path_description.end() - 2)->name_id; - } - } - if (std::numeric_limits::epsilon() > path_description.front().length) - { - if (path_description.size() > 2) - { - path_description.erase(path_description.begin()); - path_description.front().turn_instruction = TurnInstruction::HeadOn; - path_description.front().necessary = true; - start_phantom.name_id = path_description.front().name_id; - } - } - - // Generalize poly line - polyline_generalizer.Run(path_description, zoomLevel); - - // fix what needs to be fixed else - unsigned necessary_pieces = 0; // a running index that counts the necessary pieces - for (unsigned i = 0; i < path_description.size() - 1 && path_description.size() >= 2; ++i) - { - if (path_description[i].necessary) - { - ++necessary_pieces; - if (path_description[i].is_via_location) - { // mark the end of a leg - via_indices.push_back(necessary_pieces); - } - const double angle = - path_description[i + 1].location.GetBearing(path_description[i].location); - path_description[i].bearing = static_cast(angle * 10); - } - } - via_indices.push_back(necessary_pieces + 1); - BOOST_ASSERT(via_indices.size() >= 2); - // BOOST_ASSERT(0 != necessary_pieces || path_description.empty()); - return; - } -}; - -#endif /* DESCRIPTIONFACTORY_H_ */ diff --git a/3party/osrm/osrm-backend/Descriptors/GPXDescriptor.h b/3party/osrm/osrm-backend/Descriptors/GPXDescriptor.h deleted file mode 100644 index 6f76b3bc87..0000000000 --- a/3party/osrm/osrm-backend/Descriptors/GPXDescriptor.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef GPX_DESCRIPTOR_H -#define GPX_DESCRIPTOR_H - -#include "BaseDescriptor.h" - -template class GPXDescriptor final : public BaseDescriptor -{ - private: - DescriptorConfig config; - FixedPointCoordinate current; - DataFacadeT *facade; - - void AddRoutePoint(const FixedPointCoordinate &coordinate, std::vector &output) - { - const std::string route_point_head = ""; - - std::string tmp; - - FixedPointCoordinate::convertInternalLatLonToString(coordinate.lat, tmp); - output.insert(output.end(), route_point_head.begin(), route_point_head.end()); - output.insert(output.end(), tmp.begin(), tmp.end()); - output.push_back('\"'); - - FixedPointCoordinate::convertInternalLatLonToString(coordinate.lon, tmp); - output.insert(output.end(), route_point_middle.begin(), route_point_middle.end()); - output.insert(output.end(), tmp.begin(), tmp.end()); - output.insert(output.end(), route_point_tail.begin(), route_point_tail.end()); - } - - public: - explicit GPXDescriptor(DataFacadeT *facade) : facade(facade) {} - - void SetConfig(const DescriptorConfig &c) final { config = c; } - - // TODO: reorder parameters - void Run(const RawRouteData &raw_route, http::Reply &reply) final - { - std::string header("" - "" - "Data (c)" - " OpenStreetMap contributors (ODbL)" - "" - ""); - reply.content.insert(reply.content.end(), header.begin(), header.end()); - const bool found_route = (raw_route.shortest_path_length != INVALID_EDGE_WEIGHT) && - (!raw_route.unpacked_path_segments.front().empty()); - if (found_route) - { - AddRoutePoint(raw_route.segment_end_coordinates.front().source_phantom.location, - reply.content); - - for (const std::vector &path_data_vector : raw_route.unpacked_path_segments) - { - for (const PathData &path_data : path_data_vector) - { - const FixedPointCoordinate current_coordinate = - facade->GetCoordinateOfNode(path_data.node); - AddRoutePoint(current_coordinate, reply.content); - } - } - AddRoutePoint(raw_route.segment_end_coordinates.back().target_phantom.location, - reply.content); - } - std::string footer(""); - reply.content.insert(reply.content.end(), footer.begin(), footer.end()); - } -}; -#endif // GPX_DESCRIPTOR_H diff --git a/3party/osrm/osrm-backend/Docs/webclient.txt b/3party/osrm/osrm-backend/Docs/webclient.txt deleted file mode 100644 index 55fcd15b8e..0000000000 --- a/3party/osrm/osrm-backend/Docs/webclient.txt +++ /dev/null @@ -1,3 +0,0 @@ -The javascript based web client is a seperate project available at - -https://github.com/DennisSchiefer/Project-OSRM-Web \ No newline at end of file diff --git a/3party/osrm/osrm-backend/Extractor/BaseParser.cpp b/3party/osrm/osrm-backend/Extractor/BaseParser.cpp deleted file mode 100644 index 20c864556b..0000000000 --- a/3party/osrm/osrm-backend/Extractor/BaseParser.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "BaseParser.h" -#include "ExtractionWay.h" -#include "ScriptingEnvironment.h" - -#include "../DataStructures/ImportNode.h" -#include "../Util/LuaUtil.h" -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" - -#include -#include -#include -#include - -BaseParser::BaseParser(ExtractorCallbacks *extractor_callbacks, - ScriptingEnvironment &scripting_environment) - : extractor_callbacks(extractor_callbacks), - lua_state(scripting_environment.getLuaState()), - scripting_environment(scripting_environment), use_turn_restrictions(true) -{ - ReadUseRestrictionsSetting(); - ReadRestrictionExceptions(); -} - -void BaseParser::ReadUseRestrictionsSetting() -{ - if (0 != luaL_dostring(lua_state, "return use_turn_restrictions\n")) - { - use_turn_restrictions = false; - } - else if (lua_isboolean(lua_state, -1)) - { - use_turn_restrictions = lua_toboolean(lua_state, -1); - } - - if (use_turn_restrictions) - { - SimpleLogger().Write() << "Using turn restrictions"; - } - else - { - SimpleLogger().Write() << "Ignoring turn restrictions"; - } -} - -void BaseParser::ReadRestrictionExceptions() -{ - if (lua_function_exists(lua_state, "get_exceptions")) - { - // get list of turn restriction exceptions - luabind::call_function( - lua_state, "get_exceptions", boost::ref(restriction_exceptions)); - const unsigned exception_count = restriction_exceptions.size(); - SimpleLogger().Write() << "Found " << exception_count - << " exceptions to turn restrictions:"; - for (const std::string &str : restriction_exceptions) - { - SimpleLogger().Write() << " " << str; - } - } - else - { - SimpleLogger().Write() << "Found no exceptions to turn restrictions"; - } -} - -void BaseParser::report_errors(lua_State *lua_state, const int status) const -{ - if (0 != status) - { - std::cerr << "-- " << lua_tostring(lua_state, -1) << std::endl; - lua_pop(lua_state, 1); // remove error message - } -} - -void BaseParser::ParseNodeInLua(ImportNode &node, lua_State *local_lua_state) -{ - luabind::call_function(local_lua_state, "node_function", boost::ref(node)); -} - -void BaseParser::ParseWayInLua(ExtractionWay &way, lua_State *local_lua_state) -{ - luabind::call_function(local_lua_state, "way_function", boost::ref(way)); -} - -bool BaseParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const -{ - // should this restriction be ignored? yes if there's an overlap between: - // a) the list of modes in the except tag of the restriction - // (except_tag_string), eg: except=bus;bicycle - // b) the lua profile defines a hierachy of modes, - // eg: [access, vehicle, bicycle] - - if (except_tag_string.empty()) - { - return false; - } - - // Be warned, this is quadratic work here, but we assume that - // only a few exceptions are actually defined. - std::vector exceptions; - boost::algorithm::split_regex(exceptions, except_tag_string, boost::regex("[;][ ]*")); - for (std::string ¤t_string : exceptions) - { - const auto string_iterator = - std::find(restriction_exceptions.begin(), restriction_exceptions.end(), current_string); - if (restriction_exceptions.end() != string_iterator) - { - return true; - } - } - return false; -} diff --git a/3party/osrm/osrm-backend/Extractor/BaseParser.h b/3party/osrm/osrm-backend/Extractor/BaseParser.h deleted file mode 100644 index b18da34311..0000000000 --- a/3party/osrm/osrm-backend/Extractor/BaseParser.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef BASEPARSER_H_ -#define BASEPARSER_H_ - -#include -#include - -struct lua_State; -class ExtractorCallbacks; -class ScriptingEnvironment; -struct ExtractionWay; -struct ImportNode; - -class BaseParser -{ - public: - BaseParser() = delete; - BaseParser(const BaseParser &) = delete; - BaseParser(ExtractorCallbacks *extractor_callbacks, - ScriptingEnvironment &scripting_environment); - virtual ~BaseParser() {} - virtual bool ReadHeader() = 0; - virtual bool Parse() = 0; - - virtual void ParseNodeInLua(ImportNode &node, lua_State *lua_state); - virtual void ParseWayInLua(ExtractionWay &way, lua_State *lua_state); - virtual void report_errors(lua_State *lua_state, const int status) const; - - protected: - virtual void ReadUseRestrictionsSetting(); - virtual void ReadRestrictionExceptions(); - virtual bool ShouldIgnoreRestriction(const std::string &except_tag_string) const; - - ExtractorCallbacks *extractor_callbacks; - lua_State *lua_state; - ScriptingEnvironment &scripting_environment; - std::vector restriction_exceptions; - bool use_turn_restrictions; -}; - -#endif /* BASEPARSER_H_ */ diff --git a/3party/osrm/osrm-backend/Extractor/ExtractionHelperFunctions.h b/3party/osrm/osrm-backend/Extractor/ExtractionHelperFunctions.h deleted file mode 100644 index b053338fd0..0000000000 --- a/3party/osrm/osrm-backend/Extractor/ExtractionHelperFunctions.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef EXTRACTION_HELPER_FUNCTIONS_H -#define EXTRACTION_HELPER_FUNCTIONS_H - -#include "../Util/cast.hpp" - -#include -#include -#include -#include - -#include - -namespace qi = boost::spirit::qi; - -// TODO: Move into LUA - -inline bool durationIsValid(const std::string &s) -{ - boost::regex e( - "((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)", - boost::regex_constants::icase | boost::regex_constants::perl); - - std::vector result; - boost::algorithm::split_regex(result, s, boost::regex(":")); - const bool matched = regex_match(s, e); - return matched; -} - -inline unsigned parseDuration(const std::string &s) -{ - unsigned hours = 0; - unsigned minutes = 0; - unsigned seconds = 0; - boost::regex e( - "((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)", - boost::regex_constants::icase | boost::regex_constants::perl); - - std::vector result; - boost::algorithm::split_regex(result, s, boost::regex(":")); - const bool matched = regex_match(s, e); - if (matched) - { - if (1 == result.size()) - { - minutes = cast::string_to_int(result[0]); - } - if (2 == result.size()) - { - minutes = cast::string_to_int(result[1]); - hours = cast::string_to_int(result[0]); - } - if (3 == result.size()) - { - seconds = cast::string_to_int(result[2]); - minutes = cast::string_to_int(result[1]); - hours = cast::string_to_int(result[0]); - } - return 10 * (3600 * hours + 60 * minutes + seconds); - } - return std::numeric_limits::max(); -} - -#endif // EXTRACTION_HELPER_FUNCTIONS_H_ diff --git a/3party/osrm/osrm-backend/Extractor/Extractor.cpp b/3party/osrm/osrm-backend/Extractor/Extractor.cpp deleted file mode 100644 index c9c870bf15..0000000000 --- a/3party/osrm/osrm-backend/Extractor/Extractor.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "Extractor.h" - -#include "ExtractorCallbacks.h" -#include "ExtractionContainers.h" -#include "PBFParser.h" -#include "ScriptingEnvironment.h" -#include "XMLParser.h" - -#include "../Util/GitDescription.h" -#include "../Util/IniFileUtil.h" -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" -#include "../Util/TimingUtil.h" -#include "../typedefs.h" - -#include - -#include - -#include - -#include -#include -#include -#include -#include - -Extractor::Extractor() : requested_num_threads(0), file_has_pbf_format(false) -{ -} - -Extractor::~Extractor() {} - -bool Extractor::ParseArguments(int argc, char *argv[]) -{ - // 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", - boost::program_options::value(&config_file_path) - ->default_value("extractor.ini"), - "Path to a configuration file."); - - // declare a group of options that will be allowed both on command line and in config file - boost::program_options::options_description config_options("Configuration"); - config_options.add_options()("profile,p", - boost::program_options::value( - &profile_path)->default_value("profile.lua"), - "Path to LUA routing profile")( - "threads,t", - boost::program_options::value(&requested_num_threads) - ->default_value(tbb::task_scheduler_init::default_num_threads()), - "Number of threads to use"); - - // hidden options, will be allowed both on command line and in config file, but will not be - // shown to the user - std::string string_input_path; - boost::program_options::options_description hidden_options("Hidden options"); - hidden_options.add_options()( - "input,i", - boost::program_options::value(&string_input_path), - "Input file in .osm, .osm.bz2 or .osm.pbf format"); - - // positional option - boost::program_options::positional_options_description positional_options; - positional_options.add("input", 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 config_file_options; - config_file_options.add(config_options).add(hidden_options); - - boost::program_options::options_description visible_options( - boost::filesystem::basename(argv[0]) + " [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() << g_GIT_DESCRIPTION; - return false; - } - - if (option_variables.count("help")) - { - SimpleLogger().Write() << visible_options; - return false; - } - - boost::program_options::notify(option_variables); - - // parse config file - if (boost::filesystem::is_regular_file(config_file_path)) - { - SimpleLogger().Write() << "Reading options from: " << config_file_path.string(); - std::string ini_file_contents = ReadIniFileAndLowerContents(config_file_path); - std::stringstream config_stream(ini_file_contents); - boost::program_options::store(parse_config_file(config_stream, config_file_options), - option_variables); - boost::program_options::notify(option_variables); - } - - if (!option_variables.count("input")) - { - SimpleLogger().Write() << visible_options; - return false; - } - - input_path = boost::filesystem::path(string_input_path); - - return true; -} - -void Extractor::GenerateOutputFilesNames() -{ - output_file_name = input_path.string(); - restriction_file_name = input_path.string(); - std::string::size_type pos = output_file_name.find(".osm.bz2"); - if (pos == std::string::npos) - { - pos = output_file_name.find(".osm.pbf"); - if (pos != std::string::npos) - { - file_has_pbf_format = true; - } - else - { - pos = output_file_name.find(".osm.xml"); - } - } - if (pos == std::string::npos) - { - pos = output_file_name.find(".pbf"); - if (pos != std::string::npos) - { - file_has_pbf_format = true; - } - } - if (pos == std::string::npos) - { - pos = output_file_name.find(".osm"); - if (pos == std::string::npos) - { - output_file_name.append(".osrm"); - restriction_file_name.append(".osrm.restrictions"); - } - else - { - output_file_name.replace(pos, 5, ".osrm"); - restriction_file_name.replace(pos, 5, ".osrm.restrictions"); - } - } - else - { - output_file_name.replace(pos, 8, ".osrm"); - restriction_file_name.replace(pos, 8, ".osrm.restrictions"); - } -} - -int Extractor::Run(int argc, char *argv[]) -{ - try - { - LogPolicy::GetInstance().Unmute(); - - TIMER_START(extracting); - - if (!ParseArguments(argc, argv)) - return 0; - - if (1 > requested_num_threads) - { - SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger"; - return 1; - } - - if (!boost::filesystem::is_regular_file(input_path)) - { - SimpleLogger().Write(logWARNING) << "Input file " << input_path.string() - << " not found!"; - return 1; - } - - if (!boost::filesystem::is_regular_file(profile_path)) - { - SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string() - << " not found!"; - return 1; - } - - const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads(); - - SimpleLogger().Write() << "Input file: " << input_path.filename().string(); - SimpleLogger().Write() << "Profile: " << profile_path.filename().string(); - SimpleLogger().Write() << "Threads: " << requested_num_threads; - if (recommended_num_threads != requested_num_threads) - { - SimpleLogger().Write(logWARNING) << "The recommended number of threads is " - << recommended_num_threads - << "! This setting may have performance side-effects."; - } - - tbb::task_scheduler_init init(requested_num_threads); - - /*** Setup Scripting Environment ***/ - ScriptingEnvironment scripting_environment(profile_path.string().c_str()); - - GenerateOutputFilesNames(); - - std::unordered_map string_map; - ExtractionContainers extraction_containers; - - string_map[""] = 0; - auto extractor_callbacks = new ExtractorCallbacks(extraction_containers, string_map); - BaseParser *parser; - if (file_has_pbf_format) - { - parser = new PBFParser(input_path.string().c_str(), - extractor_callbacks, - scripting_environment, - requested_num_threads); - } - else - { - parser = new XMLParser(input_path.string().c_str(), - extractor_callbacks, - scripting_environment); - } - - if (!parser->ReadHeader()) - { - throw OSRMException("Parser not initialized!"); - } - - SimpleLogger().Write() << "Parsing in progress.."; - TIMER_START(parsing); - - parser->Parse(); - delete parser; - delete extractor_callbacks; - - TIMER_STOP(parsing); - SimpleLogger().Write() << "Parsing finished after " << TIMER_SEC(parsing) << " seconds"; - - if (extraction_containers.all_edges_list.empty()) - { - SimpleLogger().Write(logWARNING) << "The input data is empty, exiting."; - return 1; - } - - extraction_containers.PrepareData(output_file_name, restriction_file_name); - - TIMER_STOP(extracting); - SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting) << "s"; - SimpleLogger().Write() << "To prepare the data for routing, run: " - << "./osrm-prepare " << output_file_name << std::endl; - } - catch (boost::program_options::too_many_positional_options_error &) - { - SimpleLogger().Write(logWARNING) << "Only one input file can be specified"; - return 1; - } - catch (std::exception &e) - { - SimpleLogger().Write(logWARNING) << e.what(); - return 1; - } - return 0; -} diff --git a/3party/osrm/osrm-backend/Extractor/Extractor.h b/3party/osrm/osrm-backend/Extractor/Extractor.h deleted file mode 100644 index 70c943a06a..0000000000 --- a/3party/osrm/osrm-backend/Extractor/Extractor.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef EXTRACTOR_H_ -#define EXTRACTOR_H_ - -#include - -#include - -class ExtractorCallbacks; - -/** \brief Class of 'extract' utility. */ -class Extractor -{ - protected: - unsigned requested_num_threads; - boost::filesystem::path config_file_path; - boost::filesystem::path input_path; - boost::filesystem::path profile_path; - - std::string output_file_name; - std::string restriction_file_name; - bool file_has_pbf_format; - - /** \brief Parses "extractor's" command line arguments */ - bool ParseArguments(int argc, char *argv[]); - - /** \brief Parses config file, if present in options */ - void GenerateOutputFilesNames(); - - public: - explicit Extractor(); - Extractor(const Extractor &) = delete; - virtual ~Extractor(); - - int Run(int argc, char *argv[]); -}; -#endif /* EXTRACTOR_H_ */ diff --git a/3party/osrm/osrm-backend/Extractor/ExtractorCallbacks.cpp b/3party/osrm/osrm-backend/Extractor/ExtractorCallbacks.cpp deleted file mode 100644 index d607d41da0..0000000000 --- a/3party/osrm/osrm-backend/Extractor/ExtractorCallbacks.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "ExtractorCallbacks.h" -#include "ExtractionContainers.h" -#include "ExtractionWay.h" - -#include "../DataStructures/Restriction.h" -#include "../DataStructures/ImportNode.h" -#include "../Util/simple_logger.hpp" - -#include - -#include -#include -#include - -ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers, - std::unordered_map &string_map) - : string_map(string_map), external_memory(extraction_containers) -{ -} - -/** warning: caller needs to take care of synchronization! */ -void ExtractorCallbacks::ProcessNode(const ExternalMemoryNode &n) -{ - if (n.lat <= 85 * COORDINATE_PRECISION && n.lat >= -85 * COORDINATE_PRECISION) - { - external_memory.all_nodes_list.push_back(n); - } -} - -bool ExtractorCallbacks::ProcessRestriction(const InputRestrictionContainer &restriction) -{ - external_memory.restrictions_list.push_back(restriction); - return true; -} - -/** warning: caller needs to take care of synchronization! */ -void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way) -{ - if (((0 >= parsed_way.forward_speed) || - (TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)) && - ((0 >= parsed_way.backward_speed) || - (TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode)) && - (0 >= parsed_way.duration)) - { // Only true if the way is specified by the speed profile - return; - } - - if (parsed_way.path.size() <= 1) - { // safe-guard against broken data - return; - } - - if (std::numeric_limits::max() == parsed_way.id) - { - SimpleLogger().Write(logDEBUG) << "found bogus way with id: " << parsed_way.id - << " of size " << parsed_way.path.size(); - return; - } - - if (0 < parsed_way.duration) - { - // TODO: iterate all way segments and set duration corresponding to the length of each - // segment - parsed_way.forward_speed = parsed_way.duration / (parsed_way.path.size() - 1); - parsed_way.backward_speed = parsed_way.duration / (parsed_way.path.size() - 1); - } - - if (std::numeric_limits::epsilon() >= std::abs(-1. - parsed_way.forward_speed)) - { - SimpleLogger().Write(logDEBUG) << "found way with bogus speed, id: " << parsed_way.id; - return; - } - - // Get the unique identifier for the street name - const auto &string_map_iterator = string_map.find(parsed_way.name); - if (string_map.end() == string_map_iterator) - { - parsed_way.nameID = external_memory.name_list.size(); - external_memory.name_list.push_back(parsed_way.name); - string_map.insert(std::make_pair(parsed_way.name, parsed_way.nameID)); - } - else - { - parsed_way.nameID = string_map_iterator->second; - } - - if (TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode) - { - std::reverse(parsed_way.path.begin(), parsed_way.path.end()); - parsed_way.forward_travel_mode = parsed_way.backward_travel_mode; - parsed_way.backward_travel_mode = TRAVEL_MODE_INACCESSIBLE; - } - - const bool split_edge = - (parsed_way.forward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.forward_travel_mode) && - (parsed_way.backward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.backward_travel_mode) && - ((parsed_way.forward_speed != parsed_way.backward_speed) || - (parsed_way.forward_travel_mode != parsed_way.backward_travel_mode)); - - BOOST_ASSERT(parsed_way.forward_travel_mode>0); - 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 - : ExtractionWay::bidirectional), - parsed_way.forward_speed, - parsed_way.nameID, - parsed_way.roundabout, - parsed_way.ignoreInGrid, - (0 < parsed_way.duration), - parsed_way.isAccessRestricted, - parsed_way.forward_travel_mode, - split_edge)); - external_memory.used_node_id_list.push_back(parsed_way.path[n]); - } - external_memory.used_node_id_list.push_back(parsed_way.path.back()); - - // The following information is needed to identify start and end segments of restrictions - external_memory.way_start_end_id_list.push_back( - WayIDStartAndEndEdge(parsed_way.id, - parsed_way.path[0], - parsed_way.path[1], - parsed_way.path[parsed_way.path.size() - 2], - parsed_way.path.back())); - - if (split_edge) - { // Only true if the way should be split - BOOST_ASSERT(parsed_way.backward_travel_mode>0); - std::reverse(parsed_way.path.begin(), parsed_way.path.end()); - - for (std::vector::size_type 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], - ExtractionWay::oneway, - parsed_way.backward_speed, - parsed_way.nameID, - parsed_way.roundabout, - parsed_way.ignoreInGrid, - (0 < parsed_way.duration), - parsed_way.isAccessRestricted, - parsed_way.backward_travel_mode, - split_edge)); - } - external_memory.way_start_end_id_list.push_back( - WayIDStartAndEndEdge(parsed_way.id, - parsed_way.path[0], - parsed_way.path[1], - parsed_way.path[parsed_way.path.size() - 2], - parsed_way.path.back())); - } -} diff --git a/3party/osrm/osrm-backend/Extractor/ExtractorStructs.h b/3party/osrm/osrm-backend/Extractor/ExtractorStructs.h deleted file mode 100644 index a3c6f3eaf5..0000000000 --- a/3party/osrm/osrm-backend/Extractor/ExtractorStructs.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef EXTRACTORSTRUCTS_H_ -#define EXTRACTORSTRUCTS_H_ - -#include "../DataStructures/HashTable.h" -#include "../DataStructures/ImportNode.h" -#include "../typedefs.h" - -#include -#include - -struct ExtractorRelation -{ - ExtractorRelation() : type(unknown) {} - enum - { unknown = 0, - ferry, - turnRestriction } type; - HashTable keyVals; -}; - -struct WayIDStartAndEndEdge -{ - unsigned wayID; - NodeID firstStart; - NodeID firstTarget; - NodeID lastStart; - NodeID lastTarget; - WayIDStartAndEndEdge() - : wayID(std::numeric_limits::max()), firstStart(std::numeric_limits::max()), firstTarget(std::numeric_limits::max()), lastStart(std::numeric_limits::max()), - lastTarget(std::numeric_limits::max()) - { - } - - explicit WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt) - : wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt) - { - } - - static WayIDStartAndEndEdge min_value() - { - return WayIDStartAndEndEdge((std::numeric_limits::min)(), - (std::numeric_limits::min)(), - (std::numeric_limits::min)(), - (std::numeric_limits::min)(), - (std::numeric_limits::min)()); - } - static WayIDStartAndEndEdge max_value() - { - return WayIDStartAndEndEdge((std::numeric_limits::max)(), - (std::numeric_limits::max)(), - (std::numeric_limits::max)(), - (std::numeric_limits::max)(), - (std::numeric_limits::max)()); - } -}; - -struct CmpWayByID -{ - using value_type = WayIDStartAndEndEdge; - bool operator()(const WayIDStartAndEndEdge &a, const WayIDStartAndEndEdge &b) const - { - return a.wayID < b.wayID; - } - value_type max_value() { return WayIDStartAndEndEdge::max_value(); } - value_type min_value() { return WayIDStartAndEndEdge::min_value(); } -}; - -struct Cmp -{ - using value_type = NodeID; - bool operator()(const NodeID left, const NodeID right) const { return left < right; } - value_type max_value() { return 0xffffffff; } - value_type min_value() { return 0x0; } -}; - -struct CmpNodeByID -{ - using value_type = ExternalMemoryNode; - bool operator()(const ExternalMemoryNode &left, const ExternalMemoryNode &right) const - { - return left.node_id < right.node_id; - } - value_type max_value() { return ExternalMemoryNode::max_value(); } - value_type min_value() { return ExternalMemoryNode::min_value(); } -}; - -#endif /* EXTRACTORSTRUCTS_H_ */ diff --git a/3party/osrm/osrm-backend/Extractor/PBFParser.cpp b/3party/osrm/osrm-backend/Extractor/PBFParser.cpp deleted file mode 100644 index fd489533f1..0000000000 --- a/3party/osrm/osrm-backend/Extractor/PBFParser.cpp +++ /dev/null @@ -1,665 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "PBFParser.h" - -#include "ExtractionWay.h" -#include "ExtractorCallbacks.h" -#include "ScriptingEnvironment.h" - -#include "../DataStructures/HashTable.h" -#include "../DataStructures/ImportNode.h" -#include "../DataStructures/Restriction.h" -#include "../Util/MachineInfo.h" -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" -#include "../typedefs.h" - -#include - -#include -#include - -#include - -#include - -#include -#include -#include -#include - -PBFParser::PBFParser(const char *fileName, - ExtractorCallbacks *extractor_callbacks, - ScriptingEnvironment &scripting_environment, - unsigned num_threads) - : BaseParser(extractor_callbacks, scripting_environment) -{ - if (0 == num_threads) - { - num_parser_threads = tbb::task_scheduler_init::default_num_threads(); - } - else - { - num_parser_threads = num_threads; - } - - GOOGLE_PROTOBUF_VERIFY_VERSION; - // TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk? - // NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free. - - // Max 2500 items in queue, hardcoded. - thread_data_queue = std::make_shared>(2500); - input.open(fileName, std::ios::in | std::ios::binary); - - if (!input) - { - throw OSRMException("pbf file not found."); - } - - block_count = 0; - group_count = 0; -} - -PBFParser::~PBFParser() -{ - if (input.is_open()) - { - input.close(); - } - - // Clean up any leftover ThreadData objects in the queue - ParserThreadData *thread_data; - while (thread_data_queue->try_pop(thread_data)) - { - delete thread_data; - } - google::protobuf::ShutdownProtobufLibrary(); - - SimpleLogger().Write(logDEBUG) << "parsed " << block_count << " blocks from pbf with " - << group_count << " groups"; -} - -inline bool PBFParser::ReadHeader() -{ - ParserThreadData init_data; - /** read Header */ - if (!readPBFBlobHeader(input, &init_data)) - { - return false; - } - - if (readBlob(input, &init_data)) - { - if (!init_data.PBFHeaderBlock.ParseFromArray(&(init_data.charBuffer[0]), - static_cast(init_data.charBuffer.size()))) - { - std::cerr << "[error] Header not parseable!" << std::endl; - return false; - } - - const auto feature_size = init_data.PBFHeaderBlock.required_features_size(); - for (int i = 0; i < feature_size; ++i) - { - const std::string &feature = init_data.PBFHeaderBlock.required_features(i); - bool supported = false; - if ("OsmSchema-V0.6" == feature) - { - supported = true; - } - else if ("DenseNodes" == feature) - { - supported = true; - } - - if (!supported) - { - std::cerr << "[error] required feature not supported: " << feature.data() - << std::endl; - return false; - } - } - } - else - { - std::cerr << "[error] blob not loaded!" << std::endl; - } - return true; -} - -inline void PBFParser::ReadData() -{ - bool keep_running = true; - do - { - ParserThreadData *thread_data = new ParserThreadData(); - keep_running = readNextBlock(input, thread_data); - - if (keep_running) - { - thread_data_queue->push(thread_data); - } - else - { - // No more data to read, parse stops when nullptr encountered - thread_data_queue->push(nullptr); - delete thread_data; - } - } while (keep_running); -} - -inline void PBFParser::ParseData() -{ - tbb::task_scheduler_init init(num_parser_threads); - - while (true) - { - ParserThreadData *thread_data; - thread_data_queue->wait_and_pop(thread_data); - if (nullptr == thread_data) - { - thread_data_queue->push(nullptr); // Signal end of data for other threads - break; - } - - loadBlock(thread_data); - - int group_size = thread_data->PBFprimitiveBlock.primitivegroup_size(); - for (int i = 0; i < group_size; ++i) - { - thread_data->currentGroupID = i; - loadGroup(thread_data); - - if (thread_data->entityTypeIndicator == TypeNode) - { - parseNode(thread_data); - } - if (thread_data->entityTypeIndicator == TypeWay) - { - parseWay(thread_data); - } - if (thread_data->entityTypeIndicator == TypeRelation) - { - parseRelation(thread_data); - } - if (thread_data->entityTypeIndicator == TypeDenseNode) - { - parseDenseNode(thread_data); - } - } - - delete thread_data; - thread_data = nullptr; - } -} - -inline bool PBFParser::Parse() -{ - // Start the read and parse threads - std::thread read_thread(std::bind(&PBFParser::ReadData, this)); - - // Open several parse threads that are synchronized before call to - std::thread parse_thread(std::bind(&PBFParser::ParseData, this)); - - // Wait for the threads to finish - read_thread.join(); - parse_thread.join(); - - return true; -} - -inline void PBFParser::parseDenseNode(ParserThreadData *thread_data) -{ - const OSMPBF::DenseNodes &dense = - thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).dense(); - int denseTagIndex = 0; - int64_t m_lastDenseID = 0; - int64_t m_lastDenseLatitude = 0; - int64_t m_lastDenseLongitude = 0; - - const int number_of_nodes = dense.id_size(); - std::vector extracted_nodes_vector(number_of_nodes); - for (int i = 0; i < number_of_nodes; ++i) - { - m_lastDenseID += dense.id(i); - m_lastDenseLatitude += dense.lat(i); - m_lastDenseLongitude += dense.lon(i); - extracted_nodes_vector[i].node_id = static_cast(m_lastDenseID); - extracted_nodes_vector[i].lat = static_cast( - COORDINATE_PRECISION * - ((double)m_lastDenseLatitude * thread_data->PBFprimitiveBlock.granularity() + - thread_data->PBFprimitiveBlock.lat_offset()) / - NANO); - extracted_nodes_vector[i].lon = static_cast( - COORDINATE_PRECISION * - ((double)m_lastDenseLongitude * thread_data->PBFprimitiveBlock.granularity() + - thread_data->PBFprimitiveBlock.lon_offset()) / - NANO); - while (denseTagIndex < dense.keys_vals_size()) - { - const int tagValue = dense.keys_vals(denseTagIndex); - if (0 == tagValue) - { - ++denseTagIndex; - break; - } - const int keyValue = dense.keys_vals(denseTagIndex + 1); - const std::string &key = thread_data->PBFprimitiveBlock.stringtable().s(tagValue); - const std::string &value = thread_data->PBFprimitiveBlock.stringtable().s(keyValue); - extracted_nodes_vector[i].keyVals.Add(std::move(key), std::move(value)); - denseTagIndex += 2; - } - } - - tbb::parallel_for(tbb::blocked_range(0, extracted_nodes_vector.size()), - [this, &extracted_nodes_vector](const tbb::blocked_range &range) - { - lua_State *lua_state = this->scripting_environment.getLuaState(); - for (size_t i = range.begin(); i != range.end(); ++i) - { - ImportNode &import_node = extracted_nodes_vector[i]; - ParseNodeInLua(import_node, lua_state); - } - }); - - for (const ImportNode &import_node : extracted_nodes_vector) - { - extractor_callbacks->ProcessNode(import_node); - } -} - -inline void PBFParser::parseNode(ParserThreadData *) -{ - throw OSRMException("Parsing of simple nodes not supported. PBF should use dense nodes"); -} - -inline void PBFParser::parseRelation(ParserThreadData *thread_data) -{ - // TODO: leave early, if relation is not a restriction - // TODO: reuse rawRestriction container - if (!use_turn_restrictions) - { - return; - } - const OSMPBF::PrimitiveGroup &group = - thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID); - - for (int i = 0, relation_size = group.relations_size(); i < relation_size; ++i) - { - std::string except_tag_string; - const OSMPBF::Relation &inputRelation = - thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).relations(i); - bool is_restriction = false; - bool is_only_restriction = false; - for (int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k) - { - const std::string &key = - thread_data->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k)); - const std::string &val = - thread_data->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k)); - if ("type" == key) - { - if ("restriction" == val) - { - is_restriction = true; - } - else - { - break; - } - } - if (("restriction" == key) && (val.find("only_") == 0)) - { - is_only_restriction = true; - } - if ("except" == key) - { - except_tag_string = val; - } - } - - if (is_restriction && ShouldIgnoreRestriction(except_tag_string)) - { - continue; - } - - if (is_restriction) - { - int64_t last_ref = 0; - InputRestrictionContainer current_restriction_container(is_only_restriction); - for (int rolesIndex = 0, last_role = inputRelation.roles_sid_size(); - rolesIndex < last_role; - ++rolesIndex) - { - const std::string &role = thread_data->PBFprimitiveBlock.stringtable().s( - inputRelation.roles_sid(rolesIndex)); - last_ref += inputRelation.memids(rolesIndex); - - if (!("from" == role || "to" == role || "via" == role)) - { - continue; - } - - switch (inputRelation.types(rolesIndex)) - { - case 0: // node - if ("from" == role || "to" == role) - { // Only via should be a node - continue; - } - BOOST_ASSERT("via" == role); - if (std::numeric_limits::max() != - current_restriction_container.viaNode) - { - current_restriction_container.viaNode = - std::numeric_limits::max(); - } - BOOST_ASSERT(std::numeric_limits::max() == - current_restriction_container.viaNode); - current_restriction_container.restriction.viaNode = - static_cast(last_ref); - break; - case 1: // way - BOOST_ASSERT("from" == role || "to" == role || "via" == role); - if ("from" == role) - { - current_restriction_container.fromWay = static_cast(last_ref); - } - if ("to" == role) - { - current_restriction_container.toWay = static_cast(last_ref); - } - if ("via" == role) - { - BOOST_ASSERT(current_restriction_container.restriction.toNode == - std::numeric_limits::max()); - current_restriction_container.viaNode = static_cast(last_ref); - } - break; - case 2: // relation, not used. relations relating to relations are evil. - continue; - BOOST_ASSERT(false); - break; - - default: // should not happen - BOOST_ASSERT(false); - break; - } - } - if (!extractor_callbacks->ProcessRestriction(current_restriction_container)) - { - std::cerr << "[PBFParser] relation not parsed" << std::endl; - } - } - } -} - -inline void PBFParser::parseWay(ParserThreadData *thread_data) -{ - const int number_of_ways = - thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).ways_size(); - std::vector parsed_way_vector(number_of_ways); - for (int i = 0; i < number_of_ways; ++i) - { - const OSMPBF::Way &input_way = - thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).ways(i); - parsed_way_vector[i].id = static_cast(input_way.id()); - unsigned node_id_in_path = 0; - const auto number_of_referenced_nodes = input_way.refs_size(); - for (auto j = 0; j < number_of_referenced_nodes; ++j) - { - node_id_in_path += static_cast(input_way.refs(j)); - parsed_way_vector[i].path.push_back(node_id_in_path); - } - BOOST_ASSERT(input_way.keys_size() == input_way.vals_size()); - const auto number_of_keys = input_way.keys_size(); - for (auto j = 0; j < number_of_keys; ++j) - { - const std::string &key = - thread_data->PBFprimitiveBlock.stringtable().s(input_way.keys(j)); - const std::string &val = - thread_data->PBFprimitiveBlock.stringtable().s(input_way.vals(j)); - parsed_way_vector[i].keyVals.Add(std::move(key), std::move(val)); - } - } - - // TODO: investigate if schedule guided will be handled by tbb automatically - tbb::parallel_for(tbb::blocked_range(0, parsed_way_vector.size()), - [this, &parsed_way_vector](const tbb::blocked_range &range) - { - lua_State *lua_state = this->scripting_environment.getLuaState(); - for (size_t i = range.begin(); i != range.end(); i++) - { - ExtractionWay &extraction_way = parsed_way_vector[i]; - if (2 <= extraction_way.path.size()) - { - ParseWayInLua(extraction_way, lua_state); - } - } - }); - - for (ExtractionWay &extraction_way : parsed_way_vector) - { - if (2 <= extraction_way.path.size()) - { - extractor_callbacks->ProcessWay(extraction_way); - } - } -} - -inline void PBFParser::loadGroup(ParserThreadData *thread_data) -{ -#ifndef NDEBUG - ++group_count; -#endif - - const OSMPBF::PrimitiveGroup &group = - thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID); - thread_data->entityTypeIndicator = TypeDummy; - if (0 != group.nodes_size()) - { - thread_data->entityTypeIndicator = TypeNode; - } - if (0 != group.ways_size()) - { - thread_data->entityTypeIndicator = TypeWay; - } - if (0 != group.relations_size()) - { - thread_data->entityTypeIndicator = TypeRelation; - } - if (group.has_dense()) - { - thread_data->entityTypeIndicator = TypeDenseNode; - BOOST_ASSERT(0 != group.dense().id_size()); - } - BOOST_ASSERT(thread_data->entityTypeIndicator != TypeDummy); -} - -inline void PBFParser::loadBlock(ParserThreadData *thread_data) -{ - ++block_count; - thread_data->currentGroupID = 0; - thread_data->currentEntityID = 0; -} - -inline bool PBFParser::readPBFBlobHeader(std::fstream &stream, ParserThreadData *thread_data) -{ - int size(0); - stream.read((char *)&size, sizeof(int)); - size = SwapEndian(size); - if (stream.eof()) - { - return false; - } - if (size > MAX_BLOB_HEADER_SIZE || size < 0) - { - return false; - } - char *data = new char[size]; - stream.read(data, size * sizeof(data[0])); - - bool dataSuccessfullyParsed = (thread_data->PBFBlobHeader).ParseFromArray(data, size); - delete[] data; - return dataSuccessfullyParsed; -} - -inline bool PBFParser::unpackZLIB(ParserThreadData *thread_data) -{ - auto raw_size = thread_data->PBFBlob.raw_size(); - char *unpacked_data_array = new char[raw_size]; - z_stream compressed_data_stream; - compressed_data_stream.next_in = (unsigned char *)thread_data->PBFBlob.zlib_data().data(); - compressed_data_stream.avail_in = thread_data->PBFBlob.zlib_data().size(); - compressed_data_stream.next_out = (unsigned char *)unpacked_data_array; - compressed_data_stream.avail_out = raw_size; - compressed_data_stream.zalloc = Z_NULL; - compressed_data_stream.zfree = Z_NULL; - compressed_data_stream.opaque = Z_NULL; - int return_code = inflateInit(&compressed_data_stream); - if (return_code != Z_OK) - { - std::cerr << "[error] failed to init zlib stream" << std::endl; - delete[] unpacked_data_array; - return false; - } - - return_code = inflate(&compressed_data_stream, Z_FINISH); - if (return_code != Z_STREAM_END) - { - std::cerr << "[error] failed to inflate zlib stream" << std::endl; - std::cerr << "[error] Error type: " << return_code << std::endl; - delete[] unpacked_data_array; - return false; - } - - return_code = inflateEnd(&compressed_data_stream); - if (return_code != Z_OK) - { - std::cerr << "[error] failed to deinit zlib stream" << std::endl; - delete[] unpacked_data_array; - return false; - } - - thread_data->charBuffer.clear(); - thread_data->charBuffer.resize(raw_size); - std::copy(unpacked_data_array, unpacked_data_array + raw_size, thread_data->charBuffer.begin()); - delete[] unpacked_data_array; - return true; -} - -inline bool PBFParser::unpackLZMA(ParserThreadData *) { return false; } - -inline bool PBFParser::readBlob(std::fstream &stream, ParserThreadData *thread_data) -{ - if (stream.eof()) - { - return false; - } - - const int size = thread_data->PBFBlobHeader.datasize(); - if (size < 0 || size > MAX_BLOB_SIZE) - { - std::cerr << "[error] invalid Blob size:" << size << std::endl; - return false; - } - - char *data = new char[size]; - stream.read(data, sizeof(data[0]) * size); - - if (!thread_data->PBFBlob.ParseFromArray(data, size)) - { - std::cerr << "[error] failed to parse blob" << std::endl; - delete[] data; - return false; - } - - if (thread_data->PBFBlob.has_raw()) - { - const std::string &data = thread_data->PBFBlob.raw(); - thread_data->charBuffer.clear(); - thread_data->charBuffer.resize(data.size()); - std::copy(data.begin(), data.end(), thread_data->charBuffer.begin()); - } - else if (thread_data->PBFBlob.has_zlib_data()) - { - if (!unpackZLIB(thread_data)) - { - std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl; - delete[] data; - return false; - } - } - else if (thread_data->PBFBlob.has_lzma_data()) - { - if (!unpackLZMA(thread_data)) - { - std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl; - } - delete[] data; - return false; - } - else - { - std::cerr << "[error] Blob contains no data" << std::endl; - delete[] data; - return false; - } - delete[] data; - return true; -} - -bool PBFParser::readNextBlock(std::fstream &stream, ParserThreadData *thread_data) -{ - if (stream.eof()) - { - return false; - } - - if (!readPBFBlobHeader(stream, thread_data)) - { - return false; - } - - if (thread_data->PBFBlobHeader.type() != "OSMData") - { - return false; - } - - if (!readBlob(stream, thread_data)) - { - return false; - } - - if (!thread_data->PBFprimitiveBlock.ParseFromArray(&(thread_data->charBuffer[0]), - thread_data->charBuffer.size())) - { - std::cerr << "failed to parse PrimitiveBlock" << std::endl; - return false; - } - return true; -} diff --git a/3party/osrm/osrm-backend/Extractor/PBFParser.h b/3party/osrm/osrm-backend/Extractor/PBFParser.h deleted file mode 100644 index c65a29d406..0000000000 --- a/3party/osrm/osrm-backend/Extractor/PBFParser.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef PBFPARSER_H_ -#define PBFPARSER_H_ - -#include "BaseParser.h" -#include "../DataStructures/ConcurrentQueue.h" - -#include -#include - -#include -#include - -class PBFParser : public BaseParser -{ - - enum EntityType - { TypeDummy = 0, - TypeNode = 1, - TypeWay = 2, - TypeRelation = 4, - TypeDenseNode = 8 }; - - struct ParserThreadData - { - int currentGroupID; - int currentEntityID; - EntityType entityTypeIndicator; - - OSMPBF::BlobHeader PBFBlobHeader; - OSMPBF::Blob PBFBlob; - - OSMPBF::HeaderBlock PBFHeaderBlock; - OSMPBF::PrimitiveBlock PBFprimitiveBlock; - - std::vector charBuffer; - }; - - public: - PBFParser(const char *file_name, - ExtractorCallbacks *extractor_callbacks, - ScriptingEnvironment &scripting_environment, - unsigned num_parser_threads = 0); - virtual ~PBFParser(); - - inline bool ReadHeader(); - inline bool Parse(); - - private: - inline void ReadData(); - inline void ParseData(); - inline void parseDenseNode(ParserThreadData *thread_data); - inline void parseNode(ParserThreadData *thread_data); - inline void parseRelation(ParserThreadData *thread_data); - inline void parseWay(ParserThreadData *thread_data); - - inline void loadGroup(ParserThreadData *thread_data); - inline void loadBlock(ParserThreadData *thread_data); - inline bool readPBFBlobHeader(std::fstream &stream, ParserThreadData *thread_data); - inline bool unpackZLIB(ParserThreadData *thread_data); - inline bool unpackLZMA(ParserThreadData *thread_data); - inline bool readBlob(std::fstream &stream, ParserThreadData *thread_data); - inline bool readNextBlock(std::fstream &stream, ParserThreadData *thread_data); - - static const int NANO = 1000 * 1000 * 1000; - static const int MAX_BLOB_HEADER_SIZE = 64 * 1024; - static const int MAX_BLOB_SIZE = 32 * 1024 * 1024; - - unsigned group_count; - unsigned block_count; - - std::fstream input; // the input stream to parse - std::shared_ptr> thread_data_queue; - unsigned num_parser_threads; -}; - -#endif /* PBFPARSER_H_ */ diff --git a/3party/osrm/osrm-backend/Extractor/ScriptingEnvironment.cpp b/3party/osrm/osrm-backend/Extractor/ScriptingEnvironment.cpp deleted file mode 100644 index 3ecb0c4664..0000000000 --- a/3party/osrm/osrm-backend/Extractor/ScriptingEnvironment.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "ScriptingEnvironment.h" - -#include "ExtractionHelperFunctions.h" -#include "ExtractionWay.h" -#include "../DataStructures/ImportNode.h" -#include "../Util/LuaUtil.h" -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" -#include "../typedefs.h" - -#include - -ScriptingEnvironment::ScriptingEnvironment() {} -ScriptingEnvironment::ScriptingEnvironment(const char *file_name) -: file_name(file_name) -{ - SimpleLogger().Write() << "Using script " << file_name; -} - -void ScriptingEnvironment::initLuaState(lua_State* lua_state) -{ - luabind::open(lua_state); - // open utility libraries string library; - luaL_openlibs(lua_state); - - luaAddScriptFolderToLoadPath(lua_state, file_name.c_str()); - - // Add our function to the state's global scope - luabind::module(lua_state)[ - luabind::def("print", LUA_print), - luabind::def("durationIsValid", durationIsValid), - luabind::def("parseDuration", parseDuration), - - luabind::class_>("keyVals") - .def("Add", &HashTable::Add) - .def("Find", &HashTable::Find) - .def("Holds", &HashTable::Holds), - - luabind::class_("Node") - // .def(luabind::constructor<>()) - .def_readwrite("lat", &ImportNode::lat) - .def_readwrite("lon", &ImportNode::lon) - .def_readonly("id", &ImportNode::node_id) - .def_readwrite("bollard", &ImportNode::bollard) - .def_readwrite("traffic_light", &ImportNode::trafficLight) - .def_readwrite("tags", &ImportNode::keyVals), - - luabind::class_("Way") - // .def(luabind::constructor<>()) - .def_readonly("id", &ExtractionWay::id) - .def_readwrite("name", &ExtractionWay::name) - .def_readwrite("forward_speed", &ExtractionWay::forward_speed) - .def_readwrite("backward_speed", &ExtractionWay::backward_speed) - .def_readwrite("duration", &ExtractionWay::duration) - .def_readwrite("access", &ExtractionWay::access) - .def_readwrite("roundabout", &ExtractionWay::roundabout) - .def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted) - .def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid) - .def_readwrite("tags", &ExtractionWay::keyVals) - .property("direction", &ExtractionWay::get_direction, &ExtractionWay::set_direction) - .property("forward_mode", &ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode) - .property("backward_mode", &ExtractionWay::get_backward_mode, &ExtractionWay::set_backward_mode) - .enum_("constants")[ - luabind::value("notSure", 0), - luabind::value("oneway", 1), - luabind::value("bidirectional", 2), - luabind::value("opposite", 3) - ], - luabind::class_>("vector") - .def("Add", static_cast::*)(const std::string &)>(&std::vector::push_back)) - ]; - - if (0 != luaL_dofile(lua_state, file_name.c_str())) - { - luabind::object error_msg(luabind::from_stack(lua_state, -1)); - std::ostringstream error_stream; - error_stream << error_msg; - throw OSRMException("ERROR occured in profile script:\n" + error_stream.str()); - } -} - -lua_State *ScriptingEnvironment::getLuaState() -{ - bool initialized = false; - auto& ref = script_contexts.local(initialized); - if (!initialized) - { - std::shared_ptr state(luaL_newstate(), lua_close); - ref = state; - initLuaState(ref.get()); - } - - return ref.get(); -} diff --git a/3party/osrm/osrm-backend/Extractor/XMLParser.cpp b/3party/osrm/osrm-backend/Extractor/XMLParser.cpp deleted file mode 100644 index a984c76b72..0000000000 --- a/3party/osrm/osrm-backend/Extractor/XMLParser.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "XMLParser.h" - -#include "ExtractionWay.h" -#include "ExtractorCallbacks.h" - -#include "../DataStructures/HashTable.h" -#include "../DataStructures/ImportNode.h" -#include "../DataStructures/InputReaderFactory.h" -#include "../DataStructures/Restriction.h" -#include "../Util/cast.hpp" -#include "../Util/simple_logger.hpp" -#include "../Util/StringUtil.h" -#include "../typedefs.h" - -#include - -XMLParser::XMLParser(const char *filename, - ExtractorCallbacks *extractor_callbacks, - ScriptingEnvironment &scripting_environment) - : BaseParser(extractor_callbacks, scripting_environment) -{ - inputReader = inputReaderFactory(filename); -} - -bool XMLParser::ReadHeader() { return xmlTextReaderRead(inputReader) == 1; } -bool XMLParser::Parse() -{ - while (xmlTextReaderRead(inputReader) == 1) - { - const int type = xmlTextReaderNodeType(inputReader); - - // 1 is Element - if (type != 1) - { - continue; - } - - xmlChar *currentName = xmlTextReaderName(inputReader); - if (currentName == nullptr) - { - continue; - } - - if (xmlStrEqual(currentName, (const xmlChar *)"node") == 1) - { - ImportNode current_node = ReadXMLNode(); - ParseNodeInLua(current_node, lua_state); - extractor_callbacks->ProcessNode(current_node); - } - - if (xmlStrEqual(currentName, (const xmlChar *)"way") == 1) - { - ExtractionWay way = ReadXMLWay(); - ParseWayInLua(way, lua_state); - extractor_callbacks->ProcessWay(way); - } - if (use_turn_restrictions && xmlStrEqual(currentName, (const xmlChar *)"relation") == 1) - { - InputRestrictionContainer current_restriction = ReadXMLRestriction(); - if ((UINT_MAX != current_restriction.fromWay) && - !extractor_callbacks->ProcessRestriction(current_restriction)) - { - std::cerr << "[XMLParser] restriction not parsed" << std::endl; - } - } - xmlFree(currentName); - } - return true; -} - -InputRestrictionContainer XMLParser::ReadXMLRestriction() -{ - - InputRestrictionContainer restriction; - - if (xmlTextReaderIsEmptyElement(inputReader) == 1) - { - return restriction; - } - - std::string except_tag_string; - const int depth = xmlTextReaderDepth(inputReader); - while (xmlTextReaderRead(inputReader) == 1) - { - const int child_type = xmlTextReaderNodeType(inputReader); - if (child_type != 1 && child_type != 15) - { - continue; - } - const int child_depth = xmlTextReaderDepth(inputReader); - xmlChar *child_name = xmlTextReaderName(inputReader); - if (child_name == nullptr) - { - continue; - } - if (depth == child_depth && child_type == 15 && - xmlStrEqual(child_name, (const xmlChar *)"relation") == 1) - { - xmlFree(child_name); - break; - } - if (child_type != 1) - { - xmlFree(child_name); - continue; - } - - if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1) - { - xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k"); - xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v"); - if (key != nullptr && value != nullptr) - { - if (xmlStrEqual(key, (const xmlChar *)"restriction") && - StringStartsWith((const char *)value, "only_")) - { - restriction.restriction.flags.isOnly = true; - } - if (xmlStrEqual(key, (const xmlChar *)"except")) - { - except_tag_string = (const char *)value; - } - } - - if (key != nullptr) - { - xmlFree(key); - } - if (value != nullptr) - { - xmlFree(value); - } - } - else if (xmlStrEqual(child_name, (const xmlChar *)"member") == 1) - { - xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref"); - if (ref != nullptr) - { - xmlChar *role = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"role"); - xmlChar *type = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"type"); - - if (xmlStrEqual(role, (const xmlChar *)"to") && - xmlStrEqual(type, (const xmlChar *)"way")) - { - restriction.toWay = cast::string_to_uint((const char *)ref); - } - if (xmlStrEqual(role, (const xmlChar *)"from") && - xmlStrEqual(type, (const xmlChar *)"way")) - { - restriction.fromWay = cast::string_to_uint((const char *)ref); - } - if (xmlStrEqual(role, (const xmlChar *)"via") && - xmlStrEqual(type, (const xmlChar *)"node")) - { - restriction.restriction.viaNode = cast::string_to_uint((const char *)ref); - } - - if (nullptr != type) - { - xmlFree(type); - } - if (nullptr != role) - { - xmlFree(role); - } - if (nullptr != ref) - { - xmlFree(ref); - } - } - } - xmlFree(child_name); - } - - if (ShouldIgnoreRestriction(except_tag_string)) - { - restriction.fromWay = UINT_MAX; // workaround to ignore the restriction - } - return restriction; -} - -ExtractionWay XMLParser::ReadXMLWay() -{ - ExtractionWay way; - if (xmlTextReaderIsEmptyElement(inputReader) == 1) - { - return way; - } - const int depth = xmlTextReaderDepth(inputReader); - while (xmlTextReaderRead(inputReader) == 1) - { - const int child_type = xmlTextReaderNodeType(inputReader); - if (child_type != 1 && child_type != 15) - { - continue; - } - const int child_depth = xmlTextReaderDepth(inputReader); - xmlChar *child_name = xmlTextReaderName(inputReader); - if (child_name == nullptr) - { - continue; - } - - if (depth == child_depth && child_type == 15 && - xmlStrEqual(child_name, (const xmlChar *)"way") == 1) - { - xmlChar *way_id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id"); - way.id = cast::string_to_uint((char *)way_id); - xmlFree(way_id); - xmlFree(child_name); - break; - } - if (child_type != 1) - { - xmlFree(child_name); - continue; - } - - if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1) - { - xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k"); - xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v"); - - if (key != nullptr && value != nullptr) - { - way.keyVals.Add(std::string((char *)key), std::string((char *)value)); - } - if (key != nullptr) - { - xmlFree(key); - } - if (value != nullptr) - { - xmlFree(value); - } - } - else if (xmlStrEqual(child_name, (const xmlChar *)"nd") == 1) - { - xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref"); - if (ref != nullptr) - { - way.path.push_back(cast::string_to_uint((const char *)ref)); - xmlFree(ref); - } - } - xmlFree(child_name); - } - return way; -} - -ImportNode XMLParser::ReadXMLNode() -{ - ImportNode node; - - xmlChar *attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lat"); - if (attribute != nullptr) - { - node.lat = static_cast(COORDINATE_PRECISION * cast::string_to_double((const char *)attribute)); - xmlFree(attribute); - } - attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lon"); - if (attribute != nullptr) - { - node.lon = static_cast(COORDINATE_PRECISION * cast::string_to_double((const char *)attribute)); - xmlFree(attribute); - } - attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id"); - if (attribute != nullptr) - { - node.node_id = cast::string_to_uint((const char *)attribute); - xmlFree(attribute); - } - - if (xmlTextReaderIsEmptyElement(inputReader) == 1) - { - return node; - } - const int depth = xmlTextReaderDepth(inputReader); - while (xmlTextReaderRead(inputReader) == 1) - { - const int child_type = xmlTextReaderNodeType(inputReader); - // 1 = Element, 15 = EndElement - if (child_type != 1 && child_type != 15) - { - continue; - } - const int child_depth = xmlTextReaderDepth(inputReader); - xmlChar *child_name = xmlTextReaderName(inputReader); - if (child_name == nullptr) - { - continue; - } - - if (depth == child_depth && child_type == 15 && - xmlStrEqual(child_name, (const xmlChar *)"node") == 1) - { - xmlFree(child_name); - break; - } - if (child_type != 1) - { - xmlFree(child_name); - continue; - } - - if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1) - { - xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k"); - xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v"); - if (key != nullptr && value != nullptr) - { - node.keyVals.Add(std::string((char *)(key)), std::string((char *)(value))); - } - if (key != nullptr) - { - xmlFree(key); - } - if (value != nullptr) - { - xmlFree(value); - } - } - - xmlFree(child_name); - } - return node; -} diff --git a/3party/osrm/osrm-backend/Extractor/XMLParser.h b/3party/osrm/osrm-backend/Extractor/XMLParser.h deleted file mode 100644 index 178747ae71..0000000000 --- a/3party/osrm/osrm-backend/Extractor/XMLParser.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef XMLPARSER_H_ -#define XMLPARSER_H_ - -#include "BaseParser.h" -#include "../DataStructures/Restriction.h" - -#include - -class ExtractorCallbacks; - -class XMLParser : public BaseParser -{ - public: - XMLParser(const char *filename, - ExtractorCallbacks *extractor_callbacks, - ScriptingEnvironment &scripting_environment); - bool ReadHeader(); - bool Parse(); - - private: - InputRestrictionContainer ReadXMLRestriction(); - ExtractionWay ReadXMLWay(); - ImportNode ReadXMLNode(); - xmlTextReaderPtr inputReader; -}; - -#endif /* XMLPARSER_H_ */ diff --git a/3party/osrm/osrm-backend/Gemfile b/3party/osrm/osrm-backend/Gemfile old mode 100644 new mode 100755 index 114808e497..31d044bd62 --- a/3party/osrm/osrm-backend/Gemfile +++ b/3party/osrm/osrm-backend/Gemfile @@ -4,4 +4,4 @@ gem "cucumber" gem "rake" gem "osmlib-base" gem "sys-proctable" -gem "rspec-expectations" \ No newline at end of file +gem "rspec-expectations" diff --git a/3party/osrm/osrm-backend/Gemfile.lock b/3party/osrm/osrm-backend/Gemfile.lock old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/Include/osrm/Coordinate.h b/3party/osrm/osrm-backend/Include/osrm/Coordinate.h deleted file mode 100644 index 5b8102d283..0000000000 --- a/3party/osrm/osrm-backend/Include/osrm/Coordinate.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef FIXED_POINT_COORDINATE_H_ -#define FIXED_POINT_COORDINATE_H_ - -#include //for std::ostream -#include -#include - -#include "../../../../../std/msvc_cpp11_workarounds.hpp" - -CONSTEXPR_VALUE float COORDINATE_PRECISION = 1000000.f; - -struct FixedPointCoordinate -{ - int lat; - int lon; - - FixedPointCoordinate(); - FixedPointCoordinate(int lat, int lon); - - template - FixedPointCoordinate(const T &coordinate) : lat(coordinate.lat), lon(coordinate.lon) - { - static_assert(std::is_same::value, "coordinate types incompatible"); - static_assert(std::is_same::value, "coordinate types incompatible"); - } - - void Reset(); - bool isSet() const; - bool isValid() const; - bool operator==(const FixedPointCoordinate &other) const; - - static double - ApproximateDistance(const int lat1, const int lon1, const int lat2, const int lon2); - - static double ApproximateDistance(const FixedPointCoordinate &first_coordinate, - const FixedPointCoordinate &second_coordinate); - - static float ApproximateEuclideanDistance(const FixedPointCoordinate &first_coordinate, - const FixedPointCoordinate &second_coordinate); - - static float - ApproximateEuclideanDistance(const int lat1, const int lon1, const int lat2, const int lon2); - - static float ApproximateSquaredEuclideanDistance(const FixedPointCoordinate &first_coordinate, - const FixedPointCoordinate &second_coordinate); - - static void convertInternalLatLonToString(const int value, std::string &output); - - static void convertInternalCoordinateToString(const FixedPointCoordinate &coordinate, - std::string &output); - - static void convertInternalReversedCoordinateToString(const FixedPointCoordinate &coordinate, - std::string &output); - - static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source, - const FixedPointCoordinate &segment_target, - const FixedPointCoordinate &query_location); - - static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source, - const FixedPointCoordinate &segment_target, - const FixedPointCoordinate &query_location, - FixedPointCoordinate &nearest_location, - float &ratio); - - static int - OrderedPerpendicularDistanceApproximation(const FixedPointCoordinate &segment_source, - const FixedPointCoordinate &segment_target, - const FixedPointCoordinate &query_location); - - static float GetBearing(const FixedPointCoordinate &A, const FixedPointCoordinate &B); - - float GetBearing(const FixedPointCoordinate &other) const; - - void Output(std::ostream &out) const; - - static float DegreeToRadian(const float degree); - static float RadianToDegree(const float radian); -}; - -inline std::ostream &operator<<(std::ostream &out_stream, FixedPointCoordinate const &coordinate) -{ - coordinate.Output(out_stream); - return out_stream; -} - -#endif /* FIXED_POINT_COORDINATE_H_ */ diff --git a/3party/osrm/osrm-backend/Include/osrm/Reply.h b/3party/osrm/osrm-backend/Include/osrm/Reply.h deleted file mode 100644 index a2ee1f4863..0000000000 --- a/3party/osrm/osrm-backend/Include/osrm/Reply.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef REPLY_H -#define REPLY_H - -#include "Header.h" - -#include - -#include - -namespace http -{ - -const char okHTML[] = ""; -const char badRequestHTML[] = "{\"status\": 400,\"status_message\":\"Bad Request\"}"; -const char internalServerErrorHTML[] = - "{\"status\": 500,\"status_message\":\"Internal Server Error\"}"; -const char seperators[] = {':', ' '}; -const char crlf[] = {'\r', '\n'}; -const std::string okString = "HTTP/1.0 200 OK\r\n"; -const std::string badRequestString = "HTTP/1.0 400 Bad Request\r\n"; -const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Error\r\n"; - -class Reply -{ - public: - enum status_type - { ok = 200, - badRequest = 400, - internalServerError = 500 } status; - - std::vector
headers; - std::vector ToBuffers(); - std::vector HeaderstoBuffers(); - std::vector content; - static Reply StockReply(status_type status); - void SetSize(const unsigned size); - void SetUncompressedSize(); - - Reply(); - - private: - std::string ToString(Reply::status_type status); - boost::asio::const_buffer ToBuffer(Reply::status_type status); -}; -} - -#endif // REPLY_H diff --git a/3party/osrm/osrm-backend/LICENCE.TXT b/3party/osrm/osrm-backend/LICENCE.TXT old mode 100644 new mode 100755 index 28fe97b353..c77e5cd1b2 --- a/3party/osrm/osrm-backend/LICENCE.TXT +++ b/3party/osrm/osrm-backend/LICENCE.TXT @@ -1,4 +1,4 @@ -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, diff --git a/3party/osrm/osrm-backend/Library/OSRM_impl.cpp b/3party/osrm/osrm-backend/Library/OSRM_impl.cpp deleted file mode 100644 index 4d194c065d..0000000000 --- a/3party/osrm/osrm-backend/Library/OSRM_impl.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -namespace boost { namespace interprocess { class named_mutex; } } - -#include "OSRM_impl.h" -#include "OSRM.h" - -#include -#include -#include - -#include "../Plugins/BasePlugin.h" -#include "../Plugins/DistanceTablePlugin.h" -#include "../Plugins/HelloWorldPlugin.h" -#include "../Plugins/LocatePlugin.h" -#include "../Plugins/NearestPlugin.h" -#include "../Plugins/TimestampPlugin.h" -#include "../Plugins/ViaRoutePlugin.h" -#include "../Plugins/MapsMePlugin.h" -#include "../Server/DataStructures/BaseDataFacade.h" -#include "../Server/DataStructures/InternalDataFacade.h" -#include "../Server/DataStructures/SharedBarriers.h" -#include "../Server/DataStructures/SharedDataFacade.h" -#include "../Util/make_unique.hpp" -#include "../Util/ProgramOptions.h" -#include "../Util/simple_logger.hpp" - -#include -#include -#include - -#include -#include -#include -#include - -OSRM_impl::OSRM_impl(ServerPaths server_paths, const bool use_shared_memory) -{ - if (use_shared_memory) - { - barrier = osrm::make_unique(); - query_data_facade = new SharedDataFacade(); - } - else - { - // populate base path - populate_base_path(server_paths); - query_data_facade = new InternalDataFacade(server_paths); - } - - // The following plugins handle all requests. - RegisterPlugin(new DistanceTablePlugin>(query_data_facade)); - RegisterPlugin(new HelloWorldPlugin()); - RegisterPlugin(new LocatePlugin>(query_data_facade)); - RegisterPlugin(new NearestPlugin>(query_data_facade)); - RegisterPlugin(new TimestampPlugin>(query_data_facade)); - RegisterPlugin(new ViaRoutePlugin>(query_data_facade)); - RegisterPlugin(new MapsMePlugin>( - query_data_facade, server_paths["borders"].string(), server_paths["enodesdata"].string())); -} - -OSRM_impl::~OSRM_impl() -{ - delete query_data_facade; - for (PluginMap::value_type &plugin_pointer : plugin_map) - { - delete plugin_pointer.second; - } -} - -void OSRM_impl::RegisterPlugin(BasePlugin *plugin) -{ - SimpleLogger().Write() << "loaded plugin: " << plugin->GetDescriptor(); - if (plugin_map.find(plugin->GetDescriptor()) != plugin_map.end()) - { - delete plugin_map.find(plugin->GetDescriptor())->second; - } - plugin_map.emplace(plugin->GetDescriptor(), plugin); -} - -void OSRM_impl::RunQuery(RouteParameters &route_parameters, http::Reply &reply) -{ - const PluginMap::const_iterator &iter = plugin_map.find(route_parameters.service); - - if (plugin_map.end() != iter) - { - reply.status = http::Reply::ok; - if (barrier) - { - // lock update pending - boost::interprocess::scoped_lock pending_lock( - barrier->pending_update_mutex); - - // lock query - boost::interprocess::scoped_lock query_lock( - barrier->query_mutex); - - // unlock update pending - pending_lock.unlock(); - - // increment query count - ++(barrier->number_of_queries); - - (static_cast *>(query_data_facade)) - ->CheckAndReloadFacade(); - } - - iter->second->HandleRequest(route_parameters, reply); - if (barrier) - { - // lock query - boost::interprocess::scoped_lock query_lock( - barrier->query_mutex); - - // decrement query count - --(barrier->number_of_queries); - BOOST_ASSERT_MSG(0 <= barrier->number_of_queries, "invalid number of queries"); - - // notify all processes that were waiting for this condition - if (0 == barrier->number_of_queries) - { - barrier->no_running_queries_condition.notify_all(); - } - } - } - else - { - reply = http::Reply::StockReply(http::Reply::badRequest); - } -} - -// proxy code for compilation firewall - -OSRM::OSRM(ServerPaths paths, const bool use_shared_memory) - : OSRM_pimpl_(osrm::make_unique(paths, use_shared_memory)) -{ -} - -OSRM::~OSRM() { OSRM_pimpl_.reset(); } - -void OSRM::RunQuery(RouteParameters &route_parameters, http::Reply &reply) -{ - OSRM_pimpl_->RunQuery(route_parameters, reply); -} diff --git a/3party/osrm/osrm-backend/Plugins/MapsMePlugin.h b/3party/osrm/osrm-backend/Plugins/MapsMePlugin.h deleted file mode 100644 index 78ac4a6f2d..0000000000 --- a/3party/osrm/osrm-backend/Plugins/MapsMePlugin.h +++ /dev/null @@ -1,192 +0,0 @@ -#pragma once - -#include "BasePlugin.h" - -#include "../Algorithms/ObjectToBase64.h" -#include "../DataStructures/EdgeBasedNodeData.h" -#include "../DataStructures/JSONContainer.h" -#include "../DataStructures/QueryEdge.h" -#include "../DataStructures/SearchEngine.h" -#include "../Descriptors/BaseDescriptor.h" -#include "../Util/make_unique.hpp" -#include "../Util/StringUtil.h" -#include "../Util/TimingUtil.h" - -#include -#include -#include -#include -#include - -#include "../../../../base/string_utils.hpp" -#include "../../../../coding/file_container.hpp" -#include "../../../../coding/read_write_utils.hpp" -#include "../../../../defines.hpp" -#include "../../../../geometry/region2d.hpp" -#include "../../../../indexer/geometry_serialization.hpp" -#include "../../../../indexer/mercator.hpp" -#include "../../../../storage/country_decl.hpp" -#include "../../../../storage/country_polygon.hpp" - -template class MapsMePlugin final : public BasePlugin -{ - class GetByPoint - { - m2::PointD const &m_pt; - std::vector> const &m_regions; - - public: - size_t m_res; - - GetByPoint(std::vector> const ®ions, m2::PointD const &pt) - : m_pt(pt), m_regions(regions), m_res(-1) - { - } - - /// @param[in] id Index in m_countries. - /// @return false If point is in country. - bool operator()(size_t id) - { - auto it = - find_if(m_regions[id].begin(), m_regions[id].end(), [&](m2::RegionD const ®ion) - { return region.Contains(m_pt);}); - if (it == m_regions[id].end()) - return true; - m_res = id; - return false; - } - }; - - public: - explicit MapsMePlugin(DataFacadeT *facade, std::string const &baseDir, std::string const & nodeDataFile) - : m_descriptorString("mapsme"), m_facade(facade), - m_reader(baseDir + '/' + PACKED_POLYGONS_FILE) - { - if (!osrm::LoadNodeDataFromFile(nodeDataFile, m_nodeData)) - { - SimpleLogger().Write(logDEBUG) << "Can't load node data"; - return; - } - ReaderSource src(m_reader.GetReader(PACKED_POLYGONS_INFO_TAG)); - rw::Read(src, m_countries); - m_regions.resize(m_countries.size()); - for (size_t i = 0; i < m_countries.size(); ++i) - { - // load regions from file - ReaderSource src(m_reader.GetReader(strings::to_string(i))); - - uint32_t const count = ReadVarUint(src); - for (size_t j = 0; j < count; ++j) - { - vector points; - serial::LoadOuterPath(src, serial::CodingParams(), points); - - m_regions[i].emplace_back(move(m2::RegionD(points.begin(), points.end()))); - } - } - m_searchEngine = osrm::make_unique>(facade); - } - - template void ForEachCountry(m2::PointD const &pt, ToDo &toDo) const - { - for (size_t i = 0; i < m_countries.size(); ++i) - if (m_countries[i].m_rect.IsPointInside(pt)) - if (!toDo(i)) - return; - } - - virtual ~MapsMePlugin() {} - - const std::string GetDescriptor() const final { return m_descriptorString; } - - void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final - { - // check number of parameters - if (2 > route_parameters.coordinates.size()) - { - reply = http::Reply::StockReply(http::Reply::badRequest); - return; - } - - RawRouteData raw_route; - raw_route.check_sum = m_facade->GetCheckSum(); - - if (std::any_of(begin(route_parameters.coordinates), end(route_parameters.coordinates), - [&](FixedPointCoordinate coordinate) - { - return !coordinate.isValid(); - })) - { - reply = http::Reply::StockReply(http::Reply::badRequest); - return; - } - - for (const FixedPointCoordinate &coordinate : route_parameters.coordinates) - { - raw_route.raw_via_node_coordinates.emplace_back(coordinate); - } - - std::vector phantom_node_vector(raw_route.raw_via_node_coordinates.size()); - const bool checksum_OK = (route_parameters.check_sum == raw_route.check_sum); - - for (unsigned i = 0; i < raw_route.raw_via_node_coordinates.size(); ++i) - { - m_facade->FindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i], - phantom_node_vector[i], - route_parameters.zoom_level); - } - - PhantomNodes current_phantom_node_pair; - for (unsigned i = 0; i < phantom_node_vector.size() - 1; ++i) - { - current_phantom_node_pair.source_phantom = phantom_node_vector[i]; - current_phantom_node_pair.target_phantom = phantom_node_vector[i + 1]; - raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair); - } - - m_searchEngine->alternative_path(raw_route.segment_end_coordinates.front(), raw_route); - - if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length) - { - SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found"; - } - reply.status = http::Reply::ok; - - // Get mwm names - set usedMwms; - - for (auto i : osrm::irange(0, raw_route.unpacked_path_segments.size())) - { - size_t const n = raw_route.unpacked_path_segments[i].size(); - for (size_t j = 0; j < n; ++j) - { - PathData const &path_data = raw_route.unpacked_path_segments[i][j]; - auto const & data = m_nodeData[path_data.node]; - if (data.m_segments.empty()) - continue; - auto const & seg = data.m_segments.front(); - m2::PointD pt = MercatorBounds::FromLatLon(seg.lat1, seg.lon1); - GetByPoint doGet(m_regions, pt); - ForEachCountry(pt, doGet); - - if (doGet.m_res != -1) - usedMwms.insert(m_countries[doGet.m_res].m_name); - } - } - - JSON::Object json_object; - JSON::Array json_array; - json_array.values.insert(json_array.values.begin(), usedMwms.begin(), usedMwms.end()); - json_object.values["used_mwms"] = json_array; - JSON::render(reply.content, json_object); - } - - private: - std::unique_ptr> m_searchEngine; - std::vector m_countries; - std::vector> m_regions; - std::string m_descriptorString; - DataFacadeT * m_facade; - FilesContainerR m_reader; - osrm::NodeDataVectorT m_nodeData; -}; diff --git a/3party/osrm/osrm-backend/Plugins/ViaRoutePlugin.h b/3party/osrm/osrm-backend/Plugins/ViaRoutePlugin.h deleted file mode 100644 index 7bd4b70ecd..0000000000 --- a/3party/osrm/osrm-backend/Plugins/ViaRoutePlugin.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef VIA_ROUTE_PLUGIN_H -#define VIA_ROUTE_PLUGIN_H - -#include "BasePlugin.h" - -#include "../Algorithms/ObjectToBase64.h" -#include "../DataStructures/QueryEdge.h" -#include "../DataStructures/SearchEngine.h" -#include "../Descriptors/BaseDescriptor.h" -#include "../Descriptors/GPXDescriptor.h" -#include "../Descriptors/JSONDescriptor.h" -#include "../Util/make_unique.hpp" -#include "../Util/simple_logger.hpp" -#include "../Util/StringUtil.h" -#include "../Util/TimingUtil.h" - -#include - -#include -#include -#include -#include -#include - -template class ViaRoutePlugin final : public BasePlugin -{ - private: - std::unordered_map descriptor_table; - std::unique_ptr> search_engine_ptr; - - public: - explicit ViaRoutePlugin(DataFacadeT *facade) : descriptor_string("viaroute"), facade(facade) - { - search_engine_ptr = osrm::make_unique>(facade); - - descriptor_table.emplace("json", 0); - descriptor_table.emplace("gpx", 1); - // descriptor_table.emplace("geojson", 2); - } - - virtual ~ViaRoutePlugin() {} - - const std::string GetDescriptor() const final { return descriptor_string; } - - void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final - { - // check number of parameters - if (2 > route_parameters.coordinates.size() || - std::any_of(begin(route_parameters.coordinates), - end(route_parameters.coordinates), - [&](FixedPointCoordinate coordinate) - { - return !coordinate.isValid(); - })) - { - reply = http::Reply::StockReply(http::Reply::badRequest); - return; - } - - RawRouteData raw_route; - raw_route.check_sum = facade->GetCheckSum(); - for (const FixedPointCoordinate &coordinate : route_parameters.coordinates) - { - raw_route.raw_via_node_coordinates.emplace_back(coordinate); - } - - std::vector phantom_node_vector(raw_route.raw_via_node_coordinates.size()); - const bool checksum_OK = (route_parameters.check_sum == raw_route.check_sum); - - for (unsigned i = 0; i < raw_route.raw_via_node_coordinates.size(); ++i) - { - if (checksum_OK && i < route_parameters.hints.size() && - !route_parameters.hints[i].empty()) - { - ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], phantom_node_vector[i]); - if (phantom_node_vector[i].isValid(facade->GetNumberOfNodes())) - { - continue; - } - } - facade->FindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i], - phantom_node_vector[i], - route_parameters.zoom_level); - } - - PhantomNodes current_phantom_node_pair; - for (unsigned i = 0; i < phantom_node_vector.size() - 1; ++i) - { - current_phantom_node_pair.source_phantom = phantom_node_vector[i]; - current_phantom_node_pair.target_phantom = phantom_node_vector[i + 1]; - raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair); - } - - const bool is_alternate_requested = route_parameters.alternate_route; - const bool is_only_one_segment = (1 == raw_route.segment_end_coordinates.size()); - if (is_alternate_requested && is_only_one_segment) - { - search_engine_ptr->alternative_path(raw_route.segment_end_coordinates.front(), - raw_route); - } - else - { - search_engine_ptr->shortest_path( - raw_route.segment_end_coordinates, route_parameters.uturns, raw_route); - } - - if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length) - { - SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found"; - } - reply.status = http::Reply::ok; - - DescriptorConfig descriptor_config; - - auto iter = descriptor_table.find(route_parameters.output_format); - unsigned descriptor_type = (iter != descriptor_table.end() ? iter->second : 0); - - descriptor_config.zoom_level = route_parameters.zoom_level; - descriptor_config.instructions = route_parameters.print_instructions; - descriptor_config.geometry = route_parameters.geometry; - descriptor_config.encode_geometry = route_parameters.compression; - - std::shared_ptr> descriptor; - switch (descriptor_type) - { - // case 0: - // descriptor = std::make_shared>(); - // break; - case 1: - descriptor = std::make_shared>(facade); - break; - // case 2: - // descriptor = std::make_shared>(); - // break; - default: - descriptor = std::make_shared>(facade); - break; - } - - descriptor->SetConfig(descriptor_config); - descriptor->Run(raw_route, reply); - } - - private: - std::string descriptor_string; - DataFacadeT *facade; -}; - -#endif // VIA_ROUTE_PLUGIN_H diff --git a/3party/osrm/osrm-backend/README.md b/3party/osrm/osrm-backend/README.md old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/Rakefile b/3party/osrm/osrm-backend/Rakefile old mode 100644 new mode 100755 index 562823b8ae..1c848bb07d --- a/3party/osrm/osrm-backend/Rakefile +++ b/3party/osrm/osrm-backend/Rakefile @@ -158,7 +158,7 @@ task :down do Process.kill 'TERM', pid else puts "Already down." - end + end end desc "Kill all osrm-extract, osrm-prepare and osrm-routed processes." @@ -168,7 +168,7 @@ task :kill do each_process('osrm-extract') { |pid,state| Process.kill 'KILL', pid } wait_for_shutdown 'osrm-routed' wait_for_shutdown 'osrm-prepare' - wait_for_shutdown 'osrm-extract' + wait_for_shutdown 'osrm-extract' end desc "Get PIDs of all osrm-extract, osrm-prepare and osrm-routed processes." @@ -187,3 +187,4 @@ desc "Remove test cache files." task :sweep do system "rm test/cache/*" end + diff --git a/3party/osrm/osrm-backend/RoutingAlgorithms/BasicRoutingInterface.h b/3party/osrm/osrm-backend/RoutingAlgorithms/BasicRoutingInterface.h deleted file mode 100644 index f5e7225a21..0000000000 --- a/3party/osrm/osrm-backend/RoutingAlgorithms/BasicRoutingInterface.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef BASIC_ROUTING_INTERFACE_H -#define BASIC_ROUTING_INTERFACE_H - -#include "../DataStructures/RawRouteData.h" -#include "../DataStructures/SearchEngineData.h" -#include "../DataStructures/TurnInstructions.h" -// #include "../Util/simple_logger.hpp.h" - -#include - -#include - -SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap2; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap2; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap3; -SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap3; - -template class BasicRoutingInterface -{ - private: - typedef typename DataFacadeT::EdgeData EdgeData; - - protected: - DataFacadeT *facade; - - public: - BasicRoutingInterface() = delete; - BasicRoutingInterface(const BasicRoutingInterface &) = delete; - explicit BasicRoutingInterface(DataFacadeT *facade) : facade(facade) {} - virtual ~BasicRoutingInterface() {}; - - inline void RoutingStep(SearchEngineData::QueryHeap &forward_heap, - SearchEngineData::QueryHeap &reverse_heap, - NodeID *middle_node_id, - int *upper_bound, - const int min_edge_offset, - const bool forward_direction) const - { - const NodeID node = forward_heap.DeleteMin(); - const int distance = forward_heap.GetKey(node); - - // const NodeID parentnode = forward_heap.GetData(node).parent; - // SimpleLogger().Write() << (forward_direction ? "[fwd] " : "[rev] ") << "settled edge (" << parentnode << "," << node << "), dist: " << distance; - - if (reverse_heap.WasInserted(node)) - { - const int new_distance = reverse_heap.GetKey(node) + distance; - if (new_distance < *upper_bound) - { - if (new_distance >= 0) - { - *middle_node_id = node; - *upper_bound = new_distance; - // SimpleLogger().Write() << "accepted middle node " << node << " at distance " << new_distance; - // } else { - // SimpleLogger().Write() << "discared middle node " << node << " at distance " << new_distance; - } - } - } - - if (distance + min_edge_offset > *upper_bound) - { - // SimpleLogger().Write() << "min_edge_offset: " << min_edge_offset; - forward_heap.DeleteAll(); - return; - } - - // Stalling - for (const auto edge : facade->GetAdjacentEdgeRange(node)) - { - const EdgeData &data = facade->GetEdgeData(edge, node); - const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward); - if (reverse_flag) - { - const NodeID to = facade->GetTarget(edge); - const int edge_weight = data.distance; - - BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid"); - - if (forward_heap.WasInserted(to)) - { - if (forward_heap.GetKey(to) + edge_weight < distance) - { - return; - } - } - } - } - - for (const auto edge : facade->GetAdjacentEdgeRange(node)) - { - const EdgeData &data = facade->GetEdgeData(edge, node); - bool forward_directionFlag = (forward_direction ? data.forward : data.backward); - if (forward_directionFlag) - { - - const NodeID to = facade->GetTarget(edge); - const int edge_weight = data.distance; - - BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid"); - const int to_distance = distance + edge_weight; - - // New Node discovered -> Add to Heap + Node Info Storage - if (!forward_heap.WasInserted(to)) - { - forward_heap.Insert(to, to_distance, node); - } - // Found a shorter Path -> Update distance - else if (to_distance < forward_heap.GetKey(to)) - { - // new parent - forward_heap.GetData(to).parent = node; - forward_heap.DecreaseKey(to, to_distance); - } - } - } - } - - inline void UnpackPath(const std::vector &packed_path, - const PhantomNodes &phantom_node_pair, - std::vector &unpacked_path) const - { -// const bool start_traversed_in_reverse = -// (packed_path.front() != phantom_node_pair.source_phantom.forward_node_id); -// const bool target_traversed_in_reverse = -// (packed_path.back() != phantom_node_pair.target_phantom.forward_node_id); - - const unsigned packed_path_size = static_cast(packed_path.size()); - std::stack> recursion_stack; - - // We have to push the path in reverse order onto the stack because it's LIFO. - for (unsigned i = packed_path_size - 1; i > 0; --i) - { - 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 edge; - while (!recursion_stack.empty()) - { - /* - Graphical representation of variables: - - edge.first edge.second - *------------------>* - edge_id - */ - edge = recursion_stack.top(); - recursion_stack.pop(); - - // facade->FindEdge does not suffice here in case of shortcuts. - // The above explanation unclear? Think! - EdgeID smaller_edge_id = SPECIAL_EDGEID; - NodeID smaller_node_id = SPECIAL_NODEID; - int edge_weight = std::numeric_limits::max(); - for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first)) - { - auto const & edgeData = facade->GetEdgeData(edge_id, edge.first); - const int weight = edgeData.distance; - if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) && - edgeData.forward) - { - smaller_edge_id = edge_id; - smaller_node_id = edge.first; - edge_weight = weight; - } - } - - /* - Graphical representation of variables: - - edge.first edge.second - *<------------------* - edge_id - */ - if (SPECIAL_EDGEID == smaller_edge_id) - { - for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.second)) - { - 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 != INVALID_EDGE_WEIGHT, "edge id invalid"); - - const EdgeData &ed = facade->GetEdgeData(smaller_edge_id, smaller_node_id); - if (ed.shortcut) - { // unpack - const NodeID middle_node_id = ed.id; - // again, we need to this in reversed order - recursion_stack.emplace(middle_node_id, edge.second); - recursion_stack.emplace(edge.first, middle_node_id); - } - else - { - const TravelMode travel_mode = facade->GetTravelModeForEdgeID(ed.id); - unpacked_path.emplace_back(edge.second, - INVALID_EDGE_WEIGHT, - TurnInstruction::NoTurn, - ed.distance, - travel_mode); - } - } - - // there is no equivalent to a node-based node in an edge-expanded graph. - // two equivalent routes may start (or end) at different node-based edges - // as they are added with the offset how much "distance" on the edge - // has already been traversed. Depending on offset one needs to remove - // the last node. - if (unpacked_path.size() > 1) - { - const std::size_t last_index = unpacked_path.size() - 1; - const std::size_t second_to_last_index = last_index - 1; - - // looks like a trivially true check but tests for underflow - BOOST_ASSERT(last_index > second_to_last_index); - - if (unpacked_path[last_index].node == unpacked_path[second_to_last_index].node) - { - unpacked_path.pop_back(); - } - BOOST_ASSERT(!unpacked_path.empty()); - } - } - - inline void UnpackEdge(const NodeID s, const NodeID t, std::vector &unpacked_path) const - { - std::stack> recursion_stack; - recursion_stack.emplace(s, t); - - std::pair edge; - while (!recursion_stack.empty()) - { - edge = recursion_stack.top(); - recursion_stack.pop(); - - EdgeID smaller_edge_id = SPECIAL_EDGEID; - NodeID smaller_node_id = SPECIAL_NODEID; - int edge_weight = std::numeric_limits::max(); - for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first)) - { - auto const & edgeData = facade->GetEdgeData(edge_id, edge.first); - const int weight = edgeData.distance; - if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) && - edgeData.forward) - { - smaller_edge_id = edge_id; - smaller_node_id = edge.first; - edge_weight = weight; - } - } - - if (SPECIAL_EDGEID == smaller_edge_id) - { - for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.second)) - { - 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::max(), "edge weight invalid"); - - const EdgeData &ed = facade->GetEdgeData(smaller_edge_id, smaller_node_id); - if (ed.shortcut) - { // unpack - const NodeID middle_node_id = ed.id; - // again, we need to this in reversed order - recursion_stack.emplace(middle_node_id, edge.second); - recursion_stack.emplace(edge.first, middle_node_id); - } - else - { - BOOST_ASSERT_MSG(!ed.shortcut, "edge must be shortcut"); - unpacked_path.emplace_back(edge.first); - } - } - unpacked_path.emplace_back(t); - } - - inline void RetrievePackedPathFromHeap(const SearchEngineData::QueryHeap &forward_heap, - const SearchEngineData::QueryHeap &reverse_heap, - const NodeID middle_node_id, - std::vector &packed_path) const - { - RetrievePackedPathFromSingleHeap(forward_heap, middle_node_id, packed_path); - std::reverse(packed_path.begin(), packed_path.end()); - packed_path.emplace_back(middle_node_id); - RetrievePackedPathFromSingleHeap(reverse_heap, middle_node_id, packed_path); - } - - inline void RetrievePackedPathFromSingleHeap(const SearchEngineData::QueryHeap &search_heap, - const NodeID middle_node_id, - std::vector &packed_path) const - { - NodeID current_node_id = middle_node_id; - while (current_node_id != search_heap.GetData(current_node_id).parent) - { - current_node_id = search_heap.GetData(current_node_id).parent; - packed_path.emplace_back(current_node_id); - } - } -}; - -#endif // BASIC_ROUTING_INTERFACE_H diff --git a/3party/osrm/osrm-backend/RoutingAlgorithms/NToMManyToManyRouting.h b/3party/osrm/osrm-backend/RoutingAlgorithms/NToMManyToManyRouting.h deleted file mode 100644 index 32521790e9..0000000000 --- a/3party/osrm/osrm-backend/RoutingAlgorithms/NToMManyToManyRouting.h +++ /dev/null @@ -1,265 +0,0 @@ -/* - -Copyright (c) 2014, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef NMMANY_TO_MANY_ROUTING_H -#define NMMANY_TO_MANY_ROUTING_H - -#include "BasicRoutingInterface.h" -#include "../DataStructures/SearchEngineData.h" -#include "../typedefs.h" - -#include - -#include -#include -#include -#include - -template class NMManyToManyRouting final : public BasicRoutingInterface -{ - using super = BasicRoutingInterface; - using QueryHeap = SearchEngineData::QueryHeap; - SearchEngineData &engine_working_data; - - struct NodeBucket - { - unsigned target_id; // essentially a row in the distance matrix - EdgeWeight distance; - NodeBucket(const unsigned target_id, const EdgeWeight distance) - : target_id(target_id), distance(distance) - { - } - }; - using SearchSpaceWithBuckets = std::unordered_map>; - - public: - NMManyToManyRouting(DataFacadeT *facade, SearchEngineData &engine_working_data) - : super(facade), engine_working_data(engine_working_data) - { - } - - std::shared_ptr> operator()(const PhantomNodeArray &phantom_sources_nodes_array, - const PhantomNodeArray &phantom_targets_nodes_array) const - { - const unsigned number_of_sources = static_cast(phantom_sources_nodes_array.size()); - const unsigned number_of_targets = static_cast(phantom_targets_nodes_array.size()); - std::shared_ptr> result_table = - std::make_shared>(number_of_sources * number_of_targets, - std::numeric_limits::max()); - - engine_working_data.InitializeOrClearFirstThreadLocalStorage( - super::facade->GetNumberOfNodes()); - - QueryHeap &query_heap = *(engine_working_data.forwardHeap); - - SearchSpaceWithBuckets search_space_with_buckets; - - unsigned target_id = 0; - for (const std::vector &phantom_node_vector : phantom_targets_nodes_array) - { - query_heap.Clear(); - // insert target(s) at distance 0 - - for (const PhantomNode &phantom_node : phantom_node_vector) - { - if (SPECIAL_NODEID != phantom_node.forward_node_id) - { - query_heap.Insert(phantom_node.forward_node_id, - phantom_node.GetForwardWeightPlusOffset(), - phantom_node.forward_node_id); - } - if (SPECIAL_NODEID != phantom_node.reverse_node_id) - { - query_heap.Insert(phantom_node.reverse_node_id, - phantom_node.GetReverseWeightPlusOffset(), - phantom_node.reverse_node_id); - } - } - - // explore search space - while (!query_heap.Empty()) - { - BackwardRoutingStep(target_id, query_heap, search_space_with_buckets); - } - - ++target_id; - } - - // for each source do forward search - unsigned source_id = 0; - for (const std::vector &phantom_node_vector : phantom_sources_nodes_array) - { - query_heap.Clear(); - for (const PhantomNode &phantom_node : phantom_node_vector) - { - // insert sources at distance 0 - if (SPECIAL_NODEID != phantom_node.forward_node_id) - { - query_heap.Insert(phantom_node.forward_node_id, - -phantom_node.GetForwardWeightPlusOffset(), - phantom_node.forward_node_id); - } - if (SPECIAL_NODEID != phantom_node.reverse_node_id) - { - query_heap.Insert(phantom_node.reverse_node_id, - -phantom_node.GetReverseWeightPlusOffset(), - phantom_node.reverse_node_id); - } - } - - // explore search space - while (!query_heap.Empty()) - { - ForwardRoutingStep(source_id, - number_of_targets, - query_heap, - search_space_with_buckets, - result_table); - - } - - ++source_id; - } - //BOOST_ASSERT(source_id == target_id); - return result_table; - } - - void ForwardRoutingStep(const unsigned source_id, - const unsigned number_of_locations, - QueryHeap &query_heap, - const SearchSpaceWithBuckets &search_space_with_buckets, - std::shared_ptr> result_table) const - { - const NodeID node = query_heap.DeleteMin(); - const int source_distance = query_heap.GetKey(node); - - // check if each encountered node has an entry - const auto bucket_iterator = search_space_with_buckets.find(node); - // iterate bucket if there exists one - if (bucket_iterator != search_space_with_buckets.end()) - { - const std::vector &bucket_list = bucket_iterator->second; - for (const NodeBucket ¤t_bucket : bucket_list) - { - // get target id from bucket entry - const unsigned target_id = current_bucket.target_id; - const int target_distance = current_bucket.distance; - const EdgeWeight current_distance = - (*result_table)[source_id * number_of_locations + target_id]; - // check if new distance is better - const EdgeWeight new_distance = source_distance + target_distance; - if (new_distance >= 0 && new_distance < current_distance) - { - (*result_table)[source_id * number_of_locations + target_id] = - (source_distance + target_distance); - } - } - } - if (StallAtNode(node, source_distance, query_heap)) - { - return; - } - RelaxOutgoingEdges(node, source_distance, query_heap); - } - - void BackwardRoutingStep(const unsigned target_id, - QueryHeap &query_heap, - SearchSpaceWithBuckets &search_space_with_buckets) const - { - const NodeID node = query_heap.DeleteMin(); - const int target_distance = query_heap.GetKey(node); - - // store settled nodes in search space bucket - search_space_with_buckets[node].emplace_back(target_id, target_distance); - - if (StallAtNode(node, target_distance, query_heap)) - { - return; - } - - RelaxOutgoingEdges(node, target_distance, query_heap); - } - - template - inline void - RelaxOutgoingEdges(const NodeID node, const EdgeWeight distance, QueryHeap &query_heap) const - { - for (auto edge : super::facade->GetAdjacentEdgeRange(node)) - { - const auto &data = super::facade->GetEdgeData(edge, node); - const bool direction_flag = (forward_direction ? data.forward : data.backward); - if (direction_flag) - { - const NodeID to = super::facade->GetTarget(edge); - const int edge_weight = data.distance; - - BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid"); - const int to_distance = distance + edge_weight; - - // New Node discovered -> Add to Heap + Node Info Storage - if (!query_heap.WasInserted(to)) - { - query_heap.Insert(to, to_distance, node); - } - // Found a shorter Path -> Update distance - else if (to_distance < query_heap.GetKey(to)) - { - // new parent - query_heap.GetData(to).parent = node; - query_heap.DecreaseKey(to, to_distance); - } - } - } - } - - // Stalling - template - inline bool StallAtNode(const NodeID node, const EdgeWeight distance, QueryHeap &query_heap) - const - { - for (auto edge : super::facade->GetAdjacentEdgeRange(node)) - { - const auto &data = super::facade->GetEdgeData(edge, node); - const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward); - if (reverse_flag) - { - const NodeID to = super::facade->GetTarget(edge); - const int edge_weight = data.distance; - BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid"); - if (query_heap.WasInserted(to)) - { - if (query_heap.GetKey(to) + edge_weight < distance) - { - return true; - } - } - } - } - return false; - } -}; -#endif diff --git a/3party/osrm/osrm-backend/Server/APIGrammar.h b/3party/osrm/osrm-backend/Server/APIGrammar.h deleted file mode 100644 index 83a5cd03b3..0000000000 --- a/3party/osrm/osrm-backend/Server/APIGrammar.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef APIGRAMMAR_H_ -#define APIGRAMMAR_H_ - -#include -#include -#include - -namespace qi = boost::spirit::qi; - -template -struct APIGrammar : qi::grammar -{ - explicit APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h) - { - api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query) >> -(uturns); - query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | u | cmp | language | instruction | geometry | alt_route | old_API | num_results) ) ; - - zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)]; - output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)]; - jsonp = (-qi::lit('&')) >> qi::lit("jsonp") >> '=' >> stringwithPercent[boost::bind(&HandlerT::setJSONpParameter, handler, ::_1)]; - checksum = (-qi::lit('&')) >> qi::lit("checksum") >> '=' >> qi::uint_[boost::bind(&HandlerT::setChecksum, handler, ::_1)]; - instruction = (-qi::lit('&')) >> qi::lit("instructions") >> '=' >> qi::bool_[boost::bind(&HandlerT::setInstructionFlag, handler, ::_1)]; - geometry = (-qi::lit('&')) >> qi::lit("geometry") >> '=' >> qi::bool_[boost::bind(&HandlerT::setGeometryFlag, handler, ::_1)]; - cmp = (-qi::lit('&')) >> qi::lit("compression") >> '=' >> qi::bool_[boost::bind(&HandlerT::setCompressionFlag, handler, ::_1)]; - location = (-qi::lit('&')) >> qi::lit("loc") >> '=' >> (qi::double_ >> qi::lit(',') >> qi::double_)[boost::bind(&HandlerT::addCoordinate, handler, ::_1)]; - hint = (-qi::lit('&')) >> qi::lit("hint") >> '=' >> stringwithDot[boost::bind(&HandlerT::addHint, handler, ::_1)]; - u = (-qi::lit('&')) >> qi::lit("u") >> '=' >> qi::bool_[boost::bind(&HandlerT::setUTurn, handler, ::_1)]; - uturns = (-qi::lit('&')) >> qi::lit("uturns") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAllUTurns, handler, ::_1)]; - language = (-qi::lit('&')) >> qi::lit("hl") >> '=' >> string[boost::bind(&HandlerT::setLanguage, handler, ::_1)]; - alt_route = (-qi::lit('&')) >> qi::lit("alt") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAlternateRouteFlag, handler, ::_1)]; - old_API = (-qi::lit('&')) >> qi::lit("geomformat") >> '=' >> string[boost::bind(&HandlerT::setDeprecatedAPIFlag, handler, ::_1)]; - num_results = (-qi::lit('&')) >> qi::lit("num_results") >> '=' >> qi::short_[boost::bind(&HandlerT::setNumberOfResults, handler, ::_1)]; - - string = +(qi::char_("a-zA-Z")); - stringwithDot = +(qi::char_("a-zA-Z0-9_.-")); - stringwithPercent = +(qi::char_("a-zA-Z0-9_.-") | qi::char_('[') | qi::char_(']') | (qi::char_('%') >> qi::char_("0-9A-Z") >> qi::char_("0-9A-Z") )); - } - - qi::rule api_call, query; - qi::rule service, zoom, output, string, jsonp, checksum, location, hint, - stringwithDot, stringwithPercent, language, instruction, geometry, - cmp, alt_route, u, uturns, old_API, num_results; - - HandlerT * handler; -}; - -#endif /* APIGRAMMAR_H_ */ diff --git a/3party/osrm/osrm-backend/Server/RequestHandler.cpp b/3party/osrm/osrm-backend/Server/RequestHandler.cpp deleted file mode 100644 index b358d8d2da..0000000000 --- a/3party/osrm/osrm-backend/Server/RequestHandler.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "RequestHandler.h" - -#include "APIGrammar.h" -#include "Http/Request.h" - -#include "../DataStructures/JSONContainer.h" -#include "../Library/OSRM.h" -#include "../Util/simple_logger.hpp" -#include "../Util/StringUtil.h" -#include "../typedefs.h" - -#include -#include - -#include - -#include -#include - -RequestHandler::RequestHandler() : routing_machine(nullptr) {} - -void RequestHandler::handle_request(const http::Request &req, http::Reply &reply) -{ - // parse command - try - { - std::string request; - URIDecode(req.uri, request); - - // deactivated as GCC apparently does not implement that, not even in 4.9 - // std::time_t t = std::time(nullptr); - // SimpleLogger().Write() << std::put_time(std::localtime(&t), "%m-%d-%Y %H:%M:%S") << - // " " << req.endpoint.to_string() << " " << - // req.referrer << ( 0 == req.referrer.length() ? "- " :" ") << - // req.agent << ( 0 == req.agent.length() ? "- " :" ") << request; - - time_t ltime; - struct tm *time_stamp; - - ltime = time(nullptr); - time_stamp = localtime(<ime); - - // log timestamp - SimpleLogger().Write() << (time_stamp->tm_mday < 10 ? "0" : "") << time_stamp->tm_mday << "-" - << (time_stamp->tm_mon + 1 < 10 ? "0" : "") << (time_stamp->tm_mon + 1) << "-" - << 1900 + time_stamp->tm_year << " " << (time_stamp->tm_hour < 10 ? "0" : "") - << time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "") << time_stamp->tm_min - << ":" << (time_stamp->tm_sec < 10 ? "0" : "") << time_stamp->tm_sec << " " - << req.endpoint.to_string() << " " << req.referrer - << (0 == req.referrer.length() ? "- " : " ") << req.agent - << (0 == req.agent.length() ? "- " : " ") << request; - - RouteParameters route_parameters; - APIGrammarParser api_parser(&route_parameters); - - auto iter = request.begin(); - const bool result = boost::spirit::qi::parse(iter, request.end(), api_parser); - - // check if the was an error with the request - if (!result || (iter != request.end())) - { - reply = http::Reply::StockReply(http::Reply::badRequest); - reply.content.clear(); - const auto position = std::distance(request.begin(), iter); - JSON::Object json_result; - json_result.values["status"] = 400; - std::string message = "Query string malformed close to position "; - message += cast::integral_to_string(position); - json_result.values["status_message"] = message; - JSON::render(reply.content, json_result); - return; - } - - // parsing done, lets call the right plugin to handle the request - BOOST_ASSERT_MSG(routing_machine != nullptr, "pointer not init'ed"); - - if (!route_parameters.jsonp_parameter.empty()) - { // prepend response with jsonp parameter - const std::string json_p = (route_parameters.jsonp_parameter + "("); - reply.content.insert(reply.content.end(), json_p.begin(), json_p.end()); - } - routing_machine->RunQuery(route_parameters, reply); - if (!route_parameters.jsonp_parameter.empty()) - { // append brace to jsonp response - reply.content.push_back(')'); - } - - // set headers - reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size())); - if ("gpx" == route_parameters.output_format) - { // gpx file - reply.headers.emplace_back("Content-Type", "application/gpx+xml; charset=UTF-8"); - reply.headers.emplace_back("Content-Disposition", "attachment; filename=\"route.gpx\""); - } - else if (route_parameters.jsonp_parameter.empty()) - { // json file - reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8"); - reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.json\""); - } - else - { // jsonp - reply.headers.emplace_back("Content-Type", "text/javascript; charset=UTF-8"); - reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.js\""); - } - } - catch (const std::exception &e) - { - reply = http::Reply::StockReply(http::Reply::internalServerError); - SimpleLogger().Write(logWARNING) << "[server error] code: " << e.what() - << ", uri: " << req.uri; - return; - } -} - -void RequestHandler::RegisterRoutingMachine(OSRM *osrm) { routing_machine = osrm; } diff --git a/3party/osrm/osrm-backend/Server/RequestParser.cpp b/3party/osrm/osrm-backend/Server/RequestParser.cpp deleted file mode 100644 index 6e9cddf5ee..0000000000 --- a/3party/osrm/osrm-backend/Server/RequestParser.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "RequestParser.h" - -#include "Http/Request.h" - -namespace http -{ - -RequestParser::RequestParser() : state_(method_start), header({"", ""}) {} - -void RequestParser::Reset() { state_ = method_start; } - -boost::tuple -RequestParser::Parse(Request &req, char *begin, char *end, http::CompressionType *compression_type) -{ - while (begin != end) - { - boost::tribool result = consume(req, *begin++, compression_type); - if (result || !result) - { - return boost::make_tuple(result, begin); - } - } - boost::tribool result = boost::indeterminate; - return boost::make_tuple(result, begin); -} - -boost::tribool -RequestParser::consume(Request &req, char input, http::CompressionType *compression_type) -{ - switch (state_) - { - case method_start: - if (!isChar(input) || isCTL(input) || isTSpecial(input)) - { - return false; - } - state_ = method; - return boost::indeterminate; - case method: - if (input == ' ') - { - state_ = uri; - return boost::indeterminate; - } - if (!isChar(input) || isCTL(input) || isTSpecial(input)) - { - return false; - } - return boost::indeterminate; - case uri_start: - if (isCTL(input)) - { - return false; - } - state_ = uri; - req.uri.push_back(input); - return boost::indeterminate; - case uri: - if (input == ' ') - { - state_ = http_version_h; - return boost::indeterminate; - } - if (isCTL(input)) - { - return false; - } - req.uri.push_back(input); - return boost::indeterminate; - case http_version_h: - if (input == 'H') - { - state_ = http_version_t_1; - return boost::indeterminate; - } - return false; - case http_version_t_1: - if (input == 'T') - { - state_ = http_version_t_2; - return boost::indeterminate; - } - return false; - case http_version_t_2: - if (input == 'T') - { - state_ = http_version_p; - return boost::indeterminate; - } - return false; - case http_version_p: - if (input == 'P') - { - state_ = http_version_slash; - return boost::indeterminate; - } - return false; - case http_version_slash: - if (input == '/') - { - state_ = http_version_major_start; - return boost::indeterminate; - } - return false; - case http_version_major_start: - if (isDigit(input)) - { - state_ = http_version_major; - return boost::indeterminate; - } - return false; - case http_version_major: - if (input == '.') - { - state_ = http_version_minor_start; - return boost::indeterminate; - } - if (isDigit(input)) - { - return boost::indeterminate; - } - return false; - case http_version_minor_start: - if (isDigit(input)) - { - state_ = http_version_minor; - return boost::indeterminate; - } - return false; - case http_version_minor: - if (input == '\r') - { - state_ = expecting_newline_1; - return boost::indeterminate; - } - if (isDigit(input)) - { - return boost::indeterminate; - } - return false; - case expecting_newline_1: - if (input == '\n') - { - state_ = header_line_start; - return boost::indeterminate; - } - return false; - case header_line_start: - if (header.name == "Accept-Encoding") - { - /* giving gzip precedence over deflate */ - if (header.value.find("deflate") != std::string::npos) - { - *compression_type = deflateRFC1951; - } - if (header.value.find("gzip") != std::string::npos) - { - *compression_type = gzipRFC1952; - } - } - - if ("Referer" == header.name) - { - req.referrer = header.value; - } - - if ("User-Agent" == header.name) - { - req.agent = header.value; - } - - if (input == '\r') - { - state_ = expecting_newline_3; - return boost::indeterminate; - } - if (!isChar(input) || isCTL(input) || isTSpecial(input)) - { - return false; - } - state_ = header_name; - header.Clear(); - header.name.push_back(input); - return boost::indeterminate; - case header_lws: - if (input == '\r') - { - state_ = expecting_newline_2; - return boost::indeterminate; - } - if (input == ' ' || input == '\t') - { - return boost::indeterminate; - } - if (isCTL(input)) - { - return false; - } - state_ = header_value; - return boost::indeterminate; - case header_name: - if (input == ':') - { - state_ = space_before_header_value; - return boost::indeterminate; - } - if (!isChar(input) || isCTL(input) || isTSpecial(input)) - { - return false; - } - header.name.push_back(input); - return boost::indeterminate; - case space_before_header_value: - if (input == ' ') - { - state_ = header_value; - return boost::indeterminate; - } - return false; - case header_value: - if (input == '\r') - { - state_ = expecting_newline_2; - return boost::indeterminate; - } - if (isCTL(input)) - { - return false; - } - header.value.push_back(input); - return boost::indeterminate; - case expecting_newline_2: - if (input == '\n') - { - state_ = header_line_start; - return boost::indeterminate; - } - return false; - default: // expecting_newline_3: - return (input == '\n'); - // default: - // return false; - } -} - -inline bool RequestParser::isChar(int character) { return character >= 0 && character <= 127; } - -inline bool RequestParser::isCTL(int character) -{ - return (character >= 0 && character <= 31) || (character == 127); -} - -inline bool RequestParser::isTSpecial(int character) -{ - switch (character) - { - case '(': - case ')': - case '<': - case '>': - case '@': - case ',': - case ';': - case ':': - case '\\': - case '"': - case '/': - case '[': - case ']': - case '?': - case '=': - case '{': - case '}': - case ' ': - case '\t': - return true; - default: - return false; - } -} - -inline bool RequestParser::isDigit(int character) { return character >= '0' && character <= '9'; } -} diff --git a/3party/osrm/osrm-backend/Tools/components.cpp b/3party/osrm/osrm-backend/Tools/components.cpp deleted file mode 100644 index b60077bd0d..0000000000 --- a/3party/osrm/osrm-backend/Tools/components.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "../typedefs.h" -#include "../Algorithms/StronglyConnectedComponents.h" -#include "../Util/GraphLoader.h" -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" -#include "../Util/FingerPrint.h" - -#include -#include -#include -#include - -std::vector coordinate_list; -std::vector restrictions_vector; -std::vector bollard_ID_list; -std::vector trafficlight_ID_list; - -int main(int argc, char *argv[]) -{ - LogPolicy::GetInstance().Unmute(); - try - { - // enable logging - if (argc < 3) - { - SimpleLogger().Write(logWARNING) << "usage:\n" << argv[0] - << " "; - return -1; - } - - SimpleLogger().Write() << "Using restrictions from file: " << argv[2]; - std::ifstream restriction_ifstream(argv[2], std::ios::binary); - const FingerPrint fingerprint_orig; - FingerPrint fingerprint_loaded; - restriction_ifstream.read((char *)&fingerprint_loaded, sizeof(FingerPrint)); - - // check fingerprint and warn if necessary - if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig)) - { - SimpleLogger().Write(logWARNING) << argv[2] << " was prepared with a different build. " - "Reprocess to get rid of this warning."; - } - - if (!restriction_ifstream.good()) - { - throw OSRMException("Could not access files"); - } - uint32_t usable_restrictions = 0; - restriction_ifstream.read((char *)&usable_restrictions, sizeof(uint32_t)); - restrictions_vector.resize(usable_restrictions); - - // load restrictions - if (usable_restrictions > 0) - { - restriction_ifstream.read((char *)&(restrictions_vector[0]), - usable_restrictions * sizeof(TurnRestriction)); - } - restriction_ifstream.close(); - - std::ifstream input_stream(argv[1], std::ifstream::in | std::ifstream::binary); - if (!input_stream.is_open()) - { - throw OSRMException("Cannot open osrm file"); - } - - // load graph data - std::vector edge_list; - const NodeID number_of_nodes = readBinaryOSRMGraphFromStream(input_stream, - edge_list, - bollard_ID_list, - trafficlight_ID_list, - &coordinate_list, - restrictions_vector); - input_stream.close(); - - BOOST_ASSERT_MSG(restrictions_vector.size() == usable_restrictions, - "size of restrictions_vector changed"); - - SimpleLogger().Write() << restrictions_vector.size() << " restrictions, " - << bollard_ID_list.size() << " bollard nodes, " - << trafficlight_ID_list.size() << " traffic lights"; - - // Building an edge-expanded graph from node-based input an turn - // restrictions - SimpleLogger().Write() << "Starting SCC graph traversal"; - std::shared_ptr tarjan = std::make_shared(number_of_nodes, - edge_list, - bollard_ID_list, - trafficlight_ID_list, - restrictions_vector, - coordinate_list); - edge_list.clear(); - edge_list.shrink_to_fit(); - - tarjan->Run(); - SimpleLogger().Write() << "finished component analysis"; - } - catch (const std::exception &e) - { - SimpleLogger().Write(logWARNING) << "[exception] " << e.what(); - } - return 0; -} diff --git a/3party/osrm/osrm-backend/UnitTests/datastructure_tests.cpp b/3party/osrm/osrm-backend/UnitTests/datastructure_tests.cpp deleted file mode 100644 index d451a91c7a..0000000000 --- a/3party/osrm/osrm-backend/UnitTests/datastructure_tests.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#define BOOST_TEST_MODULE datastructure tests - -#include - -/* - * This file will contain an automatically generated main function. - */ diff --git a/3party/osrm/osrm-backend/Util/GraphLoader.h b/3party/osrm/osrm-backend/Util/GraphLoader.h deleted file mode 100644 index f1a43af1c4..0000000000 --- a/3party/osrm/osrm-backend/Util/GraphLoader.h +++ /dev/null @@ -1,429 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef GRAPHLOADER_H -#define GRAPHLOADER_H - -#include "OSRMException.h" -#include "../DataStructures/ImportNode.h" -#include "../DataStructures/ImportEdge.h" -#include "../DataStructures/QueryNode.h" -#include "../DataStructures/Restriction.h" -#include "../Util/simple_logger.hpp" -#include "../Util/FingerPrint.h" -#include "../typedefs.h" - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -template -NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream, - std::vector &edge_list, - std::vector &barrier_node_list, - std::vector &traffic_light_node_list, - std::vector *int_to_ext_node_id_map, - std::vector &restriction_list) -{ - const FingerPrint fingerprint_orig; - FingerPrint fingerprint_loaded; - input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint)); - - if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig)) - { - SimpleLogger().Write(logWARNING) << ".osrm was prepared with different build.\n" - "Reprocess to get rid of this warning."; - } - - NodeID n, source, target; - EdgeID m; - short dir; // direction (0 = open, 1 = forward, 2+ = open) - std::unordered_map ext_to_int_id_map; - input_stream.read((char *)&n, sizeof(NodeID)); - SimpleLogger().Write() << "Importing n = " << n << " nodes "; - ExternalMemoryNode current_node; - for (NodeID i = 0; i < n; ++i) - { - input_stream.read((char *)¤t_node, sizeof(ExternalMemoryNode)); - int_to_ext_node_id_map->emplace_back(current_node.lat, current_node.lon, current_node.node_id); - ext_to_int_id_map.emplace(current_node.node_id, i); - if (current_node.bollard) - { - barrier_node_list.emplace_back(i); - } - if (current_node.trafficLight) - { - traffic_light_node_list.emplace_back(i); - } - } - - // tighten vector sizes - barrier_node_list.shrink_to_fit(); - traffic_light_node_list.shrink_to_fit(); - input_stream.read((char *)&m, sizeof(unsigned)); - SimpleLogger().Write() << " and " << m << " edges "; - for (TurnRestriction ¤t_restriction : restriction_list) - { - auto internal_id_iter = ext_to_int_id_map.find(current_restriction.fromNode); - if (internal_id_iter == ext_to_int_id_map.end()) - { - SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction"; - continue; - } - current_restriction.fromNode = internal_id_iter->second; - - internal_id_iter = ext_to_int_id_map.find(current_restriction.viaNode); - if (internal_id_iter == ext_to_int_id_map.end()) - { - SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction"; - continue; - } - current_restriction.viaNode = internal_id_iter->second; - - internal_id_iter = ext_to_int_id_map.find(current_restriction.toNode); - if (internal_id_iter == ext_to_int_id_map.end()) - { - SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction"; - continue; - } - current_restriction.toNode = internal_id_iter->second; - } - - edge_list.reserve(m); - EdgeWeight weight; - NodeID nameID; - 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)); - input_stream.read((char *)&dir, sizeof(short)); - input_stream.read((char *)&weight, sizeof(int)); - input_stream.read((char *)&nameID, sizeof(unsigned)); - input_stream.read((char *)&is_roundabout, sizeof(bool)); - input_stream.read((char *)&ignore_in_grid, sizeof(bool)); - input_stream.read((char *)&is_access_restricted, sizeof(bool)); - input_stream.read((char *)&travel_mode, sizeof(TravelMode)); - input_stream.read((char *)&is_split, sizeof(bool)); - - BOOST_ASSERT_MSG(length > 0, "loaded null length edge"); - BOOST_ASSERT_MSG(weight > 0, "loaded null weight"); - BOOST_ASSERT_MSG(0 <= dir && dir <= 2, "loaded bogus direction"); - - bool forward = true; - bool backward = true; - if (1 == dir) - { - backward = false; - } - if (2 == dir) - { - forward = false; - } - - // translate the external NodeIDs to internal IDs - auto internal_id_iter = ext_to_int_id_map.find(source); - if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end()) - { -#ifndef NDEBUG - SimpleLogger().Write(logWARNING) << " unresolved source NodeID: " << source; -#endif - continue; - } - source = internal_id_iter->second; - internal_id_iter = ext_to_int_id_map.find(target); - if (ext_to_int_id_map.find(target) == ext_to_int_id_map.end()) - { -#ifndef NDEBUG - SimpleLogger().Write(logWARNING) << "unresolved target NodeID : " << target; -#endif - continue; - } - target = internal_id_iter->second; - BOOST_ASSERT_MSG(source != UINT_MAX && target != UINT_MAX, "nonexisting source or target"); - - if (source > target) - { - std::swap(source, target); - std::swap(forward, backward); - } - - edge_list.emplace_back(way_id, - source, - target, - nameID, - weight, - forward, - backward, - is_roundabout, - ignore_in_grid, - is_access_restricted, - travel_mode, - is_split); - } - - 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) && - (edge_list[i - 1].source == edge_list[i].source)) - { - const bool edge_flags_equivalent = - (edge_list[i - 1].forward == edge_list[i].forward) && - (edge_list[i - 1].backward == edge_list[i].backward); - const bool edge_flags_are_superset1 = - (edge_list[i - 1].forward && edge_list[i - 1].backward) && - (edge_list[i].backward != edge_list[i].backward); - const bool edge_flags_are_superset_2 = - (edge_list[i].forward && edge_list[i].backward) && - (edge_list[i - 1].backward != edge_list[i - 1].backward); - - if (edge_flags_equivalent) - { - edge_list[i].weight = std::min(edge_list[i - 1].weight, edge_list[i].weight); - edge_list[i - 1].source = UINT_MAX; - } - else if (edge_flags_are_superset1) - { - if (edge_list[i - 1].weight <= edge_list[i].weight) - { - // edge i-1 is smaller and goes in both directions. Throw away the other edge - edge_list[i].source = UINT_MAX; - } - else - { - // edge i-1 is open in both directions, but edge i is smaller in one direction. - // Close edge i-1 in this direction - edge_list[i - 1].forward = !edge_list[i].forward; - edge_list[i - 1].backward = !edge_list[i].backward; - } - } - else if (edge_flags_are_superset_2) - { - if (edge_list[i - 1].weight <= edge_list[i].weight) - { - // edge i-1 is smaller for one direction. edge i is open in both. close edge i - // in the other direction - edge_list[i].forward = !edge_list[i - 1].forward; - edge_list[i].backward = !edge_list[i - 1].backward; - } - else - { - // edge i is smaller and goes in both direction. Throw away edge i-1 - edge_list[i - 1].source = UINT_MAX; - } - } - } - } - const auto new_end_iter = std::remove_if(edge_list.begin(), - edge_list.end(), - [](const EdgeT &edge) - { return edge.source == SPECIAL_NODEID; }); - ext_to_int_id_map.clear(); - edge_list.erase(new_end_iter, edge_list.end()); // remove excess candidates. - edge_list.shrink_to_fit(); - SimpleLogger().Write() << "Graph loaded ok and has " << edge_list.size() << " edges"; - return n; -} - -template -NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream, - std::vector &edge_list, - std::vector & coordinate_list) -{ - const FingerPrint fingerprint_orig; - FingerPrint fingerprint_loaded; - input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint)); - - if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig)) - { - SimpleLogger().Write(logWARNING) << ".osrm was prepared with different build.\n" - "Reprocess to get rid of this warning."; - } - - NodeID n, source, target; - EdgeID m; - short dir; // direction (0 = open, 1 = forward, 2+ = open) - std::unordered_map ext_to_int_id_map; - - input_stream.read((char *)&n, sizeof(NodeID)); - SimpleLogger().Write() << "Importing n = " << n << " nodes "; - ExternalMemoryNode current_node; - for (NodeID i = 0; i < n; ++i) - { - input_stream.read((char *)¤t_node, sizeof(ExternalMemoryNode)); - coordinate_list.emplace_back(current_node.lat, current_node.lon); - ext_to_int_id_map.emplace(current_node.node_id, i); - } - - input_stream.read((char *)&m, sizeof(unsigned)); - SimpleLogger().Write() << " and " << m << " edges "; - - edge_list.reserve(m); - 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)); - input_stream.read((char *)&dir, sizeof(short)); - input_stream.read((char *)&weight, sizeof(int)); - input_stream.read((char *)&nameID, sizeof(unsigned)); - input_stream.read((char *)&is_roundabout, sizeof(bool)); - input_stream.read((char *)&ignore_in_grid, sizeof(bool)); - input_stream.read((char *)&is_access_restricted, sizeof(bool)); - input_stream.read((char *)&travel_mode, sizeof(TravelMode)); - input_stream.read((char *)&is_split, sizeof(bool)); - - BOOST_ASSERT_MSG(length > 0, "loaded null length edge"); - BOOST_ASSERT_MSG(weight > 0, "loaded null weight"); - BOOST_ASSERT_MSG(0 <= dir && dir <= 2, "loaded bogus direction"); - - // translate the external NodeIDs to internal IDs - auto internal_id_iter = ext_to_int_id_map.find(source); - if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end()) - { -#ifndef NDEBUG - SimpleLogger().Write(logWARNING) << " unresolved source NodeID: " << source; -#endif - continue; - } - source = internal_id_iter->second; - internal_id_iter = ext_to_int_id_map.find(target); - if (ext_to_int_id_map.find(target) == ext_to_int_id_map.end()) - { -#ifndef NDEBUG - SimpleLogger().Write(logWARNING) << "unresolved target NodeID : " << target; -#endif - continue; - } - target = internal_id_iter->second; - BOOST_ASSERT_MSG(source != UINT_MAX && target != UINT_MAX, "nonexisting source or target"); - - if (source > target) - { - std::swap(source, target); - } - - edge_list.emplace_back(source, - target); - } - - 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) && - (edge_list[i - 1].source == edge_list[i].source)) - { - edge_list[i].distance = std::min(edge_list[i - 1].distance, edge_list[i].distance); - edge_list[i - 1].source = UINT_MAX; - } - } - const auto new_end_iter = std::remove_if(edge_list.begin(), - edge_list.end(), - [](const EdgeT &edge) - { return edge.source == SPECIAL_NODEID; }); - ext_to_int_id_map.clear(); - edge_list.erase(new_end_iter, edge_list.end()); // remove excess candidates. - edge_list.shrink_to_fit(); - SimpleLogger().Write() << "Graph loaded ok and has " << n << " nodes and " << edge_list.size() << " edges"; - return n; -} - - -template -unsigned readHSGRFromStream(const boost::filesystem::path &hsgr_file, - std::vector &node_list, - std::vector &edge_list, - unsigned *check_sum) -{ - if (!boost::filesystem::exists(hsgr_file)) - { - throw OSRMException("hsgr file does not exist"); - } - if (0 == boost::filesystem::file_size(hsgr_file)) - { - throw OSRMException("hsgr file is empty"); - } - - boost::filesystem::ifstream hsgr_input_stream(hsgr_file, std::ios::binary); - - FingerPrint fingerprint_loaded, fingerprint_orig; - hsgr_input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint)); - if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig)) - { - SimpleLogger().Write(logWARNING) << ".hsgr was prepared with different build.\n" - "Reprocess to get rid of this warning."; - } - - unsigned number_of_nodes = 0; - unsigned number_of_edges = 0; - hsgr_input_stream.read((char *)check_sum, sizeof(unsigned)); - hsgr_input_stream.read((char *)&number_of_nodes, sizeof(unsigned)); - BOOST_ASSERT_MSG(0 != number_of_nodes, "number of nodes is zero"); - hsgr_input_stream.read((char *)&number_of_edges, sizeof(unsigned)); - - SimpleLogger().Write() << "number_of_nodes: " << number_of_nodes - << ", number_of_edges: " << number_of_edges; - - // BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero"); - node_list.resize(number_of_nodes); - hsgr_input_stream.read((char *)&(node_list[0]), number_of_nodes * sizeof(NodeT)); - - edge_list.resize(number_of_edges); - if (number_of_edges > 0) - { - hsgr_input_stream.read((char *)&(edge_list[0]), number_of_edges * sizeof(EdgeT)); - } - hsgr_input_stream.close(); - - return number_of_nodes; -} - -#endif // GRAPHLOADER_H diff --git a/3party/osrm/osrm-backend/Util/TimingUtil.h b/3party/osrm/osrm-backend/Util/TimingUtil.h deleted file mode 100644 index c1505cebfe..0000000000 --- a/3party/osrm/osrm-backend/Util/TimingUtil.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef TIMINGUTIL_H -#define TIMINGUTIL_H - -#include - -#define TIMER_START(_X) auto _X##_start = std::chrono::steady_clock::now(), _X##_stop = _X##_start -#define TIMER_STOP(_X) _X##_stop = std::chrono::steady_clock::now() -#define TIMER_MSEC(_X) std::chrono::duration_cast(_X##_stop - _X##_start).count() -#define TIMER_SEC(_X) (0.001*std::chrono::duration_cast(_X##_stop - _X##_start).count()) -#define TIMER_MIN(_X) std::chrono::duration_cast(_X##_stop - _X##_start).count() - -#endif // TIMINGUTIL_H diff --git a/3party/osrm/osrm-backend/Util/TrigonometryTables.h b/3party/osrm/osrm-backend/Util/TrigonometryTables.h deleted file mode 100644 index 64076a23c3..0000000000 --- a/3party/osrm/osrm-backend/Util/TrigonometryTables.h +++ /dev/null @@ -1,790 +0,0 @@ -/* - -Copyright (c) 2013, Project OSRM, Dennis Luxen, others -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list -of conditions and the following disclaimer. -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef TRIGONOMETRY_TABLES_H -#define TRIGONOMETRY_TABLES_H - -#include "../typedefs.h" -#include - -#include - -constexpr unsigned short atan_table[4096] = { -0x0000, 0x0014, 0x0028, 0x003d, 0x0051, 0x0065, -0x007a, 0x008e, 0x00a3, 0x00b7, 0x00cb, 0x00e0, -0x00f4, 0x0108, 0x011d, 0x0131, 0x0146, 0x015a, -0x016e, 0x0183, 0x0197, 0x01ab, 0x01c0, 0x01d4, -0x01e9, 0x01fd, 0x0211, 0x0226, 0x023a, 0x024e, -0x0263, 0x0277, 0x028c, 0x02a0, 0x02b4, 0x02c9, -0x02dd, 0x02f1, 0x0306, 0x031a, 0x032f, 0x0343, -0x0357, 0x036c, 0x0380, 0x0394, 0x03a9, 0x03bd, -0x03d2, 0x03e6, 0x03fa, 0x040f, 0x0423, 0x0437, -0x044c, 0x0460, 0x0475, 0x0489, 0x049d, 0x04b2, -0x04c6, 0x04da, 0x04ef, 0x0503, 0x0517, 0x052c, -0x0540, 0x0555, 0x0569, 0x057d, 0x0592, 0x05a6, -0x05ba, 0x05cf, 0x05e3, 0x05f8, 0x060c, 0x0620, -0x0635, 0x0649, 0x065d, 0x0672, 0x0686, 0x069b, -0x06af, 0x06c3, 0x06d8, 0x06ec, 0x0700, 0x0715, -0x0729, 0x073d, 0x0752, 0x0766, 0x077b, 0x078f, -0x07a3, 0x07b8, 0x07cc, 0x07e0, 0x07f5, 0x0809, -0x081d, 0x0832, 0x0846, 0x085b, 0x086f, 0x0883, -0x0898, 0x08ac, 0x08c0, 0x08d5, 0x08e9, 0x08fd, -0x0912, 0x0926, 0x093b, 0x094f, 0x0963, 0x0978, -0x098c, 0x09a0, 0x09b5, 0x09c9, 0x09dd, 0x09f2, -0x0a06, 0x0a1a, 0x0a2f, 0x0a43, 0x0a58, 0x0a6c, -0x0a80, 0x0a95, 0x0aa9, 0x0abd, 0x0ad2, 0x0ae6, -0x0afa, 0x0b0f, 0x0b23, 0x0b37, 0x0b4c, 0x0b60, -0x0b75, 0x0b89, 0x0b9d, 0x0bb2, 0x0bc6, 0x0bda, -0x0bef, 0x0c03, 0x0c17, 0x0c2c, 0x0c40, 0x0c54, -0x0c69, 0x0c7d, 0x0c91, 0x0ca6, 0x0cba, 0x0cce, -0x0ce3, 0x0cf7, 0x0d0b, 0x0d20, 0x0d34, 0x0d48, -0x0d5d, 0x0d71, 0x0d86, 0x0d9a, 0x0dae, 0x0dc3, -0x0dd7, 0x0deb, 0x0e00, 0x0e14, 0x0e28, 0x0e3d, -0x0e51, 0x0e65, 0x0e7a, 0x0e8e, 0x0ea2, 0x0eb7, -0x0ecb, 0x0edf, 0x0ef4, 0x0f08, 0x0f1c, 0x0f31, -0x0f45, 0x0f59, 0x0f6e, 0x0f82, 0x0f96, 0x0fab, -0x0fbf, 0x0fd3, 0x0fe8, 0x0ffc, 0x1010, 0x1025, -0x1039, 0x104d, 0x1062, 0x1076, 0x108a, 0x109e, -0x10b3, 0x10c7, 0x10db, 0x10f0, 0x1104, 0x1118, -0x112d, 0x1141, 0x1155, 0x116a, 0x117e, 0x1192, -0x11a7, 0x11bb, 0x11cf, 0x11e4, 0x11f8, 0x120c, -0x1221, 0x1235, 0x1249, 0x125d, 0x1272, 0x1286, -0x129a, 0x12af, 0x12c3, 0x12d7, 0x12ec, 0x1300, -0x1314, 0x1329, 0x133d, 0x1351, 0x1365, 0x137a, -0x138e, 0x13a2, 0x13b7, 0x13cb, 0x13df, 0x13f4, -0x1408, 0x141c, 0x1431, 0x1445, 0x1459, 0x146d, -0x1482, 0x1496, 0x14aa, 0x14bf, 0x14d3, 0x14e7, -0x14fb, 0x1510, 0x1524, 0x1538, 0x154d, 0x1561, -0x1575, 0x1589, 0x159e, 0x15b2, 0x15c6, 0x15db, -0x15ef, 0x1603, 0x1617, 0x162c, 0x1640, 0x1654, -0x1669, 0x167d, 0x1691, 0x16a5, 0x16ba, 0x16ce, -0x16e2, 0x16f7, 0x170b, 0x171f, 0x1733, 0x1748, -0x175c, 0x1770, 0x1784, 0x1799, 0x17ad, 0x17c1, -0x17d6, 0x17ea, 0x17fe, 0x1812, 0x1827, 0x183b, -0x184f, 0x1863, 0x1878, 0x188c, 0x18a0, 0x18b4, -0x18c9, 0x18dd, 0x18f1, 0x1905, 0x191a, 0x192e, -0x1942, 0x1957, 0x196b, 0x197f, 0x1993, 0x19a8, -0x19bc, 0x19d0, 0x19e4, 0x19f9, 0x1a0d, 0x1a21, -0x1a35, 0x1a49, 0x1a5e, 0x1a72, 0x1a86, 0x1a9a, -0x1aaf, 0x1ac3, 0x1ad7, 0x1aeb, 0x1b00, 0x1b14, -0x1b28, 0x1b3c, 0x1b51, 0x1b65, 0x1b79, 0x1b8d, -0x1ba2, 0x1bb6, 0x1bca, 0x1bde, 0x1bf2, 0x1c07, -0x1c1b, 0x1c2f, 0x1c43, 0x1c58, 0x1c6c, 0x1c80, -0x1c94, 0x1ca8, 0x1cbd, 0x1cd1, 0x1ce5, 0x1cf9, -0x1d0e, 0x1d22, 0x1d36, 0x1d4a, 0x1d5e, 0x1d73, -0x1d87, 0x1d9b, 0x1daf, 0x1dc3, 0x1dd8, 0x1dec, -0x1e00, 0x1e14, 0x1e28, 0x1e3d, 0x1e51, 0x1e65, -0x1e79, 0x1e8d, 0x1ea2, 0x1eb6, 0x1eca, 0x1ede, -0x1ef2, 0x1f07, 0x1f1b, 0x1f2f, 0x1f43, 0x1f57, -0x1f6c, 0x1f80, 0x1f94, 0x1fa8, 0x1fbc, 0x1fd1, -0x1fe5, 0x1ff9, 0x200d, 0x2021, 0x2035, 0x204a, -0x205e, 0x2072, 0x2086, 0x209a, 0x20ae, 0x20c3, -0x20d7, 0x20eb, 0x20ff, 0x2113, 0x2127, 0x213c, -0x2150, 0x2164, 0x2178, 0x218c, 0x21a0, 0x21b5, -0x21c9, 0x21dd, 0x21f1, 0x2205, 0x2219, 0x222e, -0x2242, 0x2256, 0x226a, 0x227e, 0x2292, 0x22a6, -0x22bb, 0x22cf, 0x22e3, 0x22f7, 0x230b, 0x231f, -0x2333, 0x2348, 0x235c, 0x2370, 0x2384, 0x2398, -0x23ac, 0x23c0, 0x23d5, 0x23e9, 0x23fd, 0x2411, -0x2425, 0x2439, 0x244d, 0x2461, 0x2476, 0x248a, -0x249e, 0x24b2, 0x24c6, 0x24da, 0x24ee, 0x2502, -0x2517, 0x252b, 0x253f, 0x2553, 0x2567, 0x257b, -0x258f, 0x25a3, 0x25b7, 0x25cb, 0x25e0, 0x25f4, -0x2608, 0x261c, 0x2630, 0x2644, 0x2658, 0x266c, -0x2680, 0x2694, 0x26a9, 0x26bd, 0x26d1, 0x26e5, -0x26f9, 0x270d, 0x2721, 0x2735, 0x2749, 0x275d, -0x2771, 0x2785, 0x279a, 0x27ae, 0x27c2, 0x27d6, -0x27ea, 0x27fe, 0x2812, 0x2826, 0x283a, 0x284e, -0x2862, 0x2876, 0x288a, 0x289e, 0x28b3, 0x28c7, -0x28db, 0x28ef, 0x2903, 0x2917, 0x292b, 0x293f, -0x2953, 0x2967, 0x297b, 0x298f, 0x29a3, 0x29b7, -0x29cb, 0x29df, 0x29f3, 0x2a07, 0x2a1b, 0x2a2f, -0x2a43, 0x2a58, 0x2a6c, 0x2a80, 0x2a94, 0x2aa8, -0x2abc, 0x2ad0, 0x2ae4, 0x2af8, 0x2b0c, 0x2b20, -0x2b34, 0x2b48, 0x2b5c, 0x2b70, 0x2b84, 0x2b98, -0x2bac, 0x2bc0, 0x2bd4, 0x2be8, 0x2bfc, 0x2c10, -0x2c24, 0x2c38, 0x2c4c, 0x2c60, 0x2c74, 0x2c88, -0x2c9c, 0x2cb0, 0x2cc4, 0x2cd8, 0x2cec, 0x2d00, -0x2d14, 0x2d28, 0x2d3c, 0x2d50, 0x2d64, 0x2d78, -0x2d8c, 0x2da0, 0x2db4, 0x2dc8, 0x2ddc, 0x2df0, -0x2e04, 0x2e18, 0x2e2c, 0x2e40, 0x2e54, 0x2e68, -0x2e7c, 0x2e90, 0x2ea3, 0x2eb7, 0x2ecb, 0x2edf, -0x2ef3, 0x2f07, 0x2f1b, 0x2f2f, 0x2f43, 0x2f57, -0x2f6b, 0x2f7f, 0x2f93, 0x2fa7, 0x2fbb, 0x2fcf, -0x2fe3, 0x2ff7, 0x300b, 0x301e, 0x3032, 0x3046, -0x305a, 0x306e, 0x3082, 0x3096, 0x30aa, 0x30be, -0x30d2, 0x30e6, 0x30fa, 0x310e, 0x3122, 0x3135, -0x3149, 0x315d, 0x3171, 0x3185, 0x3199, 0x31ad, -0x31c1, 0x31d5, 0x31e9, 0x31fd, 0x3210, 0x3224, -0x3238, 0x324c, 0x3260, 0x3274, 0x3288, 0x329c, -0x32b0, 0x32c3, 0x32d7, 0x32eb, 0x32ff, 0x3313, -0x3327, 0x333b, 0x334f, 0x3363, 0x3376, 0x338a, -0x339e, 0x33b2, 0x33c6, 0x33da, 0x33ee, 0x3401, -0x3415, 0x3429, 0x343d, 0x3451, 0x3465, 0x3479, -0x348c, 0x34a0, 0x34b4, 0x34c8, 0x34dc, 0x34f0, -0x3504, 0x3517, 0x352b, 0x353f, 0x3553, 0x3567, -0x357b, 0x358e, 0x35a2, 0x35b6, 0x35ca, 0x35de, -0x35f2, 0x3605, 0x3619, 0x362d, 0x3641, 0x3655, -0x3668, 0x367c, 0x3690, 0x36a4, 0x36b8, 0x36cb, -0x36df, 0x36f3, 0x3707, 0x371b, 0x372f, 0x3742, -0x3756, 0x376a, 0x377e, 0x3791, 0x37a5, 0x37b9, -0x37cd, 0x37e1, 0x37f4, 0x3808, 0x381c, 0x3830, -0x3844, 0x3857, 0x386b, 0x387f, 0x3893, 0x38a6, -0x38ba, 0x38ce, 0x38e2, 0x38f5, 0x3909, 0x391d, -0x3931, 0x3944, 0x3958, 0x396c, 0x3980, 0x3993, -0x39a7, 0x39bb, 0x39cf, 0x39e2, 0x39f6, 0x3a0a, -0x3a1e, 0x3a31, 0x3a45, 0x3a59, 0x3a6d, 0x3a80, -0x3a94, 0x3aa8, 0x3abb, 0x3acf, 0x3ae3, 0x3af7, -0x3b0a, 0x3b1e, 0x3b32, 0x3b45, 0x3b59, 0x3b6d, -0x3b81, 0x3b94, 0x3ba8, 0x3bbc, 0x3bcf, 0x3be3, -0x3bf7, 0x3c0b, 0x3c1e, 0x3c32, 0x3c46, 0x3c59, -0x3c6d, 0x3c81, 0x3c94, 0x3ca8, 0x3cbc, 0x3ccf, -0x3ce3, 0x3cf7, 0x3d0a, 0x3d1e, 0x3d32, 0x3d45, -0x3d59, 0x3d6d, 0x3d80, 0x3d94, 0x3da8, 0x3dbb, -0x3dcf, 0x3de3, 0x3df6, 0x3e0a, 0x3e1e, 0x3e31, -0x3e45, 0x3e59, 0x3e6c, 0x3e80, 0x3e93, 0x3ea7, -0x3ebb, 0x3ece, 0x3ee2, 0x3ef6, 0x3f09, 0x3f1d, -0x3f30, 0x3f44, 0x3f58, 0x3f6b, 0x3f7f, 0x3f93, -0x3fa6, 0x3fba, 0x3fcd, 0x3fe1, 0x3ff5, 0x4008, -0x401c, 0x402f, 0x4043, 0x4057, 0x406a, 0x407e, -0x4091, 0x40a5, 0x40b8, 0x40cc, 0x40e0, 0x40f3, -0x4107, 0x411a, 0x412e, 0x4142, 0x4155, 0x4169, -0x417c, 0x4190, 0x41a3, 0x41b7, 0x41ca, 0x41de, -0x41f2, 0x4205, 0x4219, 0x422c, 0x4240, 0x4253, -0x4267, 0x427a, 0x428e, 0x42a1, 0x42b5, 0x42c9, -0x42dc, 0x42f0, 0x4303, 0x4317, 0x432a, 0x433e, -0x4351, 0x4365, 0x4378, 0x438c, 0x439f, 0x43b3, -0x43c6, 0x43da, 0x43ed, 0x4401, 0x4414, 0x4428, -0x443b, 0x444f, 0x4462, 0x4476, 0x4489, 0x449d, -0x44b0, 0x44c4, 0x44d7, 0x44eb, 0x44fe, 0x4512, -0x4525, 0x4539, 0x454c, 0x4560, 0x4573, 0x4586, -0x459a, 0x45ad, 0x45c1, 0x45d4, 0x45e8, 0x45fb, -0x460f, 0x4622, 0x4636, 0x4649, 0x465c, 0x4670, -0x4683, 0x4697, 0x46aa, 0x46be, 0x46d1, 0x46e5, -0x46f8, 0x470b, 0x471f, 0x4732, 0x4746, 0x4759, -0x476c, 0x4780, 0x4793, 0x47a7, 0x47ba, 0x47cd, -0x47e1, 0x47f4, 0x4808, 0x481b, 0x482e, 0x4842, -0x4855, 0x4869, 0x487c, 0x488f, 0x48a3, 0x48b6, -0x48ca, 0x48dd, 0x48f0, 0x4904, 0x4917, 0x492a, -0x493e, 0x4951, 0x4965, 0x4978, 0x498b, 0x499f, -0x49b2, 0x49c5, 0x49d9, 0x49ec, 0x49ff, 0x4a13, -0x4a26, 0x4a39, 0x4a4d, 0x4a60, 0x4a73, 0x4a87, -0x4a9a, 0x4aad, 0x4ac1, 0x4ad4, 0x4ae7, 0x4afb, -0x4b0e, 0x4b21, 0x4b35, 0x4b48, 0x4b5b, 0x4b6f, -0x4b82, 0x4b95, 0x4ba8, 0x4bbc, 0x4bcf, 0x4be2, -0x4bf6, 0x4c09, 0x4c1c, 0x4c2f, 0x4c43, 0x4c56, -0x4c69, 0x4c7d, 0x4c90, 0x4ca3, 0x4cb6, 0x4cca, -0x4cdd, 0x4cf0, 0x4d03, 0x4d17, 0x4d2a, 0x4d3d, -0x4d50, 0x4d64, 0x4d77, 0x4d8a, 0x4d9d, 0x4db1, -0x4dc4, 0x4dd7, 0x4dea, 0x4dfe, 0x4e11, 0x4e24, -0x4e37, 0x4e4b, 0x4e5e, 0x4e71, 0x4e84, 0x4e97, -0x4eab, 0x4ebe, 0x4ed1, 0x4ee4, 0x4ef7, 0x4f0b, -0x4f1e, 0x4f31, 0x4f44, 0x4f57, 0x4f6b, 0x4f7e, -0x4f91, 0x4fa4, 0x4fb7, 0x4fcb, 0x4fde, 0x4ff1, -0x5004, 0x5017, 0x502a, 0x503e, 0x5051, 0x5064, -0x5077, 0x508a, 0x509d, 0x50b1, 0x50c4, 0x50d7, -0x50ea, 0x50fd, 0x5110, 0x5123, 0x5137, 0x514a, -0x515d, 0x5170, 0x5183, 0x5196, 0x51a9, 0x51bc, -0x51d0, 0x51e3, 0x51f6, 0x5209, 0x521c, 0x522f, -0x5242, 0x5255, 0x5268, 0x527c, 0x528f, 0x52a2, -0x52b5, 0x52c8, 0x52db, 0x52ee, 0x5301, 0x5314, -0x5327, 0x533a, 0x534e, 0x5361, 0x5374, 0x5387, -0x539a, 0x53ad, 0x53c0, 0x53d3, 0x53e6, 0x53f9, -0x540c, 0x541f, 0x5432, 0x5445, 0x5458, 0x546b, -0x547e, 0x5491, 0x54a5, 0x54b8, 0x54cb, 0x54de, -0x54f1, 0x5504, 0x5517, 0x552a, 0x553d, 0x5550, -0x5563, 0x5576, 0x5589, 0x559c, 0x55af, 0x55c2, -0x55d5, 0x55e8, 0x55fb, 0x560e, 0x5621, 0x5634, -0x5647, 0x565a, 0x566d, 0x5680, 0x5693, 0x56a6, -0x56b9, 0x56cb, 0x56de, 0x56f1, 0x5704, 0x5717, -0x572a, 0x573d, 0x5750, 0x5763, 0x5776, 0x5789, -0x579c, 0x57af, 0x57c2, 0x57d5, 0x57e8, 0x57fb, -0x580e, 0x5820, 0x5833, 0x5846, 0x5859, 0x586c, -0x587f, 0x5892, 0x58a5, 0x58b8, 0x58cb, 0x58de, -0x58f0, 0x5903, 0x5916, 0x5929, 0x593c, 0x594f, -0x5962, 0x5975, 0x5988, 0x599a, 0x59ad, 0x59c0, -0x59d3, 0x59e6, 0x59f9, 0x5a0c, 0x5a1f, 0x5a31, -0x5a44, 0x5a57, 0x5a6a, 0x5a7d, 0x5a90, 0x5aa2, -0x5ab5, 0x5ac8, 0x5adb, 0x5aee, 0x5b01, 0x5b13, -0x5b26, 0x5b39, 0x5b4c, 0x5b5f, 0x5b72, 0x5b84, -0x5b97, 0x5baa, 0x5bbd, 0x5bd0, 0x5be2, 0x5bf5, -0x5c08, 0x5c1b, 0x5c2e, 0x5c40, 0x5c53, 0x5c66, -0x5c79, 0x5c8c, 0x5c9e, 0x5cb1, 0x5cc4, 0x5cd7, -0x5ce9, 0x5cfc, 0x5d0f, 0x5d22, 0x5d34, 0x5d47, -0x5d5a, 0x5d6d, 0x5d7f, 0x5d92, 0x5da5, 0x5db8, -0x5dca, 0x5ddd, 0x5df0, 0x5e03, 0x5e15, 0x5e28, -0x5e3b, 0x5e4d, 0x5e60, 0x5e73, 0x5e86, 0x5e98, -0x5eab, 0x5ebe, 0x5ed0, 0x5ee3, 0x5ef6, 0x5f09, -0x5f1b, 0x5f2e, 0x5f41, 0x5f53, 0x5f66, 0x5f79, -0x5f8b, 0x5f9e, 0x5fb1, 0x5fc3, 0x5fd6, 0x5fe9, -0x5ffb, 0x600e, 0x6021, 0x6033, 0x6046, 0x6059, -0x606b, 0x607e, 0x6091, 0x60a3, 0x60b6, 0x60c8, -0x60db, 0x60ee, 0x6100, 0x6113, 0x6126, 0x6138, -0x614b, 0x615d, 0x6170, 0x6183, 0x6195, 0x61a8, -0x61ba, 0x61cd, 0x61e0, 0x61f2, 0x6205, 0x6217, -0x622a, 0x623d, 0x624f, 0x6262, 0x6274, 0x6287, -0x6299, 0x62ac, 0x62bf, 0x62d1, 0x62e4, 0x62f6, -0x6309, 0x631b, 0x632e, 0x6340, 0x6353, 0x6366, -0x6378, 0x638b, 0x639d, 0x63b0, 0x63c2, 0x63d5, -0x63e7, 0x63fa, 0x640c, 0x641f, 0x6431, 0x6444, -0x6456, 0x6469, 0x647b, 0x648e, 0x64a0, 0x64b3, -0x64c5, 0x64d8, 0x64ea, 0x64fd, 0x650f, 0x6522, -0x6534, 0x6547, 0x6559, 0x656c, 0x657e, 0x6591, -0x65a3, 0x65b5, 0x65c8, 0x65da, 0x65ed, 0x65ff, -0x6612, 0x6624, 0x6637, 0x6649, 0x665b, 0x666e, -0x6680, 0x6693, 0x66a5, 0x66b8, 0x66ca, 0x66dc, -0x66ef, 0x6701, 0x6714, 0x6726, 0x6738, 0x674b, -0x675d, 0x6770, 0x6782, 0x6794, 0x67a7, 0x67b9, -0x67cc, 0x67de, 0x67f0, 0x6803, 0x6815, 0x6827, -0x683a, 0x684c, 0x685e, 0x6871, 0x6883, 0x6896, -0x68a8, 0x68ba, 0x68cd, 0x68df, 0x68f1, 0x6904, -0x6916, 0x6928, 0x693b, 0x694d, 0x695f, 0x6972, -0x6984, 0x6996, 0x69a8, 0x69bb, 0x69cd, 0x69df, -0x69f2, 0x6a04, 0x6a16, 0x6a29, 0x6a3b, 0x6a4d, -0x6a5f, 0x6a72, 0x6a84, 0x6a96, 0x6aa9, 0x6abb, -0x6acd, 0x6adf, 0x6af2, 0x6b04, 0x6b16, 0x6b28, -0x6b3b, 0x6b4d, 0x6b5f, 0x6b71, 0x6b84, 0x6b96, -0x6ba8, 0x6bba, 0x6bcd, 0x6bdf, 0x6bf1, 0x6c03, -0x6c15, 0x6c28, 0x6c3a, 0x6c4c, 0x6c5e, 0x6c70, -0x6c83, 0x6c95, 0x6ca7, 0x6cb9, 0x6ccb, 0x6cde, -0x6cf0, 0x6d02, 0x6d14, 0x6d26, 0x6d39, 0x6d4b, -0x6d5d, 0x6d6f, 0x6d81, 0x6d93, 0x6da6, 0x6db8, -0x6dca, 0x6ddc, 0x6dee, 0x6e00, 0x6e12, 0x6e25, -0x6e37, 0x6e49, 0x6e5b, 0x6e6d, 0x6e7f, 0x6e91, -0x6ea3, 0x6eb6, 0x6ec8, 0x6eda, 0x6eec, 0x6efe, -0x6f10, 0x6f22, 0x6f34, 0x6f46, 0x6f58, 0x6f6b, -0x6f7d, 0x6f8f, 0x6fa1, 0x6fb3, 0x6fc5, 0x6fd7, -0x6fe9, 0x6ffb, 0x700d, 0x701f, 0x7031, 0x7043, -0x7055, 0x7068, 0x707a, 0x708c, 0x709e, 0x70b0, -0x70c2, 0x70d4, 0x70e6, 0x70f8, 0x710a, 0x711c, -0x712e, 0x7140, 0x7152, 0x7164, 0x7176, 0x7188, -0x719a, 0x71ac, 0x71be, 0x71d0, 0x71e2, 0x71f4, -0x7206, 0x7218, 0x722a, 0x723c, 0x724e, 0x7260, -0x7272, 0x7284, 0x7296, 0x72a8, 0x72ba, 0x72cc, -0x72dd, 0x72ef, 0x7301, 0x7313, 0x7325, 0x7337, -0x7349, 0x735b, 0x736d, 0x737f, 0x7391, 0x73a3, -0x73b5, 0x73c7, 0x73d8, 0x73ea, 0x73fc, 0x740e, -0x7420, 0x7432, 0x7444, 0x7456, 0x7468, 0x747a, -0x748b, 0x749d, 0x74af, 0x74c1, 0x74d3, 0x74e5, -0x74f7, 0x7509, 0x751a, 0x752c, 0x753e, 0x7550, -0x7562, 0x7574, 0x7585, 0x7597, 0x75a9, 0x75bb, -0x75cd, 0x75df, 0x75f0, 0x7602, 0x7614, 0x7626, -0x7638, 0x764a, 0x765b, 0x766d, 0x767f, 0x7691, -0x76a3, 0x76b4, 0x76c6, 0x76d8, 0x76ea, 0x76fb, -0x770d, 0x771f, 0x7731, 0x7743, 0x7754, 0x7766, -0x7778, 0x778a, 0x779b, 0x77ad, 0x77bf, 0x77d1, -0x77e2, 0x77f4, 0x7806, 0x7818, 0x7829, 0x783b, -0x784d, 0x785e, 0x7870, 0x7882, 0x7894, 0x78a5, -0x78b7, 0x78c9, 0x78da, 0x78ec, 0x78fe, 0x7910, -0x7921, 0x7933, 0x7945, 0x7956, 0x7968, 0x797a, -0x798b, 0x799d, 0x79af, 0x79c0, 0x79d2, 0x79e4, -0x79f5, 0x7a07, 0x7a19, 0x7a2a, 0x7a3c, 0x7a4e, -0x7a5f, 0x7a71, 0x7a82, 0x7a94, 0x7aa6, 0x7ab7, -0x7ac9, 0x7adb, 0x7aec, 0x7afe, 0x7b0f, 0x7b21, -0x7b33, 0x7b44, 0x7b56, 0x7b67, 0x7b79, 0x7b8b, -0x7b9c, 0x7bae, 0x7bbf, 0x7bd1, 0x7be2, 0x7bf4, -0x7c06, 0x7c17, 0x7c29, 0x7c3a, 0x7c4c, 0x7c5d, -0x7c6f, 0x7c81, 0x7c92, 0x7ca4, 0x7cb5, 0x7cc7, -0x7cd8, 0x7cea, 0x7cfb, 0x7d0d, 0x7d1e, 0x7d30, -0x7d41, 0x7d53, 0x7d64, 0x7d76, 0x7d87, 0x7d99, -0x7daa, 0x7dbc, 0x7dcd, 0x7ddf, 0x7df0, 0x7e02, -0x7e13, 0x7e25, 0x7e36, 0x7e48, 0x7e59, 0x7e6b, -0x7e7c, 0x7e8e, 0x7e9f, 0x7eb0, 0x7ec2, 0x7ed3, -0x7ee5, 0x7ef6, 0x7f08, 0x7f19, 0x7f2b, 0x7f3c, -0x7f4d, 0x7f5f, 0x7f70, 0x7f82, 0x7f93, 0x7fa4, -0x7fb6, 0x7fc7, 0x7fd9, 0x7fea, 0x7ffb, 0x800d, -0x801e, 0x8030, 0x8041, 0x8052, 0x8064, 0x8075, -0x8086, 0x8098, 0x80a9, 0x80bb, 0x80cc, 0x80dd, -0x80ef, 0x8100, 0x8111, 0x8123, 0x8134, 0x8145, -0x8157, 0x8168, 0x8179, 0x818b, 0x819c, 0x81ad, -0x81bf, 0x81d0, 0x81e1, 0x81f3, 0x8204, 0x8215, -0x8226, 0x8238, 0x8249, 0x825a, 0x826c, 0x827d, -0x828e, 0x829f, 0x82b1, 0x82c2, 0x82d3, 0x82e5, -0x82f6, 0x8307, 0x8318, 0x832a, 0x833b, 0x834c, -0x835d, 0x836f, 0x8380, 0x8391, 0x83a2, 0x83b3, -0x83c5, 0x83d6, 0x83e7, 0x83f8, 0x840a, 0x841b, -0x842c, 0x843d, 0x844e, 0x8460, 0x8471, 0x8482, -0x8493, 0x84a4, 0x84b6, 0x84c7, 0x84d8, 0x84e9, -0x84fa, 0x850b, 0x851d, 0x852e, 0x853f, 0x8550, -0x8561, 0x8572, 0x8584, 0x8595, 0x85a6, 0x85b7, -0x85c8, 0x85d9, 0x85ea, 0x85fb, 0x860d, 0x861e, -0x862f, 0x8640, 0x8651, 0x8662, 0x8673, 0x8684, -0x8695, 0x86a7, 0x86b8, 0x86c9, 0x86da, 0x86eb, -0x86fc, 0x870d, 0x871e, 0x872f, 0x8740, 0x8751, -0x8762, 0x8773, 0x8784, 0x8796, 0x87a7, 0x87b8, -0x87c9, 0x87da, 0x87eb, 0x87fc, 0x880d, 0x881e, -0x882f, 0x8840, 0x8851, 0x8862, 0x8873, 0x8884, -0x8895, 0x88a6, 0x88b7, 0x88c8, 0x88d9, 0x88ea, -0x88fb, 0x890c, 0x891d, 0x892e, 0x893f, 0x8950, -0x8961, 0x8972, 0x8983, 0x8994, 0x89a5, 0x89b6, -0x89c6, 0x89d7, 0x89e8, 0x89f9, 0x8a0a, 0x8a1b, -0x8a2c, 0x8a3d, 0x8a4e, 0x8a5f, 0x8a70, 0x8a81, -0x8a92, 0x8aa3, 0x8ab3, 0x8ac4, 0x8ad5, 0x8ae6, -0x8af7, 0x8b08, 0x8b19, 0x8b2a, 0x8b3b, 0x8b4b, -0x8b5c, 0x8b6d, 0x8b7e, 0x8b8f, 0x8ba0, 0x8bb1, -0x8bc1, 0x8bd2, 0x8be3, 0x8bf4, 0x8c05, 0x8c16, -0x8c27, 0x8c37, 0x8c48, 0x8c59, 0x8c6a, 0x8c7b, -0x8c8c, 0x8c9c, 0x8cad, 0x8cbe, 0x8ccf, 0x8ce0, -0x8cf0, 0x8d01, 0x8d12, 0x8d23, 0x8d34, 0x8d44, -0x8d55, 0x8d66, 0x8d77, 0x8d87, 0x8d98, 0x8da9, -0x8dba, 0x8dca, 0x8ddb, 0x8dec, 0x8dfd, 0x8e0d, -0x8e1e, 0x8e2f, 0x8e40, 0x8e50, 0x8e61, 0x8e72, -0x8e83, 0x8e93, 0x8ea4, 0x8eb5, 0x8ec5, 0x8ed6, -0x8ee7, 0x8ef8, 0x8f08, 0x8f19, 0x8f2a, 0x8f3a, -0x8f4b, 0x8f5c, 0x8f6c, 0x8f7d, 0x8f8e, 0x8f9e, -0x8faf, 0x8fc0, 0x8fd0, 0x8fe1, 0x8ff2, 0x9002, -0x9013, 0x9024, 0x9034, 0x9045, 0x9056, 0x9066, -0x9077, 0x9088, 0x9098, 0x90a9, 0x90b9, 0x90ca, -0x90db, 0x90eb, 0x90fc, 0x910c, 0x911d, 0x912e, -0x913e, 0x914f, 0x915f, 0x9170, 0x9181, 0x9191, -0x91a2, 0x91b2, 0x91c3, 0x91d3, 0x91e4, 0x91f5, -0x9205, 0x9216, 0x9226, 0x9237, 0x9247, 0x9258, -0x9268, 0x9279, 0x9289, 0x929a, 0x92aa, 0x92bb, -0x92cc, 0x92dc, 0x92ed, 0x92fd, 0x930e, 0x931e, -0x932f, 0x933f, 0x9350, 0x9360, 0x9370, 0x9381, -0x9391, 0x93a2, 0x93b2, 0x93c3, 0x93d3, 0x93e4, -0x93f4, 0x9405, 0x9415, 0x9426, 0x9436, 0x9447, -0x9457, 0x9467, 0x9478, 0x9488, 0x9499, 0x94a9, -0x94ba, 0x94ca, 0x94da, 0x94eb, 0x94fb, 0x950c, -0x951c, 0x952c, 0x953d, 0x954d, 0x955e, 0x956e, -0x957e, 0x958f, 0x959f, 0x95af, 0x95c0, 0x95d0, -0x95e1, 0x95f1, 0x9601, 0x9612, 0x9622, 0x9632, -0x9643, 0x9653, 0x9663, 0x9674, 0x9684, 0x9694, -0x96a5, 0x96b5, 0x96c5, 0x96d6, 0x96e6, 0x96f6, -0x9707, 0x9717, 0x9727, 0x9738, 0x9748, 0x9758, -0x9768, 0x9779, 0x9789, 0x9799, 0x97aa, 0x97ba, -0x97ca, 0x97da, 0x97eb, 0x97fb, 0x980b, 0x981b, -0x982c, 0x983c, 0x984c, 0x985c, 0x986d, 0x987d, -0x988d, 0x989d, 0x98ad, 0x98be, 0x98ce, 0x98de, -0x98ee, 0x98ff, 0x990f, 0x991f, 0x992f, 0x993f, -0x9950, 0x9960, 0x9970, 0x9980, 0x9990, 0x99a0, -0x99b1, 0x99c1, 0x99d1, 0x99e1, 0x99f1, 0x9a01, -0x9a12, 0x9a22, 0x9a32, 0x9a42, 0x9a52, 0x9a62, -0x9a72, 0x9a83, 0x9a93, 0x9aa3, 0x9ab3, 0x9ac3, -0x9ad3, 0x9ae3, 0x9af3, 0x9b04, 0x9b14, 0x9b24, -0x9b34, 0x9b44, 0x9b54, 0x9b64, 0x9b74, 0x9b84, -0x9b94, 0x9ba4, 0x9bb5, 0x9bc5, 0x9bd5, 0x9be5, -0x9bf5, 0x9c05, 0x9c15, 0x9c25, 0x9c35, 0x9c45, -0x9c55, 0x9c65, 0x9c75, 0x9c85, 0x9c95, 0x9ca5, -0x9cb5, 0x9cc5, 0x9cd5, 0x9ce5, 0x9cf5, 0x9d05, -0x9d15, 0x9d25, 0x9d35, 0x9d45, 0x9d55, 0x9d65, -0x9d75, 0x9d85, 0x9d95, 0x9da5, 0x9db5, 0x9dc5, -0x9dd5, 0x9de5, 0x9df5, 0x9e05, 0x9e15, 0x9e25, -0x9e35, 0x9e45, 0x9e55, 0x9e65, 0x9e74, 0x9e84, -0x9e94, 0x9ea4, 0x9eb4, 0x9ec4, 0x9ed4, 0x9ee4, -0x9ef4, 0x9f04, 0x9f14, 0x9f23, 0x9f33, 0x9f43, -0x9f53, 0x9f63, 0x9f73, 0x9f83, 0x9f93, 0x9fa3, -0x9fb2, 0x9fc2, 0x9fd2, 0x9fe2, 0x9ff2, 0xa002, -0xa012, 0xa021, 0xa031, 0xa041, 0xa051, 0xa061, -0xa071, 0xa080, 0xa090, 0xa0a0, 0xa0b0, 0xa0c0, -0xa0cf, 0xa0df, 0xa0ef, 0xa0ff, 0xa10f, 0xa11e, -0xa12e, 0xa13e, 0xa14e, 0xa15e, 0xa16d, 0xa17d, -0xa18d, 0xa19d, 0xa1ac, 0xa1bc, 0xa1cc, 0xa1dc, -0xa1eb, 0xa1fb, 0xa20b, 0xa21b, 0xa22a, 0xa23a, -0xa24a, 0xa25a, 0xa269, 0xa279, 0xa289, 0xa298, -0xa2a8, 0xa2b8, 0xa2c8, 0xa2d7, 0xa2e7, 0xa2f7, -0xa306, 0xa316, 0xa326, 0xa335, 0xa345, 0xa355, -0xa364, 0xa374, 0xa384, 0xa393, 0xa3a3, 0xa3b3, -0xa3c2, 0xa3d2, 0xa3e2, 0xa3f1, 0xa401, 0xa411, -0xa420, 0xa430, 0xa440, 0xa44f, 0xa45f, 0xa46e, -0xa47e, 0xa48e, 0xa49d, 0xa4ad, 0xa4bc, 0xa4cc, -0xa4dc, 0xa4eb, 0xa4fb, 0xa50a, 0xa51a, 0xa52a, -0xa539, 0xa549, 0xa558, 0xa568, 0xa577, 0xa587, -0xa597, 0xa5a6, 0xa5b6, 0xa5c5, 0xa5d5, 0xa5e4, -0xa5f4, 0xa603, 0xa613, 0xa622, 0xa632, 0xa641, -0xa651, 0xa660, 0xa670, 0xa67f, 0xa68f, 0xa69e, -0xa6ae, 0xa6bd, 0xa6cd, 0xa6dc, 0xa6ec, 0xa6fb, -0xa70b, 0xa71a, 0xa72a, 0xa739, 0xa749, 0xa758, -0xa768, 0xa777, 0xa787, 0xa796, 0xa7a5, 0xa7b5, -0xa7c4, 0xa7d4, 0xa7e3, 0xa7f3, 0xa802, 0xa812, -0xa821, 0xa830, 0xa840, 0xa84f, 0xa85f, 0xa86e, -0xa87d, 0xa88d, 0xa89c, 0xa8ac, 0xa8bb, 0xa8ca, -0xa8da, 0xa8e9, 0xa8f8, 0xa908, 0xa917, 0xa927, -0xa936, 0xa945, 0xa955, 0xa964, 0xa973, 0xa983, -0xa992, 0xa9a1, 0xa9b1, 0xa9c0, 0xa9cf, 0xa9df, -0xa9ee, 0xa9fd, 0xaa0d, 0xaa1c, 0xaa2b, 0xaa3b, -0xaa4a, 0xaa59, 0xaa69, 0xaa78, 0xaa87, 0xaa96, -0xaaa6, 0xaab5, 0xaac4, 0xaad4, 0xaae3, 0xaaf2, -0xab01, 0xab11, 0xab20, 0xab2f, 0xab3e, 0xab4e, -0xab5d, 0xab6c, 0xab7b, 0xab8b, 0xab9a, 0xaba9, -0xabb8, 0xabc7, 0xabd7, 0xabe6, 0xabf5, 0xac04, -0xac14, 0xac23, 0xac32, 0xac41, 0xac50, 0xac60, -0xac6f, 0xac7e, 0xac8d, 0xac9c, 0xacab, 0xacbb, -0xacca, 0xacd9, 0xace8, 0xacf7, 0xad06, 0xad16, -0xad25, 0xad34, 0xad43, 0xad52, 0xad61, 0xad70, -0xad80, 0xad8f, 0xad9e, 0xadad, 0xadbc, 0xadcb, -0xadda, 0xade9, 0xadf8, 0xae08, 0xae17, 0xae26, -0xae35, 0xae44, 0xae53, 0xae62, 0xae71, 0xae80, -0xae8f, 0xae9e, 0xaead, 0xaebd, 0xaecc, 0xaedb, -0xaeea, 0xaef9, 0xaf08, 0xaf17, 0xaf26, 0xaf35, -0xaf44, 0xaf53, 0xaf62, 0xaf71, 0xaf80, 0xaf8f, -0xaf9e, 0xafad, 0xafbc, 0xafcb, 0xafda, 0xafe9, -0xaff8, 0xb007, 0xb016, 0xb025, 0xb034, 0xb043, -0xb052, 0xb061, 0xb070, 0xb07f, 0xb08e, 0xb09d, -0xb0ac, 0xb0bb, 0xb0ca, 0xb0d9, 0xb0e8, 0xb0f6, -0xb105, 0xb114, 0xb123, 0xb132, 0xb141, 0xb150, -0xb15f, 0xb16e, 0xb17d, 0xb18c, 0xb19b, 0xb1aa, -0xb1b8, 0xb1c7, 0xb1d6, 0xb1e5, 0xb1f4, 0xb203, -0xb212, 0xb221, 0xb22f, 0xb23e, 0xb24d, 0xb25c, -0xb26b, 0xb27a, 0xb289, 0xb297, 0xb2a6, 0xb2b5, -0xb2c4, 0xb2d3, 0xb2e2, 0xb2f1, 0xb2ff, 0xb30e, -0xb31d, 0xb32c, 0xb33b, 0xb349, 0xb358, 0xb367, -0xb376, 0xb385, 0xb393, 0xb3a2, 0xb3b1, 0xb3c0, -0xb3cf, 0xb3dd, 0xb3ec, 0xb3fb, 0xb40a, 0xb418, -0xb427, 0xb436, 0xb445, 0xb453, 0xb462, 0xb471, -0xb480, 0xb48e, 0xb49d, 0xb4ac, 0xb4bb, 0xb4c9, -0xb4d8, 0xb4e7, 0xb4f6, 0xb504, 0xb513, 0xb522, -0xb530, 0xb53f, 0xb54e, 0xb55c, 0xb56b, 0xb57a, -0xb588, 0xb597, 0xb5a6, 0xb5b5, 0xb5c3, 0xb5d2, -0xb5e1, 0xb5ef, 0xb5fe, 0xb60d, 0xb61b, 0xb62a, -0xb638, 0xb647, 0xb656, 0xb664, 0xb673, 0xb682, -0xb690, 0xb69f, 0xb6ae, 0xb6bc, 0xb6cb, 0xb6d9, -0xb6e8, 0xb6f7, 0xb705, 0xb714, 0xb722, 0xb731, -0xb740, 0xb74e, 0xb75d, 0xb76b, 0xb77a, 0xb788, -0xb797, 0xb7a6, 0xb7b4, 0xb7c3, 0xb7d1, 0xb7e0, -0xb7ee, 0xb7fd, 0xb80b, 0xb81a, 0xb829, 0xb837, -0xb846, 0xb854, 0xb863, 0xb871, 0xb880, 0xb88e, -0xb89d, 0xb8ab, 0xb8ba, 0xb8c8, 0xb8d7, 0xb8e5, -0xb8f4, 0xb902, 0xb911, 0xb91f, 0xb92e, 0xb93c, -0xb94b, 0xb959, 0xb968, 0xb976, 0xb984, 0xb993, -0xb9a1, 0xb9b0, 0xb9be, 0xb9cd, 0xb9db, 0xb9ea, -0xb9f8, 0xba06, 0xba15, 0xba23, 0xba32, 0xba40, -0xba4f, 0xba5d, 0xba6b, 0xba7a, 0xba88, 0xba97, -0xbaa5, 0xbab3, 0xbac2, 0xbad0, 0xbade, 0xbaed, -0xbafb, 0xbb0a, 0xbb18, 0xbb26, 0xbb35, 0xbb43, -0xbb51, 0xbb60, 0xbb6e, 0xbb7c, 0xbb8b, 0xbb99, -0xbba8, 0xbbb6, 0xbbc4, 0xbbd3, 0xbbe1, 0xbbef, -0xbbfd, 0xbc0c, 0xbc1a, 0xbc28, 0xbc37, 0xbc45, -0xbc53, 0xbc62, 0xbc70, 0xbc7e, 0xbc8c, 0xbc9b, -0xbca9, 0xbcb7, 0xbcc6, 0xbcd4, 0xbce2, 0xbcf0, -0xbcff, 0xbd0d, 0xbd1b, 0xbd29, 0xbd38, 0xbd46, -0xbd54, 0xbd62, 0xbd71, 0xbd7f, 0xbd8d, 0xbd9b, -0xbdaa, 0xbdb8, 0xbdc6, 0xbdd4, 0xbde2, 0xbdf1, -0xbdff, 0xbe0d, 0xbe1b, 0xbe29, 0xbe38, 0xbe46, -0xbe54, 0xbe62, 0xbe70, 0xbe7f, 0xbe8d, 0xbe9b, -0xbea9, 0xbeb7, 0xbec5, 0xbed4, 0xbee2, 0xbef0, -0xbefe, 0xbf0c, 0xbf1a, 0xbf28, 0xbf37, 0xbf45, -0xbf53, 0xbf61, 0xbf6f, 0xbf7d, 0xbf8b, 0xbf99, -0xbfa7, 0xbfb6, 0xbfc4, 0xbfd2, 0xbfe0, 0xbfee, -0xbffc, 0xc00a, 0xc018, 0xc026, 0xc034, 0xc042, -0xc051, 0xc05f, 0xc06d, 0xc07b, 0xc089, 0xc097, -0xc0a5, 0xc0b3, 0xc0c1, 0xc0cf, 0xc0dd, 0xc0eb, -0xc0f9, 0xc107, 0xc115, 0xc123, 0xc131, 0xc13f, -0xc14d, 0xc15b, 0xc169, 0xc177, 0xc185, 0xc193, -0xc1a1, 0xc1af, 0xc1bd, 0xc1cb, 0xc1d9, 0xc1e7, -0xc1f5, 0xc203, 0xc211, 0xc21f, 0xc22d, 0xc23b, -0xc249, 0xc257, 0xc265, 0xc273, 0xc281, 0xc28f, -0xc29d, 0xc2ab, 0xc2b8, 0xc2c6, 0xc2d4, 0xc2e2, -0xc2f0, 0xc2fe, 0xc30c, 0xc31a, 0xc328, 0xc336, -0xc344, 0xc352, 0xc35f, 0xc36d, 0xc37b, 0xc389, -0xc397, 0xc3a5, 0xc3b3, 0xc3c1, 0xc3ce, 0xc3dc, -0xc3ea, 0xc3f8, 0xc406, 0xc414, 0xc422, 0xc42f, -0xc43d, 0xc44b, 0xc459, 0xc467, 0xc475, 0xc482, -0xc490, 0xc49e, 0xc4ac, 0xc4ba, 0xc4c7, 0xc4d5, -0xc4e3, 0xc4f1, 0xc4ff, 0xc50d, 0xc51a, 0xc528, -0xc536, 0xc544, 0xc551, 0xc55f, 0xc56d, 0xc57b, -0xc589, 0xc596, 0xc5a4, 0xc5b2, 0xc5c0, 0xc5cd, -0xc5db, 0xc5e9, 0xc5f7, 0xc604, 0xc612, 0xc620, -0xc62d, 0xc63b, 0xc649, 0xc657, 0xc664, 0xc672, -0xc680, 0xc68d, 0xc69b, 0xc6a9, 0xc6b7, 0xc6c4, -0xc6d2, 0xc6e0, 0xc6ed, 0xc6fb, 0xc709, 0xc716, -0xc724, 0xc732, 0xc73f, 0xc74d, 0xc75b, 0xc768, -0xc776, 0xc784, 0xc791, 0xc79f, 0xc7ad, 0xc7ba, -0xc7c8, 0xc7d6, 0xc7e3, 0xc7f1, 0xc7fe, 0xc80c, -0xc81a, 0xc827, 0xc835, 0xc842, 0xc850, 0xc85e, -0xc86b, 0xc879, 0xc886, 0xc894, 0xc8a2, 0xc8af, -0xc8bd, 0xc8ca, 0xc8d8, 0xc8e5, 0xc8f3, 0xc901, -0xc90e, 0xc91c, 0xc929, 0xc937, 0xc944, 0xc952, -0xc95f, 0xc96d, 0xc97b, 0xc988, 0xc996, 0xc9a3, -0xc9b1, 0xc9be, 0xc9cc, 0xc9d9, 0xc9e7, 0xc9f4, -0xca02, 0xca0f, 0xca1d, 0xca2a, 0xca38, 0xca45, -0xca53, 0xca60, 0xca6e, 0xca7b, 0xca89, 0xca96, -0xcaa4, 0xcab1, 0xcabe, 0xcacc, 0xcad9, 0xcae7, -0xcaf4, 0xcb02, 0xcb0f, 0xcb1d, 0xcb2a, 0xcb37, -0xcb45, 0xcb52, 0xcb60, 0xcb6d, 0xcb7b, 0xcb88, -0xcb95, 0xcba3, 0xcbb0, 0xcbbe, 0xcbcb, 0xcbd8, -0xcbe6, 0xcbf3, 0xcc01, 0xcc0e, 0xcc1b, 0xcc29, -0xcc36, 0xcc43, 0xcc51, 0xcc5e, 0xcc6c, 0xcc79, -0xcc86, 0xcc94, 0xcca1, 0xccae, 0xccbc, 0xccc9, -0xccd6, 0xcce4, 0xccf1, 0xccfe, 0xcd0c, 0xcd19, -0xcd26, 0xcd34, 0xcd41, 0xcd4e, 0xcd5b, 0xcd69, -0xcd76, 0xcd83, 0xcd91, 0xcd9e, 0xcdab, 0xcdb9, -0xcdc6, 0xcdd3, 0xcde0, 0xcdee, 0xcdfb, 0xce08, -0xce15, 0xce23, 0xce30, 0xce3d, 0xce4a, 0xce58, -0xce65, 0xce72, 0xce7f, 0xce8d, 0xce9a, 0xcea7, -0xceb4, 0xcec2, 0xcecf, 0xcedc, 0xcee9, 0xcef6, -0xcf04, 0xcf11, 0xcf1e, 0xcf2b, 0xcf38, 0xcf46, -0xcf53, 0xcf60, 0xcf6d, 0xcf7a, 0xcf87, 0xcf95, -0xcfa2, 0xcfaf, 0xcfbc, 0xcfc9, 0xcfd6, 0xcfe4, -0xcff1, 0xcffe, 0xd00b, 0xd018, 0xd025, 0xd032, -0xd040, 0xd04d, 0xd05a, 0xd067, 0xd074, 0xd081, -0xd08e, 0xd09b, 0xd0a9, 0xd0b6, 0xd0c3, 0xd0d0, -0xd0dd, 0xd0ea, 0xd0f7, 0xd104, 0xd111, 0xd11e, -0xd12b, 0xd139, 0xd146, 0xd153, 0xd160, 0xd16d, -0xd17a, 0xd187, 0xd194, 0xd1a1, 0xd1ae, 0xd1bb, -0xd1c8, 0xd1d5, 0xd1e2, 0xd1ef, 0xd1fc, 0xd209, -0xd216, 0xd223, 0xd230, 0xd23d, 0xd24a, 0xd257, -0xd264, 0xd271, 0xd27e, 0xd28b, 0xd298, 0xd2a5, -0xd2b2, 0xd2bf, 0xd2cc, 0xd2d9, 0xd2e6, 0xd2f3, -0xd300, 0xd30d, 0xd31a, 0xd327, 0xd334, 0xd341, -0xd34e, 0xd35b, 0xd368, 0xd375, 0xd382, 0xd38f, -0xd39c, 0xd3a8, 0xd3b5, 0xd3c2, 0xd3cf, 0xd3dc, -0xd3e9, 0xd3f6, 0xd403, 0xd410, 0xd41d, 0xd42a, -0xd436, 0xd443, 0xd450, 0xd45d, 0xd46a, 0xd477, -0xd484, 0xd491, 0xd49e, 0xd4aa, 0xd4b7, 0xd4c4, -0xd4d1, 0xd4de, 0xd4eb, 0xd4f8, 0xd504, 0xd511, -0xd51e, 0xd52b, 0xd538, 0xd545, 0xd551, 0xd55e, -0xd56b, 0xd578, 0xd585, 0xd591, 0xd59e, 0xd5ab, -0xd5b8, 0xd5c5, 0xd5d1, 0xd5de, 0xd5eb, 0xd5f8, -0xd605, 0xd611, 0xd61e, 0xd62b, 0xd638, 0xd645, -0xd651, 0xd65e, 0xd66b, 0xd678, 0xd684, 0xd691, -0xd69e, 0xd6ab, 0xd6b7, 0xd6c4, 0xd6d1, 0xd6de, -0xd6ea, 0xd6f7, 0xd704, 0xd710, 0xd71d, 0xd72a, -0xd737, 0xd743, 0xd750, 0xd75d, 0xd769, 0xd776, -0xd783, 0xd78f, 0xd79c, 0xd7a9, 0xd7b6, 0xd7c2, -0xd7cf, 0xd7dc, 0xd7e8, 0xd7f5, 0xd802, 0xd80e, -0xd81b, 0xd828, 0xd834, 0xd841, 0xd84e, 0xd85a, -0xd867, 0xd873, 0xd880, 0xd88d, 0xd899, 0xd8a6, -0xd8b3, 0xd8bf, 0xd8cc, 0xd8d8, 0xd8e5, 0xd8f2, -0xd8fe, 0xd90b, 0xd917, 0xd924, 0xd931, 0xd93d, -0xd94a, 0xd956, 0xd963, 0xd970, 0xd97c, 0xd989, -0xd995, 0xd9a2, 0xd9ae, 0xd9bb, 0xd9c8, 0xd9d4, -0xd9e1, 0xd9ed, 0xd9fa, 0xda06, 0xda13, 0xda1f, -0xda2c, 0xda38, 0xda45, 0xda51, 0xda5e, 0xda6a, -0xda77, 0xda84, 0xda90, 0xda9d, 0xdaa9, 0xdab6, -0xdac2, 0xdacf, 0xdadb, 0xdae7, 0xdaf4, 0xdb00, -0xdb0d, 0xdb19, 0xdb26, 0xdb32, 0xdb3f, 0xdb4b, -0xdb58, 0xdb64, 0xdb71, 0xdb7d, 0xdb8a, 0xdb96, -0xdba2, 0xdbaf, 0xdbbb, 0xdbc8, 0xdbd4, 0xdbe1, -0xdbed, 0xdbf9, 0xdc06, 0xdc12, 0xdc1f, 0xdc2b, -0xdc38, 0xdc44, 0xdc50, 0xdc5d, 0xdc69, 0xdc76, -0xdc82, 0xdc8e, 0xdc9b, 0xdca7, 0xdcb3, 0xdcc0, -0xdccc, 0xdcd9, 0xdce5, 0xdcf1, 0xdcfe, 0xdd0a, -0xdd16, 0xdd23, 0xdd2f, 0xdd3b, 0xdd48, 0xdd54, -0xdd60, 0xdd6d, 0xdd79, 0xdd85, 0xdd92, 0xdd9e, -0xddaa, 0xddb7, 0xddc3, 0xddcf, 0xdddc, 0xdde8, -0xddf4, 0xde01, 0xde0d, 0xde19, 0xde25, 0xde32, -0xde3e, 0xde4a, 0xde57, 0xde63, 0xde6f, 0xde7b, -0xde88, 0xde94, 0xdea0, 0xdeac, 0xdeb9, 0xdec5, -0xded1, 0xdedd, 0xdeea, 0xdef6, 0xdf02, 0xdf0e, -0xdf1b, 0xdf27, 0xdf33, 0xdf3f, 0xdf4c, 0xdf58, -0xdf64, 0xdf70, 0xdf7c, 0xdf89, 0xdf95, 0xdfa1, -0xdfad, 0xdfb9, 0xdfc6, 0xdfd2, 0xdfde, 0xdfea, -0xdff6, 0xe003, 0xe00f, 0xe01b, 0xe027, 0xe033, -0xe03f, 0xe04c, 0xe058, 0xe064, 0xe070, 0xe07c, -0xe088, 0xe094, 0xe0a1, 0xe0ad, 0xe0b9, 0xe0c5, -0xe0d1, 0xe0dd, 0xe0e9, 0xe0f5, 0xe102, 0xe10e, -0xe11a, 0xe126, 0xe132, 0xe13e, 0xe14a, 0xe156, -0xe162, 0xe16e, 0xe17b, 0xe187, 0xe193, 0xe19f, -0xe1ab, 0xe1b7, 0xe1c3, 0xe1cf, 0xe1db, 0xe1e7, -0xe1f3, 0xe1ff, 0xe20b, 0xe217, 0xe223, 0xe22f, -0xe23c, 0xe248, 0xe254, 0xe260, 0xe26c, 0xe278, -0xe284, 0xe290, 0xe29c, 0xe2a8, 0xe2b4, 0xe2c0, -0xe2cc, 0xe2d8, 0xe2e4, 0xe2f0, 0xe2fc, 0xe308, -0xe314, 0xe320, 0xe32c, 0xe338, 0xe344, 0xe350, -0xe35c, 0xe368, 0xe374, 0xe380, 0xe38b, 0xe397, -0xe3a3, 0xe3af, 0xe3bb, 0xe3c7, 0xe3d3, 0xe3df, -0xe3eb, 0xe3f7, 0xe403, 0xe40f, 0xe41b, 0xe427, -0xe433, 0xe43f, 0xe44a, 0xe456, 0xe462, 0xe46e, -0xe47a, 0xe486, 0xe492, 0xe49e, 0xe4aa, 0xe4b6, -0xe4c1, 0xe4cd, 0xe4d9, 0xe4e5, 0xe4f1, 0xe4fd, -0xe509, 0xe515, 0xe520, 0xe52c, 0xe538, 0xe544, -0xe550, 0xe55c, 0xe567, 0xe573, 0xe57f, 0xe58b, -0xe597, 0xe5a3, 0xe5af, 0xe5ba, 0xe5c6, 0xe5d2, -0xe5de, 0xe5ea, 0xe5f5, 0xe601, 0xe60d, 0xe619, -0xe625, 0xe630, 0xe63c, 0xe648, 0xe654, 0xe660, -0xe66b, 0xe677, 0xe683, 0xe68f, 0xe69a, 0xe6a6, -0xe6b2, 0xe6be, 0xe6ca, 0xe6d5, 0xe6e1, 0xe6ed, -0xe6f9, 0xe704, 0xe710, 0xe71c, 0xe727, 0xe733, -0xe73f, 0xe74b, 0xe756, 0xe762, 0xe76e, 0xe77a, -0xe785, 0xe791, 0xe79d, 0xe7a8, 0xe7b4, 0xe7c0, -0xe7cb, 0xe7d7, 0xe7e3, 0xe7ef, 0xe7fa, 0xe806, -0xe812, 0xe81d, 0xe829, 0xe835, 0xe840, 0xe84c, -0xe858, 0xe863, 0xe86f, 0xe87b, 0xe886, 0xe892, -0xe89e, 0xe8a9, 0xe8b5, 0xe8c0, 0xe8cc, 0xe8d8, -0xe8e3, 0xe8ef, 0xe8fb, 0xe906, 0xe912, 0xe91d, -0xe929, 0xe935, 0xe940, 0xe94c, 0xe958, 0xe963, -0xe96f, 0xe97a, 0xe986, 0xe991, 0xe99d, 0xe9a9, -0xe9b4, 0xe9c0, 0xe9cb, 0xe9d7, 0xe9e3, 0xe9ee, -0xe9fa, 0xea05, 0xea11, 0xea1c, 0xea28, 0xea33, -0xea3f, 0xea4a, 0xea56, 0xea62, 0xea6d, 0xea79, -0xea84, 0xea90, 0xea9b, 0xeaa7, 0xeab2, 0xeabe, -0xeac9, 0xead5, 0xeae0, 0xeaec, 0xeaf7, 0xeb03, -0xeb0e, 0xeb1a, 0xeb25, 0xeb31, 0xeb3c, 0xeb48, -0xeb53, 0xeb5f, 0xeb6a, 0xeb76, 0xeb81, 0xeb8d, -0xeb98, 0xeba3, 0xebaf, 0xebba, 0xebc6, 0xebd1, -0xebdd, 0xebe8, 0xebf4, 0xebff, 0xec0a, 0xec16, -0xec21, 0xec2d, 0xec38, 0xec44, 0xec4f, 0xec5a, -0xec66, 0xec71, 0xec7d, 0xec88, 0xec93, 0xec9f, -0xecaa, 0xecb6, 0xecc1, 0xeccc, 0xecd8, 0xece3, -0xecef, 0xecfa, 0xed05, 0xed11, 0xed1c, 0xed27, -0xed33, 0xed3e, 0xed4a, 0xed55, 0xed60, 0xed6c, -0xed77, 0xed82, 0xed8e, 0xed99, 0xeda4, 0xedb0, -0xedbb, 0xedc6, 0xedd2, 0xeddd, 0xede8, 0xedf4, -0xedff, 0xee0a, 0xee15, 0xee21, 0xee2c, 0xee37, -0xee43, 0xee4e, 0xee59, 0xee65, 0xee70, 0xee7b, -0xee86, 0xee92, 0xee9d, 0xeea8, 0xeeb3, 0xeebf, -0xeeca, 0xeed5, 0xeee1, 0xeeec, 0xeef7, 0xef02, -0xef0e, 0xef19, 0xef24, 0xef2f, 0xef3a, 0xef46, -0xef51, 0xef5c, 0xef67, 0xef73, 0xef7e, 0xef89, -0xef94, 0xef9f, 0xefab, 0xefb6, 0xefc1, 0xefcc, -0xefd7, 0xefe3, 0xefee, 0xeff9, 0xf004, 0xf00f, -0xf01b, 0xf026, 0xf031, 0xf03c, 0xf047, 0xf052, -0xf05e, 0xf069, 0xf074, 0xf07f, 0xf08a, 0xf095, -0xf0a1, 0xf0ac, 0xf0b7, 0xf0c2, 0xf0cd, 0xf0d8, -0xf0e3, 0xf0ef, 0xf0fa, 0xf105, 0xf110, 0xf11b, -0xf126, 0xf131, 0xf13c, 0xf147, 0xf153, 0xf15e, -0xf169, 0xf174, 0xf17f, 0xf18a, 0xf195, 0xf1a0, -0xf1ab, 0xf1b6, 0xf1c2, 0xf1cd, 0xf1d8, 0xf1e3, -0xf1ee, 0xf1f9, 0xf204, 0xf20f, 0xf21a, 0xf225, -0xf230, 0xf23b, 0xf246, 0xf251, 0xf25c, 0xf267, -0xf272, 0xf27d, 0xf288, 0xf293, 0xf29f, 0xf2aa, -0xf2b5, 0xf2c0, 0xf2cb, 0xf2d6, 0xf2e1, 0xf2ec, -0xf2f7, 0xf302, 0xf30d, 0xf318, 0xf323, 0xf32e, -0xf339, 0xf344, 0xf34f, 0xf35a, 0xf364, 0xf36f, -0xf37a, 0xf385, 0xf390, 0xf39b, 0xf3a6, 0xf3b1, -0xf3bc, 0xf3c7, 0xf3d2, 0xf3dd, 0xf3e8, 0xf3f3, -0xf3fe, 0xf409, 0xf414, 0xf41f, 0xf42a, 0xf435, -0xf43f, 0xf44a, 0xf455, 0xf460, 0xf46b, 0xf476, -0xf481, 0xf48c, 0xf497, 0xf4a2, 0xf4ad, 0xf4b7, -0xf4c2, 0xf4cd, 0xf4d8, 0xf4e3, 0xf4ee, 0xf4f9, -0xf504, 0xf50f, 0xf519, 0xf524, 0xf52f, 0xf53a, -0xf545, 0xf550, 0xf55b, 0xf565, 0xf570, 0xf57b, -0xf586, 0xf591, 0xf59c, 0xf5a6, 0xf5b1, 0xf5bc, -0xf5c7, 0xf5d2, 0xf5dd, 0xf5e7, 0xf5f2, 0xf5fd, -0xf608, 0xf613, 0xf61d, 0xf628, 0xf633, 0xf63e, -0xf649, 0xf653, 0xf65e, 0xf669, 0xf674, 0xf67f, -0xf689, 0xf694, 0xf69f, 0xf6aa, 0xf6b4, 0xf6bf, -0xf6ca, 0xf6d5, 0xf6e0, 0xf6ea, 0xf6f5, 0xf700, -0xf70b, 0xf715, 0xf720, 0xf72b, 0xf736, 0xf740, -0xf74b, 0xf756, 0xf760, 0xf76b, 0xf776, 0xf781, -0xf78b, 0xf796, 0xf7a1, 0xf7ab, 0xf7b6, 0xf7c1, -0xf7cc, 0xf7d6, 0xf7e1, 0xf7ec, 0xf7f6, 0xf801, -0xf80c, 0xf816, 0xf821, 0xf82c, 0xf836, 0xf841, -0xf84c, 0xf856, 0xf861, 0xf86c, 0xf876, 0xf881, -0xf88c, 0xf896, 0xf8a1, 0xf8ac, 0xf8b6, 0xf8c1, -0xf8cc, 0xf8d6, 0xf8e1, 0xf8ec, 0xf8f6, 0xf901, -0xf90b, 0xf916, 0xf921, 0xf92b, 0xf936, 0xf941, -0xf94b, 0xf956, 0xf960, 0xf96b, 0xf976, 0xf980, -0xf98b, 0xf995, 0xf9a0, 0xf9aa, 0xf9b5, 0xf9c0, -0xf9ca, 0xf9d5, 0xf9df, 0xf9ea, 0xf9f4, 0xf9ff, -0xfa0a, 0xfa14, 0xfa1f, 0xfa29, 0xfa34, 0xfa3e, -0xfa49, 0xfa53, 0xfa5e, 0xfa69, 0xfa73, 0xfa7e, -0xfa88, 0xfa93, 0xfa9d, 0xfaa8, 0xfab2, 0xfabd, -0xfac7, 0xfad2, 0xfadc, 0xfae7, 0xfaf1, 0xfafc, -0xfb06, 0xfb11, 0xfb1b, 0xfb26, 0xfb30, 0xfb3b, -0xfb45, 0xfb50, 0xfb5a, 0xfb65, 0xfb6f, 0xfb7a, -0xfb84, 0xfb8f, 0xfb99, 0xfba4, 0xfbae, 0xfbb8, -0xfbc3, 0xfbcd, 0xfbd8, 0xfbe2, 0xfbed, 0xfbf7, -0xfc02, 0xfc0c, 0xfc16, 0xfc21, 0xfc2b, 0xfc36, -0xfc40, 0xfc4b, 0xfc55, 0xfc5f, 0xfc6a, 0xfc74, -0xfc7f, 0xfc89, 0xfc93, 0xfc9e, 0xfca8, 0xfcb3, -0xfcbd, 0xfcc7, 0xfcd2, 0xfcdc, 0xfce7, 0xfcf1, -0xfcfb, 0xfd06, 0xfd10, 0xfd1a, 0xfd25, 0xfd2f, -0xfd3a, 0xfd44, 0xfd4e, 0xfd59, 0xfd63, 0xfd6d, -0xfd78, 0xfd82, 0xfd8c, 0xfd97, 0xfda1, 0xfdab, -0xfdb6, 0xfdc0, 0xfdca, 0xfdd5, 0xfddf, 0xfde9, -0xfdf4, 0xfdfe, 0xfe08, 0xfe13, 0xfe1d, 0xfe27, -0xfe32, 0xfe3c, 0xfe46, 0xfe50, 0xfe5b, 0xfe65, -0xfe6f, 0xfe7a, 0xfe84, 0xfe8e, 0xfe98, 0xfea3, -0xfead, 0xfeb7, 0xfec1, 0xfecc, 0xfed6, 0xfee0, -0xfeeb, 0xfef5, 0xfeff, 0xff09, 0xff14, 0xff1e, -0xff28, 0xff32, 0xff3c, 0xff47, 0xff51, 0xff5b, -0xff65, 0xff70, 0xff7a, 0xff84, 0xff8e, 0xff98, -0xffa3, 0xffad, 0xffb7, 0xffc1, 0xffcc, 0xffd6, -0xffe0, 0xffea, 0xfff4, 0xffff -}; - -// max value is pi/4 -constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF; - -double atan2_lookup(double y, double x) -{ - if (std::abs(x) < std::numeric_limits::epsilon()) - { - if (y >= 0.) - { - return M_PI / 2.; - } - else - { - return -M_PI / 2.; - } - } - - unsigned octant = 0; - - if (x < 0.) - { - octant = 1; - x = -x; - } - if (y < 0.) - { - octant |= 2; - y = -y; - } - - double t = y / x; - if (t > 1.0) - { - octant |= 4; - t = 1.0 / t; - } - - double angle = atan_table[(unsigned)(t * 4095)] / SCALING_FACTOR; - - switch (octant) - { - case 0: - break; - case 1: - angle = M_PI - angle; - break; - case 2: - angle = -angle; - break; - case 3: - angle = -M_PI + angle; - break; - case 4: - angle = M_PI / 2.0 - angle; - break; - case 5: - angle = M_PI / 2.0 + angle; - break; - case 6: - angle = -M_PI / 2.0 + angle; - break; - case 7: - angle = -M_PI / 2.0 - angle; - break; - } - return angle; -} - -#endif // TRIGONOMETRY_TABLES_H diff --git a/3party/osrm/osrm-backend/algorithms/bayes_classifier.hpp b/3party/osrm/osrm-backend/algorithms/bayes_classifier.hpp new file mode 100755 index 0000000000..3358144c75 --- /dev/null +++ b/3party/osrm/osrm-backend/algorithms/bayes_classifier.hpp @@ -0,0 +1,117 @@ +/* + +Copyright (c) 2015, 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 BAYES_CLASSIFIER_HPP +#define BAYES_CLASSIFIER_HPP + +#include + +#include + +struct NormalDistribution +{ + NormalDistribution(const double mean, const double standard_deviation) + : mean(mean), standard_deviation(standard_deviation) + { + } + + // FIXME implement log-probability version since its faster + double density_function(const double val) const + { + const double x = val - mean; + return 1.0 / (std::sqrt(2. * M_PI) * standard_deviation) * + std::exp(-x * x / (standard_deviation * standard_deviation)); + } + + double mean; + double standard_deviation; +}; + +struct LaplaceDistribution +{ + LaplaceDistribution(const double location, const double scale) + : location(location), scale(scale) + { + } + + // FIXME implement log-probability version since its faster + double density_function(const double val) const + { + const double x = std::abs(val - location); + return 1.0 / (2. * scale) * std::exp(-x / scale); + } + + double location; + double scale; +}; + +template +class BayesClassifier +{ + public: + enum class ClassLabel : unsigned + { + NEGATIVE, + POSITIVE + }; + using ClassificationT = std::pair; + + BayesClassifier(const PositiveDistributionT &positive_distribution, + const NegativeDistributionT &negative_distribution, + const double positive_apriori_probability) + : positive_distribution(positive_distribution), + negative_distribution(negative_distribution), + positive_apriori_probability(positive_apriori_probability), + negative_apriori_probability(1. - positive_apriori_probability) + { + } + + // Returns label and the probability of the label. + ClassificationT classify(const ValueT &v) const + { + const double positive_postpriori = + positive_apriori_probability * positive_distribution.density_function(v); + const double negative_postpriori = + negative_apriori_probability * negative_distribution.density_function(v); + const double norm = positive_postpriori + negative_postpriori; + + if (positive_postpriori > negative_postpriori) + { + return std::make_pair(ClassLabel::POSITIVE, positive_postpriori / norm); + } + + return std::make_pair(ClassLabel::NEGATIVE, negative_postpriori / norm); + } + + private: + PositiveDistributionT positive_distribution; + NegativeDistributionT negative_distribution; + double positive_apriori_probability; + double negative_apriori_probability; +}; + +#endif // BAYES_CLASSIFIER_HPP diff --git a/3party/osrm/osrm-backend/Algorithms/BFSComponentExplorer.h b/3party/osrm/osrm-backend/algorithms/bfs_components.hpp old mode 100644 new mode 100755 similarity index 52% rename from 3party/osrm/osrm-backend/Algorithms/BFSComponentExplorer.h rename to 3party/osrm/osrm-backend/algorithms/bfs_components.hpp index daab82a14f..b3f5364015 --- a/3party/osrm/osrm-backend/Algorithms/BFSComponentExplorer.h +++ b/3party/osrm/osrm-backend/algorithms/bfs_components.hpp @@ -1,8 +1,35 @@ -#ifndef BFS_COMPONENT_EXPLORER_H_ -#define BFS_COMPONENT_EXPLORER_H_ +/* + +Copyright (c) 2015, 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 BFS_COMPONENTS_HPP_ +#define BFS_COMPONENTS_HPP_ #include "../typedefs.h" -#include "../DataStructures/RestrictionMap.h" +#include "../data_structures/restriction_map.hpp" #include #include @@ -68,8 +95,8 @@ template class BFSComponentExplorer * Explores the current component that starts at node using BFS. */ unsigned ExploreComponent(std::queue> &bfs_queue, - NodeID node, - unsigned current_component) + NodeID node, + unsigned current_component) { /* Graphical representation of variables: @@ -91,42 +118,42 @@ template class BFSComponentExplorer std::pair current_queue_item = bfs_queue.front(); bfs_queue.pop(); - const NodeID v = current_queue_item.first; // current node + const NodeID v = current_queue_item.first; // current node const NodeID u = current_queue_item.second; // parent // increment size counter of current component ++current_component_size; - const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); - if (!is_barrier_node) + if (m_barrier_nodes.find(v) != m_barrier_nodes.end()) { - const NodeID to_node_of_only_restriction = - m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); + continue; + } + const NodeID to_node_of_only_restriction = + m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); - for (auto e2 : m_graph.GetAdjacentEdgeRange(v)) + for (auto e2 : m_graph.GetAdjacentEdgeRange(v)) + { + const NodeID w = m_graph.GetTarget(e2); + + if (to_node_of_only_restriction != std::numeric_limits::max() && + w != to_node_of_only_restriction) { - const NodeID w = m_graph.GetTarget(e2); + // At an only_-restriction but not at the right turn + continue; + } - if (to_node_of_only_restriction != std::numeric_limits::max() && - w != to_node_of_only_restriction) + if (u != w) + { + // only add an edge if turn is not a U-turn except + // when it is at the end of a dead-end street. + if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w)) { - // At an only_-restriction but not at the right turn - continue; - } - - if (u != w) - { - // only add an edge if turn is not a U-turn except - // when it is at the end of a dead-end street. - if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w)) + // only add an edge if turn is not prohibited + if (std::numeric_limits::max() == m_component_index_list[w]) { - // only add an edge if turn is not prohibited - if (std::numeric_limits::max() == m_component_index_list[w]) - { - // insert next (node, parent) only if w has - // not yet been explored - // mark node as read - m_component_index_list[w] = current_component; - bfs_queue.emplace(w, v); - } + // insert next (node, parent) only if w has + // not yet been explored + // mark node as read + m_component_index_list[w] = current_component; + bfs_queue.emplace(w, v); } } } @@ -144,4 +171,4 @@ template class BFSComponentExplorer const std::unordered_set &m_barrier_nodes; }; -#endif // BFS_COMPONENT_EXPLORER_H_ +#endif // BFS_COMPONENTS_HPP_ diff --git a/3party/osrm/osrm-backend/Algorithms/IteratorBasedCRC32.h b/3party/osrm/osrm-backend/algorithms/crc32_processor.hpp old mode 100644 new mode 100755 similarity index 90% rename from 3party/osrm/osrm-backend/Algorithms/IteratorBasedCRC32.h rename to 3party/osrm/osrm-backend/algorithms/crc32_processor.hpp index a68514dceb..a31b4ad23a --- a/3party/osrm/osrm-backend/Algorithms/IteratorBasedCRC32.h +++ b/3party/osrm/osrm-backend/algorithms/crc32_processor.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -49,7 +49,7 @@ class IteratorbasedCRC32 while (iter != end) { using value_type = typename std::iterator_traits::value_type; - char *data = (char *)(&(*iter)); + const char *data = reinterpret_cast(&(*iter)); if (use_hardware_implementation) { @@ -73,14 +73,14 @@ class IteratorbasedCRC32 return sse42_found; } - unsigned compute_in_software(char *str, unsigned len) + unsigned compute_in_software(const char *str, unsigned len) { crc_processor.process_bytes(str, len); return crc_processor.checksum(); } // adapted from http://byteworm.com/2010/10/13/crc32/ - unsigned compute_in_hardware(char *str, unsigned len) + unsigned compute_in_hardware(const char *str, unsigned len) { #if defined(__x86_64__) unsigned q = len / sizeof(unsigned); @@ -96,7 +96,7 @@ class IteratorbasedCRC32 ++p; } - str = (char *)p; + str = reinterpret_cast(p); while (r--) { __asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;" @@ -116,7 +116,7 @@ class IteratorbasedCRC32 return ecx; } -#if defined(__MINGW64__) || defined(_MSC_VER) +#if defined(__MINGW64__) || defined(_MSC_VER) || !defined(__x86_64__) inline void __get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) const { @@ -131,8 +131,7 @@ class IteratorbasedCRC32 struct RangebasedCRC32 { - template - unsigned operator()(const Iteratable &iterable) + template unsigned operator()(const Iteratable &iterable) { return crc32(std::begin(iterable), std::end(iterable)); } diff --git a/3party/osrm/osrm-backend/Algorithms/DouglasPeucker.cpp b/3party/osrm/osrm-backend/algorithms/douglas_peucker.cpp old mode 100644 new mode 100755 similarity index 56% rename from 3party/osrm/osrm-backend/Algorithms/DouglasPeucker.cpp rename to 3party/osrm/osrm-backend/algorithms/douglas_peucker.cpp index 6444f13575..fa7d7826b8 --- a/3party/osrm/osrm-backend/Algorithms/DouglasPeucker.cpp +++ b/3party/osrm/osrm-backend/algorithms/douglas_peucker.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,20 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "DouglasPeucker.h" +#include "douglas_peucker.hpp" -#include "../DataStructures/Range.h" -#include "../DataStructures/SegmentInformation.h" - -#include +#include "../data_structures/segment_information.hpp" #include +#include #include - #include +#include -namespace { +namespace +{ struct CoordinatePairCalculator { CoordinatePairCalculator() = delete; @@ -64,12 +63,12 @@ struct CoordinatePairCalculator // compute distance (a,c) const float x_value_1 = (first_lon - float_lon1) * cos((float_lat1 + first_lat) / 2.f); const float y_value_1 = first_lat - float_lat1; - const float dist1 = sqrt(std::pow(x_value_1, 2) + std::pow(y_value_1, 2)) * earth_radius; + const float dist1 = std::hypot(x_value_1, y_value_1) * earth_radius; // compute distance (b,c) const float x_value_2 = (second_lon - float_lon1) * cos((float_lat1 + second_lat) / 2.f); const float y_value_2 = second_lat - float_lat1; - const float dist2 = sqrt(std::pow(x_value_2, 2) + std::pow(y_value_2, 2)) * earth_radius; + const float dist2 = std::hypot(x_value_2, y_value_2) * earth_radius; // return the minimum return static_cast(std::min(dist1, dist2)); @@ -82,61 +81,40 @@ struct CoordinatePairCalculator }; } -DouglasPeucker::DouglasPeucker() - : douglas_peucker_thresholds({512440, // z0 - 256720, // z1 - 122560, // z2 - 56780, // z3 - 28800, // z4 - 14400, // z5 - 7200, // z6 - 3200, // z7 - 2400, // z8 - 1000, // z9 - 600, // z10 - 120, // z11 - 60, // z12 - 45, // z13 - 36, // z14 - 20, // z15 - 8, // z16 - 6, // z17 - 4 // z18 - }) -{ -} - void DouglasPeucker::Run(std::vector &input_geometry, const unsigned zoom_level) { - // check if input data is invalid - BOOST_ASSERT_MSG(!input_geometry.empty(), "geometry invalid"); + Run(std::begin(input_geometry), std::end(input_geometry), zoom_level); +} - if (input_geometry.size() < 2) +void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level) +{ + const auto size = std::distance(begin, end); + if (size < 2) { return; } - input_geometry.front().necessary = true; - input_geometry.back().necessary = true; + begin->necessary = true; + std::prev(end)->necessary = true; { - BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level"); - unsigned left_border = 0; - unsigned right_border = 1; + BOOST_ASSERT_MSG(zoom_level < DOUGLAS_PEUCKER_THRESHOLDS.size(), "unsupported zoom level"); + RandomAccessIt left_border = begin; + RandomAccessIt right_border = std::next(begin); // Sweep over array and identify those ranges that need to be checked do { // traverse list until new border element found - if (input_geometry[right_border].necessary) + if (right_border->necessary) { // sanity checks - BOOST_ASSERT(input_geometry[left_border].necessary); - BOOST_ASSERT(input_geometry[right_border].necessary); + BOOST_ASSERT(left_border->necessary); + BOOST_ASSERT(right_border->necessary); recursion_stack.emplace(left_border, right_border); left_border = right_border; } ++right_border; - } while (right_border < input_geometry.size()); + } while (right_border != end); } // mark locations as 'necessary' by divide-and-conquer @@ -146,40 +124,40 @@ void DouglasPeucker::Run(std::vector &input_geometry, const const GeometryRange pair = recursion_stack.top(); recursion_stack.pop(); // sanity checks - BOOST_ASSERT_MSG(input_geometry[pair.first].necessary, "left border mus be necessary"); - BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary"); - BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry"); - BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side"); + BOOST_ASSERT_MSG(pair.first->necessary, "left border must be necessary"); + BOOST_ASSERT_MSG(pair.second->necessary, "right border must be necessary"); + BOOST_ASSERT_MSG(std::distance(pair.second, end) > 0, "right border outside of geometry"); + BOOST_ASSERT_MSG(std::distance(pair.first, pair.second) >= 0, + "left border on the wrong side"); int max_int_distance = 0; - unsigned farthest_entry_index = pair.second; - const CoordinatePairCalculator dist_calc(input_geometry[pair.first].location, - input_geometry[pair.second].location); + auto farthest_entry_it = pair.second; + const CoordinatePairCalculator dist_calc(pair.first->location, pair.second->location); // sweep over range to find the maximum - for (const auto i : osrm::irange(pair.first + 1, pair.second)) + for (auto it = std::next(pair.first); it != pair.second; ++it) { - const int distance = dist_calc(input_geometry[i].location); + const int distance = dist_calc(it->location); // found new feasible maximum? - if (distance > max_int_distance && distance > douglas_peucker_thresholds[zoom_level]) + if (distance > max_int_distance && distance > DOUGLAS_PEUCKER_THRESHOLDS[zoom_level]) { - farthest_entry_index = i; + farthest_entry_it = it; max_int_distance = distance; } } // check if maximum violates a zoom level dependent threshold - if (max_int_distance > douglas_peucker_thresholds[zoom_level]) + if (max_int_distance > DOUGLAS_PEUCKER_THRESHOLDS[zoom_level]) { // mark idx as necessary - input_geometry[farthest_entry_index].necessary = true; - if (1 < (farthest_entry_index - pair.first)) + farthest_entry_it->necessary = true; + if (1 < std::distance(pair.first, farthest_entry_it)) { - recursion_stack.emplace(pair.first, farthest_entry_index); + recursion_stack.emplace(pair.first, farthest_entry_it); } - if (1 < (pair.second - farthest_entry_index)) + if (1 < std::distance(farthest_entry_it, pair.second)) { - recursion_stack.emplace(farthest_entry_index, pair.second); + recursion_stack.emplace(farthest_entry_it, pair.second); } } } diff --git a/3party/osrm/osrm-backend/Algorithms/DouglasPeucker.h b/3party/osrm/osrm-backend/algorithms/douglas_peucker.hpp old mode 100644 new mode 100755 similarity index 68% rename from 3party/osrm/osrm-backend/Algorithms/DouglasPeucker.h rename to 3party/osrm/osrm-backend/algorithms/douglas_peucker.hpp index 60fc377b10..da02982f3d --- a/3party/osrm/osrm-backend/Algorithms/DouglasPeucker.h +++ b/3party/osrm/osrm-backend/algorithms/douglas_peucker.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,9 +25,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DOUGLASPEUCKER_H_ -#define DOUGLASPEUCKER_H_ +#ifndef DOUGLAS_PEUCKER_HPP_ +#define DOUGLAS_PEUCKER_HPP_ +#include "../data_structures/segment_information.hpp" + +#include #include #include #include @@ -39,20 +42,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * bit indicating if the points is present in the generalization. * Note: points may also be pre-selected*/ -struct SegmentInformation; +static const std::array DOUGLAS_PEUCKER_THRESHOLDS{{ + 512440, // z0 + 256720, // z1 + 122560, // z2 + 56780, // z3 + 28800, // z4 + 14400, // z5 + 7200, // z6 + 3200, // z7 + 2400, // z8 + 1000, // z9 + 600, // z10 + 120, // z11 + 60, // z12 + 45, // z13 + 36, // z14 + 20, // z15 + 8, // z16 + 6, // z17 + 4 // z18 +}}; class DouglasPeucker { - private: - std::vector douglas_peucker_thresholds; + public: + using RandomAccessIt = std::vector::iterator; - using GeometryRange = std::pair; + using GeometryRange = std::pair; // Stack to simulate the recursion std::stack recursion_stack; public: - DouglasPeucker(); + void Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level); void Run(std::vector &input_geometry, const unsigned zoom_level); }; -#endif /* DOUGLASPEUCKER_H_ */ +#endif /* DOUGLAS_PEUCKER_HPP_ */ diff --git a/3party/osrm/osrm-backend/Algorithms/ObjectToBase64.h b/3party/osrm/osrm-backend/algorithms/object_encoder.hpp old mode 100644 new mode 100755 similarity index 82% rename from 3party/osrm/osrm-backend/Algorithms/ObjectToBase64.h rename to 3party/osrm/osrm-backend/algorithms/object_encoder.hpp index 6930b9c2c1..e880496a2d --- a/3party/osrm/osrm-backend/Algorithms/ObjectToBase64.h +++ b/3party/osrm/osrm-backend/algorithms/object_encoder.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,10 +25,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef OBJECT_TO_BASE64_H_ -#define OBJECT_TO_BASE64_H_ +#ifndef OBJECT_ENCODER_HPP +#define OBJECT_ENCODER_HPP -#include "../Util/StringUtil.h" +#include "../util/string_util.hpp" #include #include @@ -49,10 +49,9 @@ struct ObjectEncoder 8, 6>; - template - static void EncodeToBase64(const ObjectT &object, std::string &encoded) + template static void EncodeToBase64(const ObjectT &object, std::string &encoded) { - const char *char_ptr_to_object = (const char *)&object; + const char *char_ptr_to_object = reinterpret_cast(&object); std::vector data(sizeof(object)); std::copy(char_ptr_to_object, char_ptr_to_object + sizeof(ObjectT), data.begin()); @@ -71,8 +70,7 @@ struct ObjectEncoder replaceAll(encoded, "/", "_"); } - template - static void DecodeFromBase64(const std::string &input, ObjectT &object) + template static void DecodeFromBase64(const std::string &input, ObjectT &object) { try { @@ -81,9 +79,8 @@ struct ObjectEncoder replaceAll(encoded, "-", "+"); replaceAll(encoded, "_", "/"); - std::copy(binary_t(encoded.begin()), - binary_t(encoded.begin() + encoded.length() - 1), - (char *)&object); + std::copy(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length() - 1), + reinterpret_cast(&object)); } catch (...) { @@ -91,4 +88,4 @@ struct ObjectEncoder } }; -#endif /* OBJECT_TO_BASE64_H_ */ +#endif /* OBJECT_ENCODER_HPP */ diff --git a/3party/osrm/osrm-backend/Algorithms/PolylineCompressor.cpp b/3party/osrm/osrm-backend/algorithms/polyline_compressor.cpp old mode 100644 new mode 100755 similarity index 50% rename from 3party/osrm/osrm-backend/Algorithms/PolylineCompressor.cpp rename to 3party/osrm/osrm-backend/algorithms/polyline_compressor.cpp index bae40052b3..d5fd5828bb --- a/3party/osrm/osrm-backend/Algorithms/PolylineCompressor.cpp +++ b/3party/osrm/osrm-backend/algorithms/polyline_compressor.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,16 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "PolylineCompressor.h" -#include "../DataStructures/SegmentInformation.h" +#include "polyline_compressor.hpp" +#include "../data_structures/segment_information.hpp" -#include +#include -void PolylineCompressor::encodeVectorSignedNumber(std::vector &numbers, - std::string &output) const +std::string PolylineCompressor::encode_vector(std::vector &numbers) const { - const unsigned end = static_cast(numbers.size()); - for (unsigned i = 0; i < end; ++i) + std::string output; + const auto end = numbers.size(); + for (std::size_t i = 0; i < end; ++i) { numbers[i] <<= 1; if (numbers[i] < 0) @@ -44,69 +44,47 @@ void PolylineCompressor::encodeVectorSignedNumber(std::vector &numbers, } for (const int number : numbers) { - encodeNumber(number, output); + output += encode_number(number); } + return output; } -void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output) const +std::string PolylineCompressor::encode_number(int number_to_encode) const { + std::string output; while (number_to_encode >= 0x20) { const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63; output += static_cast(next_value); - if (92 == next_value) - { - output += static_cast(next_value); - } number_to_encode >>= 5; } number_to_encode += 63; output += static_cast(number_to_encode); - if (92 == number_to_encode) - { - output += static_cast(number_to_encode); - } + return output; } -JSON::String -PolylineCompressor::printEncodedString(const std::vector &polyline) const +std::string +PolylineCompressor::get_encoded_string(const std::vector &polyline) const { - std::string output; + if (polyline.empty()) + { + return {}; + } + std::vector delta_numbers; - if (!polyline.empty()) - { - FixedPointCoordinate last_coordinate = {0, 0}; - for (const auto &segment : polyline) - { - if (segment.necessary) - { - const int lat_diff = segment.location.lat - last_coordinate.lat; - const int lon_diff = segment.location.lon - last_coordinate.lon; - delta_numbers.emplace_back(lat_diff); - delta_numbers.emplace_back(lon_diff); - last_coordinate = segment.location; - } - } - encodeVectorSignedNumber(delta_numbers, output); - } - JSON::String return_value(output); - return return_value; -} - -JSON::Array -PolylineCompressor::printUnencodedString(const std::vector &polyline) const -{ - JSON::Array json_geometry_array; + delta_numbers.reserve((polyline.size() - 1) * 2); + FixedPointCoordinate previous_coordinate = {0, 0}; for (const auto &segment : polyline) { if (segment.necessary) { - JSON::Array json_coordinate; - json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION); - json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION); - json_geometry_array.values.push_back(json_coordinate); + const int lat_diff = segment.location.lat - previous_coordinate.lat; + const int lon_diff = segment.location.lon - previous_coordinate.lon; + delta_numbers.emplace_back(lat_diff); + delta_numbers.emplace_back(lon_diff); + previous_coordinate = segment.location; } } - return json_geometry_array; + return encode_vector(delta_numbers); } diff --git a/3party/osrm/osrm-backend/Algorithms/PolylineCompressor.h b/3party/osrm/osrm-backend/algorithms/polyline_compressor.hpp old mode 100644 new mode 100755 similarity index 76% rename from 3party/osrm/osrm-backend/Algorithms/PolylineCompressor.h rename to 3party/osrm/osrm-backend/algorithms/polyline_compressor.hpp index 5472bd808a..933ac7afab --- a/3party/osrm/osrm-backend/Algorithms/PolylineCompressor.h +++ b/3party/osrm/osrm-backend/algorithms/polyline_compressor.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -30,22 +30,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct SegmentInformation; -#include "../DataStructures/JSONContainer.h" - #include #include class PolylineCompressor { private: - void encodeVectorSignedNumber(std::vector &numbers, std::string &output) const; + std::string encode_vector(std::vector &numbers) const; - void encodeNumber(int number_to_encode, std::string &output) const; + std::string encode_number(const int number_to_encode) const; public: - JSON::String printEncodedString(const std::vector &polyline) const; - - JSON::Array printUnencodedString(const std::vector &polyline) const; + std::string get_encoded_string(const std::vector &polyline) const; }; #endif /* POLYLINECOMPRESSOR_H_ */ diff --git a/3party/osrm/osrm-backend/Util/Azimuth.h b/3party/osrm/osrm-backend/algorithms/polyline_formatter.cpp old mode 100644 new mode 100755 similarity index 56% rename from 3party/osrm/osrm-backend/Util/Azimuth.h rename to 3party/osrm/osrm-backend/algorithms/polyline_formatter.cpp index c4bf815bde..670a6121ff --- a/3party/osrm/osrm-backend/Util/Azimuth.h +++ b/3party/osrm/osrm-backend/algorithms/polyline_formatter.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,49 +25,32 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef AZIMUTH_H -#define AZIMUTH_H +#include "polyline_formatter.hpp" -#include +#include "polyline_compressor.hpp" +#include "../data_structures/segment_information.hpp" -struct Azimuth +#include + +osrm::json::String +PolylineFormatter::printEncodedString(const std::vector &polyline) const { - static std::string Get(const double heading) - { - if (heading <= 202.5) - { - if (heading >= 0 && heading <= 22.5) - { - return "N"; - } - if (heading > 22.5 && heading <= 67.5) - { - return "NE"; - } - if (heading > 67.5 && heading <= 112.5) - { - return "E"; - } - if (heading > 112.5 && heading <= 157.5) - { - return "SE"; - } - return "S"; - } - if (heading > 202.5 && heading <= 247.5) - { - return "SW"; - } - if (heading > 247.5 && heading <= 292.5) - { - return "W"; - } - if (heading > 292.5 && heading <= 337.5) - { - return "NW"; - } - return "N"; - } -}; + return osrm::json::String(PolylineCompressor().get_encoded_string(polyline)); +} -#endif // AZIMUTH_H +osrm::json::Array +PolylineFormatter::printUnencodedString(const std::vector &polyline) const +{ + osrm::json::Array json_geometry_array; + for (const auto &segment : polyline) + { + if (segment.necessary) + { + osrm::json::Array json_coordinate; + json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION); + json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION); + json_geometry_array.values.push_back(json_coordinate); + } + } + return json_geometry_array; +} diff --git a/3party/osrm/osrm-backend/algorithms/polyline_formatter.hpp b/3party/osrm/osrm-backend/algorithms/polyline_formatter.hpp new file mode 100755 index 0000000000..68cc70293e --- /dev/null +++ b/3party/osrm/osrm-backend/algorithms/polyline_formatter.hpp @@ -0,0 +1,45 @@ +/* + +Copyright (c) 2014, 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 POLYLINE_FORMATTER_HPP +#define POLYLINE_FORMATTER_HPP + +struct SegmentInformation; + +#include + +#include +#include + +struct PolylineFormatter +{ + osrm::json::String printEncodedString(const std::vector &polyline) const; + + osrm::json::Array printUnencodedString(const std::vector &polyline) const; +}; + +#endif /* POLYLINE_FORMATTER_HPP */ diff --git a/3party/osrm/osrm-backend/Algorithms/ExtractRouteNames.h b/3party/osrm/osrm-backend/algorithms/route_name_extraction.hpp old mode 100644 new mode 100755 similarity index 74% rename from 3party/osrm/osrm-backend/Algorithms/ExtractRouteNames.h rename to 3party/osrm/osrm-backend/algorithms/route_name_extraction.hpp index 519452f986..00dae89c4a --- a/3party/osrm/osrm-backend/Algorithms/ExtractRouteNames.h +++ b/3party/osrm/osrm-backend/algorithms/route_name_extraction.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -54,7 +54,8 @@ template struct ExtractRouteNames for (const SegmentT &segment : segment_list) { - if (segment.name_id != blocked_name_id && segment.length > result_segment.length && segment.name_id != 0) + if (segment.name_id != blocked_name_id && segment.length > result_segment.length && + segment.name_id != 0) { result_segment = segment; } @@ -73,9 +74,13 @@ template struct ExtractRouteNames SegmentT alternative_segment_1, alternative_segment_2; auto length_comperator = [](const SegmentT &a, const SegmentT &b) - { return a.length > b.length; }; + { + return a.length > b.length; + }; auto name_id_comperator = [](const SegmentT &a, const SegmentT &b) - { return a.name_id < b.name_id; }; + { + return a.name_id < b.name_id; + }; if (shortest_path_segments.empty()) { @@ -87,8 +92,7 @@ template struct ExtractRouteNames shortest_segment_1 = shortest_path_segments[0]; if (!alternative_path_segments.empty()) { - std::sort(alternative_path_segments.begin(), - alternative_path_segments.end(), + std::sort(alternative_path_segments.begin(), alternative_path_segments.end(), length_comperator); // also pick the longest segment for the alternative path @@ -99,16 +103,13 @@ template struct ExtractRouteNames // alternative std::vector shortest_path_set_difference(shortest_path_segments.size()); std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), name_id_comperator); - std::sort(alternative_path_segments.begin(), alternative_path_segments.end(), name_id_comperator); - std::set_difference(shortest_path_segments.begin(), - shortest_path_segments.end(), - alternative_path_segments.begin(), - alternative_path_segments.end(), - shortest_path_set_difference.begin(), - name_id_comperator); + std::sort(alternative_path_segments.begin(), alternative_path_segments.end(), + name_id_comperator); + std::set_difference(shortest_path_segments.begin(), shortest_path_segments.end(), + alternative_path_segments.begin(), alternative_path_segments.end(), + shortest_path_set_difference.begin(), name_id_comperator); - std::sort(shortest_path_set_difference.begin(), - shortest_path_set_difference.end(), + std::sort(shortest_path_set_difference.begin(), shortest_path_set_difference.end(), length_comperator); shortest_segment_2 = PickNextLongestSegment(shortest_path_set_difference, shortest_segment_1.name_id); @@ -116,29 +117,23 @@ template struct ExtractRouteNames // compute the set difference (for alternative path) depending on names between shortest and // alternative // vectors are still sorted, no need to do again - BOOST_ASSERT(std::is_sorted(shortest_path_segments.begin(), - shortest_path_segments.end(), + BOOST_ASSERT(std::is_sorted(shortest_path_segments.begin(), shortest_path_segments.end(), name_id_comperator)); BOOST_ASSERT(std::is_sorted(alternative_path_segments.begin(), - alternative_path_segments.end(), - name_id_comperator)); + alternative_path_segments.end(), name_id_comperator)); std::vector alternative_path_set_difference(alternative_path_segments.size()); - std::set_difference(alternative_path_segments.begin(), - alternative_path_segments.end(), - shortest_path_segments.begin(), - shortest_path_segments.end(), - alternative_path_set_difference.begin(), - name_id_comperator); + std::set_difference(alternative_path_segments.begin(), alternative_path_segments.end(), + shortest_path_segments.begin(), shortest_path_segments.end(), + alternative_path_set_difference.begin(), name_id_comperator); - std::sort(alternative_path_set_difference.begin(), - alternative_path_set_difference.end(), + std::sort(alternative_path_set_difference.begin(), alternative_path_set_difference.end(), length_comperator); if (!alternative_path_segments.empty()) { alternative_segment_2 = PickNextLongestSegment(alternative_path_set_difference, - alternative_segment_1.name_id); + alternative_segment_1.name_id); } // move the segments into the order in which they occur. @@ -152,15 +147,13 @@ template struct ExtractRouteNames } // fetching names for the selected segments - route_names.shortest_path_name_1 = - facade->GetEscapedNameForNameID(shortest_segment_1.name_id); - route_names.shortest_path_name_2 = - facade->GetEscapedNameForNameID(shortest_segment_2.name_id); + route_names.shortest_path_name_1 = facade->get_name_for_id(shortest_segment_1.name_id); + route_names.shortest_path_name_2 = facade->get_name_for_id(shortest_segment_2.name_id); route_names.alternative_path_name_1 = - facade->GetEscapedNameForNameID(alternative_segment_1.name_id); + facade->get_name_for_id(alternative_segment_1.name_id); route_names.alternative_path_name_2 = - facade->GetEscapedNameForNameID(alternative_segment_2.name_id); + facade->get_name_for_id(alternative_segment_2.name_id); return route_names; } diff --git a/3party/osrm/osrm-backend/algorithms/tiny_components.hpp b/3party/osrm/osrm-backend/algorithms/tiny_components.hpp new file mode 100755 index 0000000000..8eb61a9128 --- /dev/null +++ b/3party/osrm/osrm-backend/algorithms/tiny_components.hpp @@ -0,0 +1,239 @@ +/* + +Copyright (c) 2015, 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 TINY_COMPONENTS_HPP +#define TINY_COMPONENTS_HPP + +#include "../typedefs.h" +#include "../data_structures/deallocating_vector.hpp" +#include "../data_structures/import_edge.hpp" +#include "../data_structures/query_node.hpp" +#include "../data_structures/percent.hpp" +#include "../data_structures/restriction.hpp" +#include "../data_structures/restriction_map.hpp" +#include "../data_structures/turn_instructions.hpp" + +#include "../util/integer_range.hpp" +#include "../util/simple_logger.hpp" +#include "../util/std_hash.hpp" +#include "../util/timing_util.hpp" + +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include + +template class TarjanSCC +{ + struct TarjanStackFrame + { + explicit TarjanStackFrame(NodeID v, NodeID parent) : v(v), parent(parent) {} + NodeID v; + NodeID parent; + }; + + struct TarjanNode + { + TarjanNode() : index(SPECIAL_NODEID), low_link(SPECIAL_NODEID), on_stack(false) {} + unsigned index; + unsigned low_link; + bool on_stack; + }; + + std::vector components_index; + std::vector component_size_vector; + std::shared_ptr m_node_based_graph; + std::unordered_set barrier_node_set; + RestrictionMap m_restriction_map; + std::size_t size_one_counter; + + public: + template + TarjanSCC(std::shared_ptr graph, + const RestrictionMap &restrictions, + const ContainerT &barrier_node_list) + : components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID), m_node_based_graph(graph), + m_restriction_map(restrictions), size_one_counter(0) + { + barrier_node_set.insert(std::begin(barrier_node_list), std::end(barrier_node_list)); + BOOST_ASSERT(m_node_based_graph->GetNumberOfNodes() > 0); + } + + void run() + { + TIMER_START(SCC_RUN); + const NodeID max_node_id = m_node_based_graph->GetNumberOfNodes(); + + // The following is a hack to distinguish between stuff that happens + // before the recursive call and stuff that happens after + std::stack recursion_stack; + // true = stuff before, false = stuff after call + std::stack tarjan_stack; + std::vector tarjan_node_list(max_node_id); + unsigned component_index = 0, size_of_current_component = 0; + unsigned index = 0; + std::vector processing_node_before_recursion(max_node_id, true); + for (const NodeID node : osrm::irange(0u, max_node_id)) + { + if (SPECIAL_NODEID == components_index[node]) + { + recursion_stack.emplace(TarjanStackFrame(node, node)); + } + + while (!recursion_stack.empty()) + { + TarjanStackFrame currentFrame = recursion_stack.top(); + const NodeID u = currentFrame.parent; + const NodeID v = currentFrame.v; + recursion_stack.pop(); + + const bool before_recursion = processing_node_before_recursion[v]; + + if (before_recursion && tarjan_node_list[v].index != UINT_MAX) + { + continue; + } + + if (before_recursion) + { + // Mark frame to handle tail of recursion + recursion_stack.emplace(currentFrame); + processing_node_before_recursion[v] = false; + + // Mark essential information for SCC + tarjan_node_list[v].index = index; + tarjan_node_list[v].low_link = index; + tarjan_stack.push(v); + tarjan_node_list[v].on_stack = true; + ++index; + + const NodeID to_node_of_only_restriction = + m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); + + for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v)) + { + const auto vprime = m_node_based_graph->GetTarget(current_edge); + + // Traverse outgoing edges + if (barrier_node_set.find(v) != barrier_node_set.end() && u != vprime) + { + // continue; + } + + if (to_node_of_only_restriction != std::numeric_limits::max() && + vprime == to_node_of_only_restriction) + { + // At an only_-restriction but not at the right turn + // continue; + } + + if (m_restriction_map.CheckIfTurnIsRestricted(u, v, vprime)) + { + // continue; + } + + if (SPECIAL_NODEID == tarjan_node_list[vprime].index) + { + recursion_stack.emplace(TarjanStackFrame(vprime, v)); + } + else + { + if (tarjan_node_list[vprime].on_stack && + tarjan_node_list[vprime].index < tarjan_node_list[v].low_link) + { + tarjan_node_list[v].low_link = tarjan_node_list[vprime].index; + } + } + } + } + else + { + processing_node_before_recursion[v] = true; + tarjan_node_list[currentFrame.parent].low_link = + std::min(tarjan_node_list[currentFrame.parent].low_link, + tarjan_node_list[v].low_link); + // after recursion, lets do cycle checking + // Check if we found a cycle. This is the bottom part of the recursion + if (tarjan_node_list[v].low_link == tarjan_node_list[v].index) + { + NodeID vprime; + do + { + vprime = tarjan_stack.top(); + tarjan_stack.pop(); + tarjan_node_list[vprime].on_stack = false; + components_index[vprime] = component_index; + ++size_of_current_component; + } while (v != vprime); + + component_size_vector.emplace_back(size_of_current_component); + + if (size_of_current_component > 1000) + { + SimpleLogger().Write() << "large component [" << component_index + << "]=" << size_of_current_component; + } + + ++component_index; + size_of_current_component = 0; + } + } + } + } + + TIMER_STOP(SCC_RUN); + SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN) / 1000. << "s"; + + size_one_counter = std::count_if(component_size_vector.begin(), component_size_vector.end(), + [](unsigned value) + { + return 1 == value; + }); + } + + std::size_t get_number_of_components() const { return component_size_vector.size(); } + + std::size_t get_size_one_count() const { return size_one_counter; } + + unsigned get_component_size(const NodeID node) const + { + return component_size_vector[components_index[node]]; + } + + unsigned get_component_id(const NodeID node) const { return components_index[node]; } +}; + +#endif /* TINY_COMPONENTS_HPP */ diff --git a/3party/osrm/osrm-backend/appveyor.yml b/3party/osrm/osrm-backend/appveyor.yml old mode 100644 new mode 100755 index 9c3dcdee24..afb8dd4061 --- a/3party/osrm/osrm-backend/appveyor.yml +++ b/3party/osrm/osrm-backend/appveyor.yml @@ -9,9 +9,6 @@ branches: only: - develop -# Operating system (build VM template) -os: Windows Server 2012 R2 - # scripts that are called at very beginning, before repo cloning init: - git config --global core.autocrlf input @@ -38,13 +35,18 @@ build_script: - SET P=c:/projects/osrm - set TBB_INSTALL_DIR=%P%/tbb - set TBB_ARCH_PLATFORM=intel64/vc12 - - cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013 + - cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_ADDITIONAL_VERSIONS=1.57 -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013 - msbuild /clp:Verbosity=minimal /nologo OSRM.sln - msbuild /clp:Verbosity=minimal /nologo tests.vcxproj + - cd %Configuration% - if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip) + - cd ..\..\profiles + - echo disk=c:\temp\stxxl,10000,wincall > .stxxl.txt + - if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip * -tzip) - set PATH=%PATH%;c:/projects/osrm/libs/bin - cd c:/projects/osrm/build/%Configuration% - datastructure-tests.exe + - algorithm-tests.exe test: off diff --git a/3party/osrm/osrm-backend/benchmarks/static_rtree.cpp b/3party/osrm/osrm-backend/benchmarks/static_rtree.cpp new file mode 100755 index 0000000000..9d883311b0 --- /dev/null +++ b/3party/osrm/osrm-backend/benchmarks/static_rtree.cpp @@ -0,0 +1,184 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "../data_structures/original_edge_data.hpp" +#include "../data_structures/query_node.hpp" +#include "../data_structures/shared_memory_vector_wrapper.hpp" +#include "../data_structures/static_rtree.hpp" +#include "../util/boost_filesystem_2_fix.hpp" +#include "../data_structures/edge_based_node.hpp" + +#include + +#include + +// Choosen by a fair W20 dice roll (this value is completely arbitrary) +constexpr unsigned RANDOM_SEED = 13; +constexpr int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION; +constexpr int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION; +constexpr int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION; +constexpr int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION; + +using RTreeLeaf = EdgeBasedNode; +using FixedPointCoordinateListPtr = std::shared_ptr>; +using BenchStaticRTree = StaticRTree::vector, false>; + +FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file) +{ + boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary); + + QueryNode current_node; + unsigned coordinate_count = 0; + nodes_input_stream.read((char *)&coordinate_count, sizeof(unsigned)); + auto coords = std::make_shared>(coordinate_count); + for (unsigned i = 0; i < coordinate_count; ++i) + { + nodes_input_stream.read((char *)¤t_node, sizeof(QueryNode)); + coords->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon); + BOOST_ASSERT((std::abs(coords->at(i).lat) >> 30) == 0); + BOOST_ASSERT((std::abs(coords->at(i).lon) >> 30) == 0); + } + nodes_input_stream.close(); + return coords; +} + +void Benchmark(BenchStaticRTree &rtree, unsigned num_queries) +{ + std::mt19937 mt_rand(RANDOM_SEED); + std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT); + std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON); + std::vector queries; + for (unsigned i = 0; i < num_queries; i++) + { + queries.emplace_back(FixedPointCoordinate(lat_udist(mt_rand), lon_udist(mt_rand))); + } + + { + const unsigned num_results = 5; + std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results + << " phantom nodes" + << "\n"; + + TIMER_START(query_phantom); + std::vector phantom_node_vector; + for (const auto &q : queries) + { + phantom_node_vector.clear(); + rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 3, num_results); + phantom_node_vector.clear(); + rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 17, num_results); + } + TIMER_STOP(query_phantom); + + std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries + << " queries." + << "\n"; + std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query." + << "\n"; + + std::cout << "#### LocateClosestEndPointForCoordinate" + << "\n"; + } + + TIMER_START(query_endpoint); + FixedPointCoordinate result; + for (const auto &q : queries) + { + rtree.LocateClosestEndPointForCoordinate(q, result, 3); + } + TIMER_STOP(query_endpoint); + + std::cout << "Took " << TIMER_MSEC(query_endpoint) << " msec for " << num_queries << " queries." + << "\n"; + std::cout << TIMER_MSEC(query_endpoint) / ((double)num_queries) << " msec/query." + << "\n"; + + std::cout << "#### FindPhantomNodeForCoordinate" + << "\n"; + + TIMER_START(query_node); + for (const auto &q : queries) + { + PhantomNode phantom; + rtree.FindPhantomNodeForCoordinate(q, phantom, 3); + } + TIMER_STOP(query_node); + + std::cout << "Took " << TIMER_MSEC(query_node) << " msec for " << num_queries << " queries." + << "\n"; + std::cout << TIMER_MSEC(query_node) / ((double)num_queries) << " msec/query." + << "\n"; + + { + const unsigned num_results = 1; + std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results + << " phantom nodes" + << "\n"; + + TIMER_START(query_phantom); + std::vector phantom_node_vector; + for (const auto &q : queries) + { + phantom_node_vector.clear(); + rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 3, num_results); + phantom_node_vector.clear(); + rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 17, num_results); + } + TIMER_STOP(query_phantom); + + std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries + << " queries." + << "\n"; + std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query." + << "\n"; + + std::cout << "#### LocateClosestEndPointForCoordinate" + << "\n"; + } +} + +int main(int argc, char **argv) +{ + if (argc < 4) + { + std::cout << "./rtree-bench file.ramIndex file.fileIndx file.nodes" + << "\n"; + return 1; + } + + const char *ramPath = argv[1]; + const char *filePath = argv[2]; + const char *nodesPath = argv[3]; + + auto coords = LoadCoordinates(nodesPath); + + BenchStaticRTree rtree(ramPath, filePath, coords); + + Benchmark(rtree, 10000); + + return 0; +} diff --git a/3party/osrm/osrm-backend/cmake/CPackDebianConfig.cmake b/3party/osrm/osrm-backend/cmake/CPackDebianConfig.cmake old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/CheckCXXCompilerFlag.cmake b/3party/osrm/osrm-backend/cmake/CheckCXXCompilerFlag.cmake old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/FindDebArch.cmake b/3party/osrm/osrm-backend/cmake/FindDebArch.cmake old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/FindLua52.cmake b/3party/osrm/osrm-backend/cmake/FindLua52.cmake old mode 100644 new mode 100755 index 04dcf7ac7f..d17fbf61d3 --- a/3party/osrm/osrm-backend/cmake/FindLua52.cmake +++ b/3party/osrm/osrm-backend/cmake/FindLua52.cmake @@ -79,3 +79,4 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua52 VERSION_VAR LUA_VERSION_STRING) mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY) + diff --git a/3party/osrm/osrm-backend/cmake/FindLuaJIT.cmake b/3party/osrm/osrm-backend/cmake/FindLuaJIT.cmake old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/FindLuabind.cmake b/3party/osrm/osrm-backend/cmake/FindLuabind.cmake old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/FindOSMPBF.cmake b/3party/osrm/osrm-backend/cmake/FindOSMPBF.cmake old mode 100644 new mode 100755 index ca310a491a..78b1d9dc82 --- a/3party/osrm/osrm-backend/cmake/FindOSMPBF.cmake +++ b/3party/osrm/osrm-backend/cmake/FindOSMPBF.cmake @@ -51,4 +51,4 @@ IF( NOT OSMPBF_FIND_QUIETLY ) ENDIF() ENDIF() -#MARK_AS_ADVANCED(OSMPBF_INCLUDE_DIR OSMPBF_LIBRARIES OSMPBF_LIBRARY OSMPBF_LIBRARY_DBG) +#MARK_AS_ADVANCED(OSMPBF_INCLUDE_DIR OSMPBF_LIBRARIES OSMPBF_LIBRARY OSMPBF_LIBRARY_DBG) diff --git a/3party/osrm/osrm-backend/cmake/FindSTXXL.cmake b/3party/osrm/osrm-backend/cmake/FindSTXXL.cmake old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/FindTBB.cmake b/3party/osrm/osrm-backend/cmake/FindTBB.cmake old mode 100644 new mode 100755 index 886d72e923..e5ca100391 --- a/3party/osrm/osrm-backend/cmake/FindTBB.cmake +++ b/3party/osrm/osrm-backend/cmake/FindTBB.cmake @@ -193,7 +193,7 @@ mark_as_advanced(TBB_INCLUDE_DIR) #-- Look for libraries # GvdB: $ENV{TBB_ARCH_PLATFORM} is set by the build script tbbvars[.bat|.sh|.csh] if (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") - set (_TBB_LIBRARY_DIR + set (_TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib/$ENV{TBB_ARCH_PLATFORM} ${_TBB_INSTALL_DIR}/$ENV{TBB_ARCH_PLATFORM}/lib ) diff --git a/3party/osrm/osrm-backend/cmake/FingerPrint-Config.cmake b/3party/osrm/osrm-backend/cmake/FingerPrint-Config.cmake old mode 100644 new mode 100755 index 7b45d5cfc0..a3325d3059 --- a/3party/osrm/osrm-backend/cmake/FingerPrint-Config.cmake +++ b/3party/osrm/osrm-backend/cmake/FingerPrint-Config.cmake @@ -1,10 +1,10 @@ -set(OLDFILE ${SOURCE_DIR}/Util/FingerPrint.cpp) +set(OLDFILE ${SOURCE_DIR}/util/fingerprint_impl.hpp) if (EXISTS ${OLDFILE}) file(REMOVE_RECURSE ${OLDFILE}) endif() file(MD5 ${SOURCE_DIR}/prepare.cpp MD5PREPARE) -file(MD5 ${SOURCE_DIR}/DataStructures/StaticRTree.h MD5RTREE) -file(MD5 ${SOURCE_DIR}/Util/GraphLoader.h MD5GRAPH) -file(MD5 ${SOURCE_DIR}/Server/DataStructures/InternalDataFacade.h MD5OBJECTS) +file(MD5 ${SOURCE_DIR}/data_structures/static_rtree.hpp MD5RTREE) +file(MD5 ${SOURCE_DIR}/util/graph_loader.hpp MD5GRAPH) +file(MD5 ${SOURCE_DIR}/server/data_structures/internal_datafacade.hpp MD5OBJECTS) -CONFIGURE_FILE( ${SOURCE_DIR}/Util/FingerPrint.cpp.in ${SOURCE_DIR}/Util/FingerPrint.cpp ) +CONFIGURE_FILE(${SOURCE_DIR}/util/fingerprint_impl.hpp.in ${SOURCE_DIR}/util/fingerprint_impl.hpp) diff --git a/3party/osrm/osrm-backend/cmake/GetGitRevisionDescription.cmake b/3party/osrm/osrm-backend/cmake/GetGitRevisionDescription.cmake old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/GetGitRevisionDescription.cmake.in b/3party/osrm/osrm-backend/cmake/GetGitRevisionDescription.cmake.in old mode 100644 new mode 100755 index 6faa374a8d..888ce13aab --- a/3party/osrm/osrm-backend/cmake/GetGitRevisionDescription.cmake.in +++ b/3party/osrm/osrm-backend/cmake/GetGitRevisionDescription.cmake.in @@ -1,4 +1,4 @@ -# +# # Internal file for GetGitRevisionDescription.cmake # # Requires CMake 2.6 or newer (uses the 'function' command) diff --git a/3party/osrm/osrm-backend/cmake/check_luabind.cmake b/3party/osrm/osrm-backend/cmake/check_luabind.cmake old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/cmake_options_script.py b/3party/osrm/osrm-backend/cmake/cmake_options_script.py old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/pkgconfig.in b/3party/osrm/osrm-backend/cmake/pkgconfig.in old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/cmake/postinst.in b/3party/osrm/osrm-backend/cmake/postinst.in old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/config/cucumber.yml b/3party/osrm/osrm-backend/config/cucumber.yml old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/Contractor/Contractor.h b/3party/osrm/osrm-backend/contractor/contractor.hpp old mode 100644 new mode 100755 similarity index 85% rename from 3party/osrm/osrm-backend/Contractor/Contractor.h rename to 3party/osrm/osrm-backend/contractor/contractor.hpp index 9e1214f630..ccfabbc8f3 --- a/3party/osrm/osrm-backend/Contractor/Contractor.h +++ b/3party/osrm/osrm-backend/contractor/contractor.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM, Dennis Luxen, others All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,20 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CONTRACTOR_H -#define CONTRACTOR_H +#ifndef CONTRACTOR_HPP +#define CONTRACTOR_HPP -#include "../DataStructures/BinaryHeap.h" -#include "../DataStructures/DeallocatingVector.h" -#include "../DataStructures/DynamicGraph.h" -#include "../DataStructures/Percent.h" -#include "../DataStructures/QueryEdge.h" -#include "../DataStructures/Range.h" -#include "../DataStructures/XORFastHash.h" -#include "../DataStructures/XORFastHashStorage.h" -#include "../Util/simple_logger.hpp" -#include "../Util/StringUtil.h" -#include "../Util/TimingUtil.h" +#include "../data_structures/binary_heap.hpp" +#include "../data_structures/deallocating_vector.hpp" +#include "../data_structures/dynamic_graph.hpp" +#include "../data_structures/percent.hpp" +#include "../data_structures/query_edge.hpp" +#include "../data_structures/xor_fast_hash.hpp" +#include "../data_structures/xor_fast_hash_storage.hpp" +#include "../util/integer_range.hpp" +#include "../util/simple_logger.hpp" +#include "../util/timing_util.hpp" #include "../typedefs.h" #include @@ -93,9 +92,11 @@ class Contractor }; using ContractorGraph = DynamicGraph; - // using ContractorHeap = BinaryHeap + // using ContractorHeap = BinaryHeap // >; - using ContractorHeap = BinaryHeap>; + using ContractorHeap = + BinaryHeap>; using ContractorEdge = ContractorGraph::InputEdge; struct ContractorThreadData @@ -132,15 +133,14 @@ class Contractor bool is_independent : 1; }; - struct ThreadDataContainer { - explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {} + explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {} - inline ContractorThreadData* getThreadData() + inline ContractorThreadData *getThreadData() { bool exists = false; - auto& ref = data.local(exists); + auto &ref = data.local(exists); if (!exists) { ref = std::make_shared(number_of_nodes); @@ -150,7 +150,8 @@ class Contractor } int number_of_nodes; - using EnumerableThreadData = tbb::enumerable_thread_specific>; + using EnumerableThreadData = + tbb::enumerable_thread_specific>; EnumerableThreadData data; }; @@ -163,29 +164,25 @@ class Contractor const auto dend = input_edge_list.dend(); for (auto diter = input_edge_list.dbegin(); diter != dend; ++diter) { - BOOST_ASSERT_MSG(static_cast(std::max(diter->weight, 1)) > 0, "edge distance < 1"); + BOOST_ASSERT_MSG(static_cast(std::max(diter->weight, 1)) > 0, + "edge distance < 1"); #ifndef NDEBUG if (static_cast(std::max(diter->weight, 1)) > 24 * 60 * 60 * 10) { - SimpleLogger().Write(logWARNING) << "Edge weight large -> " - << static_cast(std::max(diter->weight, 1)); + SimpleLogger().Write(logWARNING) + << "Edge weight large -> " + << static_cast(std::max(diter->weight, 1)); } #endif edges.emplace_back(diter->source, diter->target, - static_cast(std::max(diter->weight, 1)), - 1, - diter->edge_id, - false, - diter->forward ? true : false, - diter->backward ? true : false); + static_cast(std::max(diter->weight, 1)), 1, + diter->edge_id, false, diter->forward ? true : false, + diter->backward ? true : false); edges.emplace_back(diter->target, diter->source, - static_cast(std::max(diter->weight, 1)), - 1, - diter->edge_id, - false, - diter->backward ? true : false, - diter->forward ? true : false); + static_cast(std::max(diter->weight, 1)), 1, + diter->edge_id, false, diter->backward ? true : false, + diter->forward ? true : false); } // clear input vector input_edge_list.clear(); @@ -283,20 +280,20 @@ class Contractor std::cout << "contractor finished initalization" << std::endl; } - ~Contractor() { } + ~Contractor() {} void Run() { // for the preperation we can use a big grain size, which is much faster (probably cache) - constexpr size_t InitGrainSize = 100000; - constexpr size_t PQGrainSize = 100000; + constexpr size_t InitGrainSize = 100000; + constexpr size_t PQGrainSize = 100000; // auto_partitioner will automatically increase the blocksize if we have // a lot of data. It is *important* for the last loop iterations // (which have a very small dataset) that it is devisible. constexpr size_t IndependentGrainSize = 1; - constexpr size_t ContractGrainSize = 1; - constexpr size_t NeighboursGrainSize = 1; - constexpr size_t DeleteGrainSize = 1; + constexpr size_t ContractGrainSize = 1; + constexpr size_t NeighboursGrainSize = 1; + constexpr size_t DeleteGrainSize = 1; const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes(); Percent p(number_of_nodes); @@ -308,30 +305,28 @@ class Contractor std::vector node_priorities(number_of_nodes); std::vector node_data(number_of_nodes); - // initialize priorities in parallel tbb::parallel_for(tbb::blocked_range(0, number_of_nodes, InitGrainSize), - [&remaining_nodes](const tbb::blocked_range& range) - { - for (int x = range.begin(); x != range.end(); ++x) - { - remaining_nodes[x].id = x; - } - } - ); - + [&remaining_nodes](const tbb::blocked_range &range) + { + for (int x = range.begin(); x != range.end(); ++x) + { + remaining_nodes[x].id = x; + } + }); std::cout << "initializing elimination PQ ..." << std::flush; tbb::parallel_for(tbb::blocked_range(0, number_of_nodes, PQGrainSize), - [this, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range& range) - { - ContractorThreadData *data = thread_data_list.getThreadData(); - for (int x = range.begin(); x != range.end(); ++x) - { - node_priorities[x] = this->EvaluateNodePriority(data, &node_data[x], x); - } - } - ); + [this, &node_priorities, &node_data, &thread_data_list]( + const tbb::blocked_range &range) + { + ContractorThreadData *data = thread_data_list.getThreadData(); + for (int x = range.begin(); x != range.end(); ++x) + { + node_priorities[x] = + this->EvaluateNodePriority(data, &node_data[x], x); + } + }); std::cout << "ok" << std::endl << "preprocessing " << number_of_nodes << " nodes ..." << std::flush; @@ -369,7 +364,8 @@ class Contractor remaining_nodes[new_node_id].id = new_node_id; } // walk over all nodes - for (const auto i : osrm::irange(0, contractor_graph->GetNumberOfNodes())) + for (const auto i : + osrm::irange(0, contractor_graph->GetNumberOfNodes())) { const NodeID source = i; for (auto current_edge : contractor_graph->GetAdjacentEdgeRange(source)) @@ -385,11 +381,9 @@ class Contractor { // node is not yet contracted. // add (renumbered) outgoing edges to new DynamicGraph. - ContractorEdge new_edge = { - new_node_id_from_orig_id_map[source], - new_node_id_from_orig_id_map[target], - data - }; + ContractorEdge new_edge = {new_node_id_from_orig_id_map[source], + new_node_id_from_orig_id_map[target], + data}; new_edge.data.is_original_via_node_ID = true; BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[source], @@ -428,28 +422,30 @@ class Contractor const int last = (int)remaining_nodes.size(); tbb::parallel_for(tbb::blocked_range(0, last, IndependentGrainSize), - [this, &node_priorities, &remaining_nodes, &thread_data_list](const tbb::blocked_range& range) - { - ContractorThreadData *data = thread_data_list.getThreadData(); - // determine independent node set - for (int i = range.begin(); i != range.end(); ++i) - { - const NodeID node = remaining_nodes[i].id; - remaining_nodes[i].is_independent = - this->IsNodeIndependent(node_priorities, data, node); - } - } - ); + [this, &node_priorities, &remaining_nodes, &thread_data_list]( + const tbb::blocked_range &range) + { + ContractorThreadData *data = thread_data_list.getThreadData(); + // determine independent node set + for (int i = range.begin(); i != range.end(); ++i) + { + const NodeID node = remaining_nodes[i].id; + remaining_nodes[i].is_independent = + this->IsNodeIndependent(node_priorities, data, node); + } + }); - const auto first = stable_partition(remaining_nodes.begin(), - remaining_nodes.end(), + const auto first = stable_partition(remaining_nodes.begin(), remaining_nodes.end(), [](RemainingNodeData node_data) - { return !node_data.is_independent; }); + { + return !node_data.is_independent; + }); const int first_independent_node = static_cast(first - remaining_nodes.begin()); // contract independent nodes - tbb::parallel_for(tbb::blocked_range(first_independent_node, last, ContractGrainSize), - [this, &remaining_nodes, &thread_data_list](const tbb::blocked_range& range) + tbb::parallel_for( + tbb::blocked_range(first_independent_node, last, ContractGrainSize), + [this, &remaining_nodes, &thread_data_list](const tbb::blocked_range &range) { ContractorThreadData *data = thread_data_list.getThreadData(); for (int position = range.begin(); position != range.end(); ++position) @@ -457,19 +453,18 @@ class Contractor const NodeID x = remaining_nodes[position].id; this->ContractNode(data, x); } - } - ); + }); // make sure we really sort each block - tbb::parallel_for(thread_data_list.data.range(), - [&](const ThreadDataContainer::EnumerableThreadData::range_type& range) + tbb::parallel_for( + thread_data_list.data.range(), + [&](const ThreadDataContainer::EnumerableThreadData::range_type &range) { - for (auto& data : range) - std::sort(data->inserted_edges.begin(), - data->inserted_edges.end()); - } - ); - tbb::parallel_for(tbb::blocked_range(first_independent_node, last, DeleteGrainSize), - [this, &remaining_nodes, &thread_data_list](const tbb::blocked_range& range) + for (auto &data : range) + std::sort(data->inserted_edges.begin(), data->inserted_edges.end()); + }); + tbb::parallel_for( + tbb::blocked_range(first_independent_node, last, DeleteGrainSize), + [this, &remaining_nodes, &thread_data_list](const tbb::blocked_range &range) { ContractorThreadData *data = thread_data_list.getThreadData(); for (int position = range.begin(); position != range.end(); ++position) @@ -477,15 +472,15 @@ class Contractor const NodeID x = remaining_nodes[position].id; this->DeleteIncomingEdges(data, x); } - } - ); + }); // insert new edges - for (auto& data : thread_data_list.data) + for (auto &data : thread_data_list.data) { for (const ContractorEdge &edge : data->inserted_edges) { - const EdgeID current_edge_ID = contractor_graph->FindEdge(edge.source, edge.target); + const EdgeID current_edge_ID = + contractor_graph->FindEdge(edge.source, edge.target); if (current_edge_ID < contractor_graph->EndEdges(edge.source)) { ContractorGraph::EdgeData ¤t_data = @@ -504,8 +499,10 @@ class Contractor data->inserted_edges.clear(); } - tbb::parallel_for(tbb::blocked_range(first_independent_node, last, NeighboursGrainSize), - [this, &remaining_nodes, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range& range) + tbb::parallel_for( + tbb::blocked_range(first_independent_node, last, NeighboursGrainSize), + [this, &remaining_nodes, &node_priorities, &node_data, &thread_data_list]( + const tbb::blocked_range &range) { ContractorThreadData *data = thread_data_list.getThreadData(); for (int position = range.begin(); position != range.end(); ++position) @@ -513,8 +510,7 @@ class Contractor NodeID x = remaining_nodes[position].id; this->UpdateNodeNeighbours(node_priorities, node_data, data, x); } - } - ); + }); // remove contracted nodes from the pool number_of_contracted_nodes += last - first_independent_node; @@ -775,17 +771,11 @@ class Contractor { inserted_edges.emplace_back(source, target, path_distance, out_data.originalEdges + in_data.originalEdges, - node, - true, - true, - false); + node, true, true, false); inserted_edges.emplace_back(target, source, path_distance, out_data.originalEdges + in_data.originalEdges, - node, - true, - false, - true); + node, true, false, true); } } } @@ -884,10 +874,9 @@ class Contractor return true; } - inline bool IsNodeIndependent( - const std::vector &priorities, - ContractorThreadData *const data, - NodeID node) const + inline bool IsNodeIndependent(const std::vector &priorities, + ContractorThreadData *const data, + NodeID node) const { const float priority = priorities[node]; @@ -970,4 +959,4 @@ class Contractor XORFastHash fast_hash; }; -#endif // CONTRACTOR_H +#endif // CONTRACTOR_HPP diff --git a/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.cpp b/3party/osrm/osrm-backend/contractor/edge_based_graph_factory.cpp old mode 100644 new mode 100755 similarity index 62% rename from 3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.cpp rename to 3party/osrm/osrm-backend/contractor/edge_based_graph_factory.cpp index fa0c4995e0..268bb9f8d0 --- a/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.cpp +++ b/3party/osrm/osrm-backend/contractor/edge_based_graph_factory.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM, Dennis Luxen, others All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,14 +25,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "EdgeBasedGraphFactory.h" -#include "../Algorithms/BFSComponentExplorer.h" -#include "../DataStructures/Percent.h" -#include "../DataStructures/Range.h" -#include "../Util/compute_angle.hpp" -#include "../Util/LuaUtil.h" -#include "../Util/simple_logger.hpp" -#include "../Util/TimingUtil.h" +#include "edge_based_graph_factory.hpp" +#include "../algorithms/tiny_components.hpp" +#include "../data_structures/percent.hpp" +#include "../util/compute_angle.hpp" +#include "../util/integer_range.hpp" +#include "../util/lua_util.hpp" +#include "../util/simple_logger.hpp" +#include "../util/timing_util.hpp" #include @@ -42,19 +42,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. EdgeBasedGraphFactory::EdgeBasedGraphFactory( const std::shared_ptr &node_based_graph, - const std::shared_ptr &node_based_graph_origin, std::unique_ptr restriction_map, std::vector &barrier_node_list, std::vector &traffic_light_node_list, - std::vector &node_info_list, + std::vector &node_info_list, SpeedProfileProperties &speed_profile) : speed_profile(speed_profile), m_number_of_edge_based_nodes(std::numeric_limits::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) + m_restriction_map(std::move(restriction_map)), max_id(0), removed_node_count(0) { - // insert into unordered sets for fast lookup m_barrier_nodes.insert(barrier_node_list.begin(), barrier_node_list.end()); m_traffic_lights.insert(traffic_light_node_list.begin(), traffic_light_node_list.end()); @@ -80,36 +77,25 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector &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) +void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, + const NodeID node_v, + const unsigned component_id) { // merge edges together into one EdgeBasedNode BOOST_ASSERT(node_u != SPECIAL_NODEID); BOOST_ASSERT(node_v != SPECIAL_NODEID); // find forward edge id and - const EdgeID e1 = m_node_based_graph->FindEdge(node_u, node_v); - BOOST_ASSERT(e1 != SPECIAL_EDGEID); + const EdgeID edge_id_1 = m_node_based_graph->FindEdge(node_u, node_v); + BOOST_ASSERT(edge_id_1 != SPECIAL_EDGEID); - const EdgeData &forward_data = m_node_based_graph->GetEdgeData(e1); + const EdgeData &forward_data = m_node_based_graph->GetEdgeData(edge_id_1); // find reverse edge id and - const EdgeID e2 = m_node_based_graph->FindEdge(node_v, node_u); + const EdgeID edge_id_2 = m_node_based_graph->FindEdge(node_v, node_u); + BOOST_ASSERT(edge_id_2 != SPECIAL_EDGEID); -#ifndef NDEBUG - if (e2 == m_node_based_graph->EndEdges(node_v)) - { - SimpleLogger().Write(logWARNING) << "Did not find edge (" << node_v << "," << node_u << ")"; - } -#endif - BOOST_ASSERT(e2 != SPECIAL_EDGEID); - BOOST_ASSERT(e2 < m_node_based_graph->EndEdges(node_v)); - const EdgeData &reverse_data = m_node_based_graph->GetEdgeData(e2); + const EdgeData &reverse_data = m_node_based_graph->GetEdgeData(edge_id_2); if (forward_data.edgeBasedNodeID == SPECIAL_NODEID && reverse_data.edgeBasedNodeID == SPECIAL_NODEID) @@ -117,20 +103,20 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod return; } - BOOST_ASSERT(m_geometry_compressor.HasEntryForID(e1) == - m_geometry_compressor.HasEntryForID(e2)); - if (m_geometry_compressor.HasEntryForID(e1)) + BOOST_ASSERT(m_geometry_compressor.HasEntryForID(edge_id_1) == + m_geometry_compressor.HasEntryForID(edge_id_2)); + if (m_geometry_compressor.HasEntryForID(edge_id_1)) { - BOOST_ASSERT(m_geometry_compressor.HasEntryForID(e2)); + BOOST_ASSERT(m_geometry_compressor.HasEntryForID(edge_id_2)); // reconstruct geometry and put in each individual edge with its offset const std::vector &forward_geometry = - m_geometry_compressor.GetBucketReference(e1); + m_geometry_compressor.GetBucketReference(edge_id_1); const std::vector &reverse_geometry = - m_geometry_compressor.GetBucketReference(e2); + m_geometry_compressor.GetBucketReference(edge_id_2); BOOST_ASSERT(forward_geometry.size() == reverse_geometry.size()); BOOST_ASSERT(0 != forward_geometry.size()); - const unsigned geometry_size = forward_geometry.size(); + const unsigned geometry_size = static_cast(forward_geometry.size()); BOOST_ASSERT(geometry_size > 1); // reconstruct bidirectional edge with individual weights and put each into the NN index @@ -178,22 +164,13 @@ 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.way_id, - reverse_data.way_id, - forward_data.edgeBasedNodeID, - reverse_data.edgeBasedNodeID, - current_edge_source_coordinate_id, - current_edge_target_coordinate_id, - forward_data.nameID, - forward_geometry[i].second, - reverse_geometry[geometry_size - 1 - i].second, - forward_dist_prefix_sum[i], - reverse_dist_prefix_sum[i], - m_geometry_compressor.GetPositionForID(e1), - i, - belongs_to_tiny_cc, - forward_data.travel_mode, - reverse_data.travel_mode); + m_edge_based_node_list.emplace_back( + forward_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID, + current_edge_source_coordinate_id, current_edge_target_coordinate_id, + forward_data.nameID, forward_geometry[i].second, + reverse_geometry[geometry_size - 1 - i].second, forward_dist_prefix_sum[i], + reverse_dist_prefix_sum[i], m_geometry_compressor.GetPositionForID(edge_id_1), + component_id, i, forward_data.travel_mode, reverse_data.travel_mode); current_edge_source_coordinate_id = current_edge_target_coordinate_id; BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed()); @@ -210,7 +187,7 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod } else { - BOOST_ASSERT(!m_geometry_compressor.HasEntryForID(e2)); + BOOST_ASSERT(!m_geometry_compressor.HasEntryForID(edge_id_2)); if (forward_data.edgeBasedNodeID != SPECIAL_NODEID) { @@ -232,22 +209,10 @@ 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.way_id, - reverse_data.way_id, - forward_data.edgeBasedNodeID, - reverse_data.edgeBasedNodeID, - node_u, - node_v, - forward_data.nameID, - forward_data.distance, - reverse_data.distance, - 0, - 0, - SPECIAL_EDGEID, - 0, - belongs_to_tiny_cc, - forward_data.travel_mode, - reverse_data.travel_mode); + m_edge_based_node_list.emplace_back( + forward_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID, node_u, node_v, + forward_data.nameID, forward_data.distance, reverse_data.distance, 0, 0, SPECIAL_EDGEID, + component_id, 0, forward_data.travel_mode, reverse_data.travel_mode); BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed()); } } @@ -255,7 +220,8 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod void EdgeBasedGraphFactory::FlushVectorToStream( std::ofstream &edge_data_file, std::vector &original_edge_data_vector) const { - if (original_edge_data_vector.empty()) { + if (original_edge_data_vector.empty()) + { return; } edge_data_file.write((char *)&(original_edge_data_vector[0]), @@ -284,10 +250,6 @@ 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:"; @@ -295,7 +257,6 @@ 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() @@ -306,7 +267,6 @@ void EdgeBasedGraphFactory::CompressGeometry() const unsigned original_number_of_edges = m_node_based_graph->GetNumberOfEdges(); Percent progress(original_number_of_nodes); - unsigned removed_node_count = 0; for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes)) { @@ -348,7 +308,6 @@ void EdgeBasedGraphFactory::CompressGeometry() BOOST_ASSERT(node_u != node_v); const EdgeID forward_e1 = m_node_based_graph->FindEdge(node_u, node_v); - BOOST_ASSERT(m_node_based_graph->EndEdges(node_u) != forward_e1); BOOST_ASSERT(SPECIAL_EDGEID != forward_e1); BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(forward_e1)); const EdgeID reverse_e1 = m_node_based_graph->FindEdge(node_w, node_v); @@ -358,15 +317,13 @@ void EdgeBasedGraphFactory::CompressGeometry() const EdgeData &fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1); const EdgeData &rev_edge_data1 = m_node_based_graph->GetEdgeData(reverse_e1); - if ((m_node_based_graph->FindEdge(node_u, node_w) != m_node_based_graph->EndEdges(node_u)) || - (m_node_based_graph->FindEdge(node_w, node_u) != m_node_based_graph->EndEdges(node_w))) + if (m_node_based_graph->FindEdgeInEitherDirection(node_u, node_w) != SPECIAL_EDGEID) { continue; } if ( // TODO: rename to IsCompatibleTo - fwd_edge_data1.IsEqualTo(fwd_edge_data2) && - rev_edge_data1.IsEqualTo(rev_edge_data2)) + fwd_edge_data1.IsEqualTo(fwd_edge_data2) && rev_edge_data1.IsEqualTo(rev_edge_data2)) { // Get distances before graph is modified const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance; @@ -381,13 +338,12 @@ void EdgeBasedGraphFactory::CompressGeometry() BOOST_ASSERT(0 != reverse_weight1); BOOST_ASSERT(0 != forward_weight2); - const bool add_traffic_signal_penalty = - (m_traffic_lights.find(node_v) != m_traffic_lights.end()); + const bool has_node_penalty = m_traffic_lights.find(node_v) != m_traffic_lights.end(); // add weight of e2's to e1 m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance; m_node_based_graph->GetEdgeData(reverse_e1).distance += rev_edge_data2.distance; - if (add_traffic_signal_penalty) + if (has_node_penalty) { m_node_based_graph->GetEdgeData(forward_e1).distance += speed_profile.traffic_signal_penalty; @@ -405,28 +361,21 @@ void EdgeBasedGraphFactory::CompressGeometry() // update any involved turn restrictions m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w); - m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w); + m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w, + m_node_based_graph); m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u); - m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u); + m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u, + m_node_based_graph); // store compressed geometry in container m_geometry_compressor.CompressEdge( - forward_e1, - forward_e2, - node_v, - node_w, - forward_weight1 + - (add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0), + forward_e1, forward_e2, node_v, node_w, + forward_weight1 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0), forward_weight2); m_geometry_compressor.CompressEdge( - reverse_e1, - reverse_e2, - node_v, - node_u, - reverse_weight1, - reverse_weight2 + - (add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0)); + reverse_e1, reverse_e2, node_v, node_u, reverse_weight1, + reverse_weight2 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0)); ++removed_node_count; BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e1).nameID == @@ -439,7 +388,7 @@ void EdgeBasedGraphFactory::CompressGeometry() unsigned new_node_count = 0; unsigned new_edge_count = 0; - for(const auto i : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes())) + for (const auto i : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes())) { if (m_node_based_graph->GetOutDegree(i) > 0) { @@ -448,10 +397,10 @@ void EdgeBasedGraphFactory::CompressGeometry() } } SimpleLogger().Write() << "new nodes: " << new_node_count << ", edges " << new_edge_count; - SimpleLogger().Write() << "Node compression ratio: " << new_node_count / - (double)original_number_of_nodes; - SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count / - (double)original_number_of_edges; + SimpleLogger().Write() << "Node compression ratio: " + << new_node_count / (double)original_number_of_nodes; + SimpleLogger().Write() << "Edge compression ratio: " + << new_edge_count / (double)original_number_of_edges; } /** @@ -461,10 +410,9 @@ void EdgeBasedGraphFactory::RenumberEdges() { // renumber edge based node IDs unsigned numbered_edges_count = 0; - for (NodeID current_node = 0; current_node < m_node_based_graph->GetNumberOfNodes(); - ++current_node) + for (const auto current_node : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes())) { - for (EdgeID current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node)) + for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node)) { EdgeData &edge_data = m_node_based_graph->GetEdgeData(current_edge); if (!edge_data.forward) @@ -482,157 +430,77 @@ 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 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 & 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. */ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes() { - SimpleLogger().Write() << "Identifying components of the road network"; + SimpleLogger().Write() << "Identifying components of the (compressed) road network"; // Run a BFS on the undirected graph and identify small components - BFSComponentExplorer component_explorer( - *m_node_based_graph, *m_restriction_map, m_barrier_nodes); + TarjanSCC component_explorer(m_node_based_graph, *m_restriction_map, + m_barrier_nodes); component_explorer.run(); - SimpleLogger().Write() << "identified: " << component_explorer.GetNumberOfComponents() - << " many components"; + SimpleLogger().Write() << "identified: " + << component_explorer.get_number_of_components() - removed_node_count + << " (compressed) components"; + SimpleLogger().Write() << "identified " + << component_explorer.get_size_one_count() - removed_node_count + << " (compressed) SCCs of size 1"; SimpleLogger().Write() << "generating edge-expanded nodes"; Percent progress(m_node_based_graph->GetNumberOfNodes()); // loop over all edges and generate new set of nodes - for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u) + for (const auto node_u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes())) { - BOOST_ASSERT(u != SPECIAL_NODEID); - BOOST_ASSERT(u < m_node_based_graph->GetNumberOfNodes()); - progress.printStatus(u); - for (EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u)) + BOOST_ASSERT(node_u != SPECIAL_NODEID); + BOOST_ASSERT(node_u < m_node_based_graph->GetNumberOfNodes()); + progress.printStatus(node_u); + for (EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(node_u)) { const EdgeData &edge_data = m_node_based_graph->GetEdgeData(e1); BOOST_ASSERT(e1 != SPECIAL_EDGEID); - const NodeID v = m_node_based_graph->GetTarget(e1); + const NodeID node_v = m_node_based_graph->GetTarget(e1); - BOOST_ASSERT(SPECIAL_NODEID != v); + BOOST_ASSERT(SPECIAL_NODEID != node_v); // pick only every other edge - if (u > v) + if (node_u > node_v) { continue; } - BOOST_ASSERT(u < v); + BOOST_ASSERT(node_u < node_v); // Note: edges that end on barrier nodes or on a turn restriction // may actually be in two distinct components. We choose the smallest - const unsigned size_of_component = std::min(component_explorer.GetComponentSize(u), - component_explorer.GetComponentSize(v)); + const unsigned size_of_component = + std::min(component_explorer.get_component_size(node_u), + component_explorer.get_component_size(node_v)); + + const unsigned id_of_smaller_component = [node_u, node_v, &component_explorer] + { + if (component_explorer.get_component_size(node_u) < + component_explorer.get_component_size(node_v)) + { + return component_explorer.get_component_id(node_u); + } + return component_explorer.get_component_id(node_v); + }(); + + const bool component_is_tiny = size_of_component < 1000; - const bool component_is_tiny = (size_of_component < 1000); if (edge_data.edgeBasedNodeID == SPECIAL_NODEID) { - InsertEdgeBasedNode(v, u, component_is_tiny); + InsertEdgeBasedNode(node_v, node_u, + (component_is_tiny ? id_of_smaller_component + 1 : 0)); } else { - InsertEdgeBasedNode(u, v, component_is_tiny); + InsertEdgeBasedNode(node_u, node_v, + (component_is_tiny ? id_of_smaller_component + 1 : 0)); } } } @@ -644,9 +512,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes() /** * Actually it also generates OriginalEdgeData and serializes them... */ -void -EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename, - lua_State *lua_state) +void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( + const std::string &original_edge_data_filename, lua_State *lua_state) { SimpleLogger().Write() << "generating edge-expanded edges"; @@ -671,10 +538,10 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg Percent progress(m_node_based_graph->GetNumberOfNodes()); - for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u) + for (const auto node_u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes())) { - progress.printStatus(u); - for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u)) + progress.printStatus(node_u); + for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(node_u)) { if (!m_node_based_graph->GetEdgeData(e1).forward) { @@ -682,21 +549,21 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg } ++node_based_edge_counter; - const NodeID v = m_node_based_graph->GetTarget(e1); - const NodeID to_node_of_only_restriction = - m_restriction_map->CheckForEmanatingIsOnlyTurn(u, v); - const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); + const NodeID node_v = m_node_based_graph->GetTarget(e1); + const NodeID only_restriction_to_node = + m_restriction_map->CheckForEmanatingIsOnlyTurn(node_u, node_v); + const bool is_barrier_node = m_barrier_nodes.find(node_v) != m_barrier_nodes.end(); - for (EdgeID e2 : m_node_based_graph->GetAdjacentEdgeRange(v)) + for (const EdgeID e2 : m_node_based_graph->GetAdjacentEdgeRange(node_v)) { if (!m_node_based_graph->GetEdgeData(e2).forward) { continue; } - const NodeID w = m_node_based_graph->GetTarget(e2); + const NodeID node_w = m_node_based_graph->GetTarget(e2); - if ((to_node_of_only_restriction != SPECIAL_NODEID) && - (w != to_node_of_only_restriction)) + if ((only_restriction_to_node != SPECIAL_NODEID) && + (node_w != only_restriction_to_node)) { // We are at an only_-restriction but not at the right turn. ++restricted_turns_counter; @@ -705,7 +572,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg if (is_barrier_node) { - if (u != w) + if (node_u != node_w) { ++skipped_barrier_turns_counter; continue; @@ -713,7 +580,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg } else { - if ((u == w) && (m_node_based_graph->GetOutDegree(v) > 1)) + if ((node_u == node_w) && (m_node_based_graph->GetOutDegree(node_v) > 1)) { ++skipped_uturns_counter; continue; @@ -722,9 +589,9 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg // only add an edge if turn is not a U-turn except when it is // at the end of a dead-end street - if (m_restriction_map->CheckIfTurnIsRestricted(u, v, w) && - (to_node_of_only_restriction == SPECIAL_NODEID) && - (w != to_node_of_only_restriction)) + if (m_restriction_map->CheckIfTurnIsRestricted(node_u, node_v, node_w) && + (only_restriction_to_node == SPECIAL_NODEID) && + (node_w != only_restriction_to_node)) { // We are at an only_-restriction but not at the right turn. ++restricted_turns_counter; @@ -741,26 +608,28 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg // the following is the core of the loop. unsigned distance = edge_data1.distance; - if (m_traffic_lights.find(v) != m_traffic_lights.end()) + if (m_traffic_lights.find(node_v) != m_traffic_lights.end()) { distance += speed_profile.traffic_signal_penalty; } // unpack last node of first segment if packed - const auto first_coordinate = m_node_info_list[(m_geometry_compressor.HasEntryForID(e1) ? - m_geometry_compressor.GetLastNodeIDOfBucket(e1) : - u)]; + const auto first_coordinate = + m_node_info_list[(m_geometry_compressor.HasEntryForID(e1) + ? m_geometry_compressor.GetLastNodeIDOfBucket(e1) + : node_u)]; // unpack first node of second segment if packed - const auto third_coordinate = m_node_info_list[(m_geometry_compressor.HasEntryForID(e2) ? - m_geometry_compressor.GetFirstNodeIDOfBucket(e2) : - w)]; + const auto third_coordinate = + m_node_info_list[(m_geometry_compressor.HasEntryForID(e2) + ? m_geometry_compressor.GetFirstNodeIDOfBucket(e2) + : node_w)]; const double turn_angle = ComputeAngle::OfThreeFixedPointCoordinates( - first_coordinate, m_node_info_list[v], third_coordinate); + first_coordinate, m_node_info_list[node_v], third_coordinate); const int turn_penalty = GetTurnPenalty(turn_angle, lua_state); - TurnInstruction turn_instruction = AnalyzeTurn(u, v, w, turn_angle); + TurnInstruction turn_instruction = AnalyzeTurn(node_u, node_v, node_w, turn_angle); if (turn_instruction == TurnInstruction::UTurn) { distance += speed_profile.u_turn_penalty; @@ -775,10 +644,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg } original_edge_data_vector.emplace_back( - (edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v), - edge_data1.nameID, - turn_instruction, - edge_is_compressed, + (edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : node_v), + edge_data1.nameID, turn_instruction, edge_is_compressed, edge_data2.travel_mode); ++original_edges_counter; @@ -791,12 +658,9 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg BOOST_ASSERT(SPECIAL_NODEID != edge_data1.edgeBasedNodeID); BOOST_ASSERT(SPECIAL_NODEID != edge_data2.edgeBasedNodeID); - m_edge_based_edge_list.emplace_back(EdgeBasedEdge(edge_data1.edgeBasedNodeID, - edge_data2.edgeBasedNodeID, - m_edge_based_edge_list.size(), - distance, - true, - false)); + m_edge_based_edge_list.emplace_back( + EdgeBasedEdge(edge_data1.edgeBasedNodeID, edge_data2.edgeBasedNodeID, + m_edge_based_edge_list.size(), distance, true, false)); } } } @@ -827,7 +691,10 @@ int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) co // call lua profile to compute turn penalty return luabind::call_function(lua_state, "turn_function", 180. - angle); } - catch (const luabind::error &er) { SimpleLogger().Write(logWARNING) << er.what(); } + catch (const luabind::error &er) + { + SimpleLogger().Write(logWARNING) << er.what(); + } } return 0; } @@ -835,8 +702,7 @@ int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) co TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID node_u, const NodeID node_v, const NodeID node_w, - const double angle) - const + const double angle) const { if (node_u == node_w) { diff --git a/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.h b/3party/osrm/osrm-backend/contractor/edge_based_graph_factory.hpp old mode 100644 new mode 100755 similarity index 78% rename from 3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.h rename to 3party/osrm/osrm-backend/contractor/edge_based_graph_factory.hpp index 2362301794..95b65babc4 --- a/3party/osrm/osrm-backend/Contractor/EdgeBasedGraphFactory.h +++ b/3party/osrm/osrm-backend/contractor/edge_based_graph_factory.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM, Dennis Luxen, others All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -27,19 +27,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This class constructs the edge-expanded routing graph -#ifndef EDGEBASEDGRAPHFACTORY_H_ -#define EDGEBASEDGRAPHFACTORY_H_ +#ifndef EDGE_BASED_GRAPH_FACTORY_HPP_ +#define EDGE_BASED_GRAPH_FACTORY_HPP_ +#include "geometry_compressor.hpp" #include "../typedefs.h" -#include "../DataStructures/DeallocatingVector.h" -#include "../DataStructures/EdgeBasedNode.h" -#include "../DataStructures/OriginalEdgeData.h" -#include "../DataStructures/QueryNode.h" -#include "../DataStructures/TurnInstructions.h" -#include "../DataStructures/NodeBasedGraph.h" -#include "../DataStructures/RestrictionMap.h" -#include "../DataStructures/EdgeBasedNodeData.h" -#include "GeometryCompressor.h" +#include "../data_structures/deallocating_vector.hpp" +#include "../data_structures/edge_based_node.hpp" +#include "../data_structures/original_edge_data.hpp" +#include "../data_structures/query_node.hpp" +#include "../data_structures/turn_instructions.hpp" +#include "../data_structures/node_based_graph.hpp" +#include "../data_structures/restriction_map.hpp" #include #include @@ -61,11 +60,10 @@ class EdgeBasedGraphFactory struct SpeedProfileProperties; explicit EdgeBasedGraphFactory(const std::shared_ptr &node_based_graph, - const std::shared_ptr &node_based_graph_origin, std::unique_ptr restricion_map, std::vector &barrier_node_list, std::vector &traffic_light_node_list, - std::vector &m_node_info_list, + std::vector &node_info_list, SpeedProfileProperties &speed_profile); void Run(const std::string &original_edge_data_filename, @@ -76,8 +74,6 @@ class EdgeBasedGraphFactory void GetEdgeBasedNodes(std::vector &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; @@ -101,33 +97,32 @@ class EdgeBasedGraphFactory unsigned m_number_of_edge_based_nodes; - std::vector m_node_info_list; + std::vector m_node_info_list; std::vector m_edge_based_node_list; DeallocatingVector m_edge_based_edge_list; std::shared_ptr m_node_based_graph; - std::shared_ptr m_node_based_graph_origin; std::unordered_set m_barrier_nodes; std::unordered_set m_traffic_lights; std::unique_ptr m_restriction_map; - std::vector 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); - void InsertEdgeBasedNode(const NodeID u, const NodeID v, const bool belongsToTinyComponent); + void InsertEdgeBasedNode(const NodeID u, const NodeID v, const unsigned component_id); void FlushVectorToStream(std::ofstream &edge_data_file, std::vector &original_edge_data_vector) const; NodeID max_id; + std::size_t removed_node_count; + }; -#endif /* EDGEBASEDGRAPHFACTORY_H_ */ +#endif /* EDGE_BASED_GRAPH_FACTORY_HPP_ */ diff --git a/3party/osrm/osrm-backend/Contractor/GeometryCompressor.cpp b/3party/osrm/osrm-backend/contractor/geometry_compressor.cpp old mode 100644 new mode 100755 similarity index 89% rename from 3party/osrm/osrm-backend/Contractor/GeometryCompressor.cpp rename to 3party/osrm/osrm-backend/contractor/geometry_compressor.cpp index be4dc7afd5..3997cdc99d --- a/3party/osrm/osrm-backend/Contractor/GeometryCompressor.cpp +++ b/3party/osrm/osrm-backend/contractor/geometry_compressor.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "GeometryCompressor.h" -#include "../Util/simple_logger.hpp" +#include "geometry_compressor.hpp" +#include "../util/simple_logger.hpp" #include #include @@ -35,9 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -int free_list_maximum = 0; -int UniqueNumber() { return ++free_list_maximum; } - GeometryCompressor::GeometryCompressor() { m_free_list.reserve(100); @@ -174,8 +171,8 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1, m_compressed_geometries[list_to_remove_index]; // found an existing list, append it to the list of edge_id_1 - edge_bucket_list1.insert( - edge_bucket_list1.end(), edge_bucket_list2.begin(), edge_bucket_list2.end()); + edge_bucket_list1.insert(edge_bucket_list1.end(), edge_bucket_list2.begin(), + edge_bucket_list2.end()); // remove the list of edge_id_2 m_edge_id_to_list_index_map.erase(edge_id_2); @@ -211,9 +208,8 @@ void GeometryCompressor::PrintStatistics() const "\n compressed edges: " << compressed_edges << "\n compressed geometries: " << compressed_geometries << "\n longest chain length: " << longest_chain_length - << "\n cmpr ratio: " - << ((float)compressed_edges / - std::max(compressed_geometries, (uint64_t)1)) + << "\n cmpr ratio: " << ((float)compressed_edges / + std::max(compressed_geometries, (uint64_t)1)) << "\n avg chain length: " << (float)compressed_geometries / std::max((uint64_t)1, compressed_edges); @@ -226,15 +222,15 @@ GeometryCompressor::GetBucketReference(const EdgeID edge_id) const return m_compressed_geometries.at(index); } - NodeID GeometryCompressor::GetFirstNodeIDOfBucket(const EdgeID edge_id) const - { - const auto &bucket = GetBucketReference(edge_id); - BOOST_ASSERT(bucket.size() >= 2); - return bucket[1].first; - } - NodeID GeometryCompressor::GetLastNodeIDOfBucket(const EdgeID edge_id) const - { - const auto &bucket = GetBucketReference(edge_id); - BOOST_ASSERT(bucket.size() >= 2); - return bucket[bucket.size()-2].first; - } +NodeID GeometryCompressor::GetFirstNodeIDOfBucket(const EdgeID edge_id) const +{ + const auto &bucket = GetBucketReference(edge_id); + BOOST_ASSERT(bucket.size() >= 2); + return bucket[1].first; +} +NodeID GeometryCompressor::GetLastNodeIDOfBucket(const EdgeID edge_id) const +{ + const auto &bucket = GetBucketReference(edge_id); + BOOST_ASSERT(bucket.size() >= 2); + return bucket[bucket.size() - 2].first; +} diff --git a/3party/osrm/osrm-backend/Contractor/GeometryCompressor.h b/3party/osrm/osrm-backend/contractor/geometry_compressor.hpp old mode 100644 new mode 100755 similarity index 92% rename from 3party/osrm/osrm-backend/Contractor/GeometryCompressor.h rename to 3party/osrm/osrm-backend/contractor/geometry_compressor.hpp index f0af3710c0..ca83fa44c9 --- a/3party/osrm/osrm-backend/Contractor/GeometryCompressor.h +++ b/3party/osrm/osrm-backend/contractor/geometry_compressor.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM, Dennis Luxen, others All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef GEOMETRY_COMPRESSOR_H -#define GEOMETRY_COMPRESSOR_H +#ifndef GEOMETRY_COMPRESSOR_HPP_ +#define GEOMETRY_COMPRESSOR_HPP_ #include "../typedefs.h" @@ -58,10 +58,12 @@ class GeometryCompressor NodeID GetLastNodeIDOfBucket(const EdgeID edge_id) const; private: + int free_list_maximum = 0; + void IncreaseFreeList(); std::vector> m_compressed_geometries; std::vector m_free_list; std::unordered_map m_edge_id_to_list_index_map; }; -#endif // GEOMETRY_COMPRESSOR_H +#endif // GEOMETRY_COMPRESSOR_HPP_ diff --git a/3party/osrm/osrm-backend/Contractor/Prepare.cpp b/3party/osrm/osrm-backend/contractor/processing_chain.cpp old mode 100644 new mode 100755 similarity index 84% rename from 3party/osrm/osrm-backend/Contractor/Prepare.cpp rename to 3party/osrm/osrm-backend/contractor/processing_chain.cpp index 807b7560f9..ccff7fd093 --- a/3party/osrm/osrm-backend/Contractor/Prepare.cpp +++ b/3party/osrm/osrm-backend/contractor/processing_chain.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM, Dennis Luxen, others All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,24 +25,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "Prepare.h" +#include "processing_chain.hpp" -#include "Contractor.h" +#include "contractor.hpp" -#include "../Algorithms/IteratorBasedCRC32.h" -#include "../DataStructures/BinaryHeap.h" -#include "../DataStructures/DeallocatingVector.h" -#include "../DataStructures/Range.h" -#include "../DataStructures/StaticRTree.h" -#include "../DataStructures/RestrictionMap.h" +#include "../algorithms/crc32_processor.hpp" +#include "../data_structures/deallocating_vector.hpp" +#include "../data_structures/static_rtree.hpp" +#include "../data_structures/restriction_map.hpp" -#include "../Util/GitDescription.h" -#include "../Util/LuaUtil.h" -#include "../Util/make_unique.hpp" -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" -#include "../Util/StringUtil.h" -#include "../Util/TimingUtil.h" +#include "../util/git_sha.hpp" +#include "../util/graph_loader.hpp" +#include "../util/integer_range.hpp" +#include "../util/lua_util.hpp" +#include "../util/make_unique.hpp" +#include "../util/osrm_exception.hpp" +#include "../util/simple_logger.hpp" +#include "../util/string_util.hpp" +#include "../util/timing_util.hpp" #include "../typedefs.h" #include @@ -117,7 +117,6 @@ 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 @@ -136,16 +135,12 @@ 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) == 24, + static_assert(sizeof(ImportEdge) == 20, "changing ImportEdge type has influence on memory consumption!"); #endif - NodeID number_of_node_based_nodes = - readBinaryOSRMGraphFromStream(input_stream, - edge_list, - barrier_node_list, - traffic_light_list, - &internal_to_external_node_map, - restriction_list); + NodeID number_of_node_based_nodes = readBinaryOSRMGraphFromStream( + input_stream, edge_list, barrier_node_list, traffic_light_list, + &internal_to_external_node_map, restriction_list); input_stream.close(); if (edge_list.empty()) @@ -163,11 +158,9 @@ int Prepare::Process(int argc, char *argv[]) DeallocatingVector edge_based_edge_list; // init node_based_edge_list, edge_based_edge_list by edgeList - number_of_edge_based_nodes = BuildEdgeExpandedGraph(lua_state, - number_of_node_based_nodes, - node_based_edge_list, - edge_based_edge_list, - speed_profile); + number_of_edge_based_nodes = + BuildEdgeExpandedGraph(lua_state, number_of_node_based_nodes, node_based_edge_list, + edge_based_edge_list, speed_profile); lua_close(lua_state); TIMER_STOP(expansion); @@ -344,9 +337,8 @@ bool Prepare::ParseArguments(int argc, char *argv[]) // 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", - boost::program_options::value(&config_file_path) - ->default_value("contractor.ini"), + "config,c", boost::program_options::value(&config_file_path) + ->default_value("contractor.ini"), "Path to a configuration file."); // declare a group of options that will be allowed both on command line and in config file @@ -355,22 +347,18 @@ bool Prepare::ParseArguments(int argc, char *argv[]) "restrictions,r", boost::program_options::value(&restrictions_path), "Restrictions file in .osrm.restrictions format")( - "profile,p", - boost::program_options::value(&profile_path) - ->default_value("profile.lua"), + "profile,p", boost::program_options::value(&profile_path) + ->default_value("profile.lua"), "Path to LUA routing profile")( - "threads,t", - boost::program_options::value(&requested_num_threads) - ->default_value(tbb::task_scheduler_init::default_num_threads()), + "threads,t", boost::program_options::value(&requested_num_threads) + ->default_value(tbb::task_scheduler_init::default_num_threads()), "Number of threads to use"); // hidden options, will be allowed both on command line and in config file, but will not be // shown to the user - std::string string_input_path; boost::program_options::options_description hidden_options("Hidden options"); hidden_options.add_options()( - "input,i", - boost::program_options::value(&string_input_path), + "input,i", boost::program_options::value(&input_path), "Input file in .osm, .osm.bz2 or .osm.pbf format"); // positional option @@ -396,6 +384,14 @@ bool Prepare::ParseArguments(int argc, char *argv[]) .run(), option_variables); + const auto &temp_config_path = option_variables["config"].as(); + if (boost::filesystem::is_regular_file(temp_config_path)) + { + boost::program_options::store(boost::program_options::parse_config_file( + temp_config_path.string().c_str(), cmdline_options, true), + option_variables); + } + if (option_variables.count("version")) { SimpleLogger().Write() << g_GIT_DESCRIPTION; @@ -421,8 +417,6 @@ bool Prepare::ParseArguments(int argc, char *argv[]) return false; } - input_path = boost::filesystem::path(string_input_path); - return true; } @@ -455,9 +449,8 @@ void Prepare::CheckRestrictionsFile(FingerPrint &fingerprint_orig) \brief Setups scripting environment (lua-scripting) Also initializes speed profile. */ -bool -Prepare::SetupScriptingEnvironment(lua_State *lua_state, - EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile) +bool Prepare::SetupScriptingEnvironment( + lua_State *lua_state, EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile) { // open utility libraries string library; luaL_openlibs(lua_state); @@ -507,19 +500,11 @@ Prepare::BuildEdgeExpandedGraph(lua_State *lua_state, std::shared_ptr node_based_graph = NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list); std::unique_ptr restriction_map = - std::unique_ptr(new RestrictionMap(node_based_graph, restriction_list)); - - std::shared_ptr node_based_graph_origin = - NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list); - + osrm::make_unique(restriction_list); std::shared_ptr edge_based_graph_factory = - std::make_shared(node_based_graph, - node_based_graph_origin, - std::move(restriction_map), - barrier_node_list, - traffic_light_list, - internal_to_external_node_map, - speed_profile); + std::make_shared(node_based_graph, std::move(restriction_map), + barrier_node_list, traffic_light_list, + internal_to_external_node_map, speed_profile); edge_list.clear(); edge_list.shrink_to_fit(); @@ -544,14 +529,6 @@ 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(); @@ -570,7 +547,7 @@ void Prepare::WriteNodeMapping() if (size_of_mapping > 0) { node_stream.write((char *)&(internal_to_external_node_map[0]), - size_of_mapping * sizeof(NodeInfo)); + size_of_mapping * sizeof(QueryNode)); } node_stream.close(); internal_to_external_node_map.clear(); @@ -582,11 +559,9 @@ void Prepare::WriteNodeMapping() Saves info to files: '.ramIndex' and '.fileIndex'. */ -void Prepare::BuildRTree(std::vector &edge_based_node_list) +void Prepare::BuildRTree(std::vector &node_based_edge_list) { SimpleLogger().Write() << "building r-tree ..."; - StaticRTree(edge_based_node_list, - rtree_nodes_path.c_str(), - rtree_leafs_path.c_str(), - internal_to_external_node_map); + StaticRTree(node_based_edge_list, rtree_nodes_path.c_str(), + rtree_leafs_path.c_str(), internal_to_external_node_map); } diff --git a/3party/osrm/osrm-backend/Contractor/Prepare.h b/3party/osrm/osrm-backend/contractor/processing_chain.hpp old mode 100644 new mode 100755 similarity index 52% rename from 3party/osrm/osrm-backend/Contractor/Prepare.h rename to 3party/osrm/osrm-backend/contractor/processing_chain.hpp index 9b9fa4c48c..933213a4c0 --- a/3party/osrm/osrm-backend/Contractor/Prepare.h +++ b/3party/osrm/osrm-backend/contractor/processing_chain.hpp @@ -1,15 +1,43 @@ -#ifndef PREPARE_H -#define PREPARE_H +/* -#include "EdgeBasedGraphFactory.h" -#include "../DataStructures/QueryEdge.h" -#include "../DataStructures/StaticGraph.h" -#include "../Util/GraphLoader.h" +Copyright (c) 2014, Project OSRM, Dennis Luxen, others +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef PROCESSING_CHAIN_HPP +#define PROCESSING_CHAIN_HPP + +#include "edge_based_graph_factory.hpp" +#include "../data_structures/query_edge.hpp" +#include "../data_structures/static_graph.hpp" + +class FingerPrint; +struct EdgeBasedNode; +struct lua_State; #include -#include - #include /** @@ -42,7 +70,7 @@ class Prepare void BuildRTree(std::vector &node_based_edge_list); private: - std::vector internal_to_external_node_map; + std::vector internal_to_external_node_map; std::vector restriction_list; std::vector barrier_node_list; std::vector traffic_light_list; @@ -62,7 +90,6 @@ class Prepare std::string graph_out; std::string rtree_nodes_path; std::string rtree_leafs_path; - std::string node_data_filename; }; -#endif // PREPARE_H +#endif // PROCESSING_CHAIN_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/BinaryHeap.h b/3party/osrm/osrm-backend/data_structures/binary_heap.hpp old mode 100644 new mode 100755 similarity index 83% rename from 3party/osrm/osrm-backend/DataStructures/BinaryHeap.h rename to 3party/osrm/osrm-backend/data_structures/binary_heap.hpp index 24a65cbf08..a23a6b0f51 --- a/3party/osrm/osrm-backend/DataStructures/BinaryHeap.h +++ b/3party/osrm/osrm-backend/data_structures/binary_heap.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -36,24 +36,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include template class ArrayStorage { public: - explicit ArrayStorage(size_t size) : positions(new Key[size]) - { - memset(positions, 0, size * sizeof(Key)); - } + explicit ArrayStorage(size_t size) : positions(size, 0) {} - ~ArrayStorage() { delete[] positions; } + ~ArrayStorage() {} Key &operator[](NodeID node) { return positions[node]; } + Key peek_index(const NodeID node) const { return positions[node]; } + void Clear() {} private: - Key *positions; + std::vector positions; }; template class MapStorage @@ -65,6 +63,16 @@ template class MapStorage void Clear() { nodes.clear(); } + Key peek_index(const NodeID node) const + { + const auto iter = nodes.find(node); + if (nodes.end() != iter) + { + return iter->second; + } + return std::numeric_limits::max(); + } + private: std::map nodes; }; @@ -76,6 +84,16 @@ template class UnorderedMapStorage Key &operator[](const NodeID node) { return nodes[node]; } + Key peek_index(const NodeID node) const + { + const auto iter = nodes.find(node); + if (std::end(nodes) != iter) + { + return iter->second; + } + return std::numeric_limits::max(); + } + Key const &operator[](const NodeID node) const { auto iter = nodes.find(node); @@ -132,13 +150,13 @@ class BinaryHeap Data &GetData(NodeID node) { - const Key index = node_index[node]; + const Key index = node_index.peek_index(node); return inserted_nodes[index].data; } Data const &GetData(NodeID node) const { - const Key index = node_index[node]; + const Key index = node_index.peek_index(node); return inserted_nodes[index].data; } @@ -148,17 +166,17 @@ class BinaryHeap return inserted_nodes[index].weight; } - bool WasRemoved(const NodeID node) + bool WasRemoved(const NodeID node) const { BOOST_ASSERT(WasInserted(node)); - const Key index = node_index[node]; + const Key index = node_index.peek_index(node); return inserted_nodes[index].key == 0; } - bool WasInserted(const NodeID node) + bool WasInserted(const NodeID node) const { - const Key index = node_index[node]; - if (index >= static_cast(inserted_nodes.size())) + const auto index = node_index.peek_index(node); + if (index >= static_cast(inserted_nodes.size())) { return false; } @@ -200,7 +218,7 @@ class BinaryHeap void DecreaseKey(NodeID node, Weight weight) { BOOST_ASSERT(std::numeric_limits::max() != node); - const Key &index = node_index[node]; + const Key &index = node_index.peek_index(node); Key &key = inserted_nodes[index].key; BOOST_ASSERT(key >= 0); @@ -235,12 +253,12 @@ class BinaryHeap { const Key droppingIndex = heap[key].index; const Weight weight = heap[key].weight; + const Key heap_size = static_cast(heap.size()); Key nextKey = key << 1; - while (nextKey < static_cast(heap.size())) + while (nextKey < heap_size) { const Key nextKeyOther = nextKey + 1; - if ((nextKeyOther < static_cast(heap.size())) && - (heap[nextKey].weight > heap[nextKeyOther].weight)) + if ((nextKeyOther < heap_size) && (heap[nextKey].weight > heap[nextKeyOther].weight)) { nextKey = nextKeyOther; } @@ -279,7 +297,7 @@ class BinaryHeap void CheckHeap() { #ifndef NDEBUG - for (Key i = 2; i < (Key)heap.size(); ++i) + for (std::size_t i = 2; i < heap.size(); ++i) { BOOST_ASSERT(heap[i].weight >= heap[i >> 1].weight); } diff --git a/3party/osrm/osrm-backend/DataStructures/ConcurrentQueue.h b/3party/osrm/osrm-backend/data_structures/concurrent_queue.hpp old mode 100644 new mode 100755 similarity index 83% rename from 3party/osrm/osrm-backend/DataStructures/ConcurrentQueue.h rename to 3party/osrm/osrm-backend/data_structures/concurrent_queue.hpp index a61503a6dd..7341a8cc48 --- a/3party/osrm/osrm-backend/DataStructures/ConcurrentQueue.h +++ b/3party/osrm/osrm-backend/data_structures/concurrent_queue.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CONCURRENT_QUEUE_H -#define CONCURRENT_QUEUE_H +#ifndef CONCURRENT_QUEUE_HPP +#define CONCURRENT_QUEUE_HPP #include #include @@ -40,9 +40,10 @@ template class ConcurrentQueue inline void push(const Data &data) { std::unique_lock lock(m_mutex); - m_not_full.wait(lock, - [this] - { return m_internal_queue.size() < m_internal_queue.capacity(); }); + m_not_full.wait(lock, [this] + { + return m_internal_queue.size() < m_internal_queue.capacity(); + }); m_internal_queue.push_back(data); m_not_empty.notify_one(); } @@ -52,9 +53,10 @@ template class ConcurrentQueue inline void wait_and_pop(Data &popped_value) { std::unique_lock lock(m_mutex); - m_not_empty.wait(lock, - [this] - { return !m_internal_queue.empty(); }); + m_not_empty.wait(lock, [this] + { + return !m_internal_queue.empty(); + }); popped_value = m_internal_queue.front(); m_internal_queue.pop_front(); m_not_full.notify_one(); @@ -80,4 +82,4 @@ template class ConcurrentQueue std::condition_variable m_not_full; }; -#endif // CONCURRENT_QUEUE_H +#endif // CONCURRENT_QUEUE_HPP diff --git a/3party/osrm/osrm-backend/data_structures/coordinate.cpp b/3party/osrm/osrm-backend/data_structures/coordinate.cpp new file mode 100755 index 0000000000..df3abe44ae --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/coordinate.cpp @@ -0,0 +1,87 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "coordinate_calculation.hpp" + +#ifndef NDEBUG +#include "../util/simple_logger.hpp" +#endif +#include + +#ifndef NDEBUG +#include +#endif +#include +#include + +FixedPointCoordinate::FixedPointCoordinate() + : lat(std::numeric_limits::min()), lon(std::numeric_limits::min()) +{ +} + +FixedPointCoordinate::FixedPointCoordinate(int lat, int lon) : lat(lat), lon(lon) +{ +#ifndef NDEBUG + if (0 != (std::abs(lat) >> 30)) + { + std::bitset<32> y_coordinate_vector(lat); + SimpleLogger().Write(logDEBUG) << "broken lat: " << lat + << ", bits: " << y_coordinate_vector; + } + if (0 != (std::abs(lon) >> 30)) + { + std::bitset<32> x_coordinate_vector(lon); + SimpleLogger().Write(logDEBUG) << "broken lon: " << lon + << ", bits: " << x_coordinate_vector; + } +#endif +} + +bool FixedPointCoordinate::is_valid() const +{ + if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION || + lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION) + { + return false; + } + return true; +} + +bool FixedPointCoordinate::operator==(const FixedPointCoordinate &other) const +{ + return lat == other.lat && lon == other.lon; +} + +void FixedPointCoordinate::output(std::ostream &out) const +{ + out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")"; +} + +float FixedPointCoordinate::bearing(const FixedPointCoordinate &other) const +{ + return coordinate_calculation::bearing(other, *this); +} diff --git a/3party/osrm/osrm-backend/data_structures/coordinate_calculation.cpp b/3party/osrm/osrm-backend/data_structures/coordinate_calculation.cpp new file mode 100755 index 0000000000..0c44989b4b --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/coordinate_calculation.cpp @@ -0,0 +1,268 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "coordinate_calculation.hpp" + +#include "../util/mercator.hpp" +#include "../util/string_util.hpp" + +#include + +#include + +#include + +#include + +namespace +{ +constexpr static const float RAD = 0.017453292519943295769236907684886f; +// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi) +// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles) +constexpr static const float earth_radius = 6372797.560856f; +} + +double coordinate_calculation::great_circle_distance(const int lat1, + const int lon1, + const int lat2, + const int lon2) +{ + BOOST_ASSERT(lat1 != std::numeric_limits::min()); + BOOST_ASSERT(lon1 != std::numeric_limits::min()); + BOOST_ASSERT(lat2 != std::numeric_limits::min()); + BOOST_ASSERT(lon2 != std::numeric_limits::min()); + const double lt1 = lat1 / COORDINATE_PRECISION; + const double ln1 = lon1 / COORDINATE_PRECISION; + const double lt2 = lat2 / COORDINATE_PRECISION; + const double ln2 = lon2 / COORDINATE_PRECISION; + const double dlat1 = lt1 * (RAD); + + const double dlong1 = ln1 * (RAD); + const double dlat2 = lt2 * (RAD); + const double dlong2 = ln2 * (RAD); + + const double dLong = dlong1 - dlong2; + const double dLat = dlat1 - dlat2; + + const double aHarv = std::pow(std::sin(dLat / 2.0), 2.0) + + std::cos(dlat1) * std::cos(dlat2) * std::pow(std::sin(dLong / 2.), 2); + const double cHarv = 2. * std::atan2(std::sqrt(aHarv), std::sqrt(1.0 - aHarv)); + return earth_radius * cHarv; +} + +double coordinate_calculation::great_circle_distance(const FixedPointCoordinate &coordinate_1, + const FixedPointCoordinate &coordinate_2) +{ + return great_circle_distance(coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, + coordinate_2.lon); +} + +float coordinate_calculation::euclidean_distance(const FixedPointCoordinate &coordinate_1, + const FixedPointCoordinate &coordinate_2) +{ + return euclidean_distance(coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, + coordinate_2.lon); +} + +float coordinate_calculation::euclidean_distance(const int lat1, + const int lon1, + const int lat2, + const int lon2) +{ + BOOST_ASSERT(lat1 != std::numeric_limits::min()); + BOOST_ASSERT(lon1 != std::numeric_limits::min()); + BOOST_ASSERT(lat2 != std::numeric_limits::min()); + BOOST_ASSERT(lon2 != std::numeric_limits::min()); + + const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD; + const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD; + const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD; + const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD; + + const float x_value = (float_lon2 - float_lon1) * std::cos((float_lat1 + float_lat2) / 2.f); + const float y_value = float_lat2 - float_lat1; + return std::hypot(x_value, y_value) * earth_radius; +} + +float coordinate_calculation::perpendicular_distance(const FixedPointCoordinate &source_coordinate, + const FixedPointCoordinate &target_coordinate, + const FixedPointCoordinate &query_location) +{ + float ratio; + FixedPointCoordinate nearest_location; + + return perpendicular_distance(source_coordinate, target_coordinate, query_location, + nearest_location, ratio); +} + +float coordinate_calculation::perpendicular_distance(const FixedPointCoordinate &segment_source, + const FixedPointCoordinate &segment_target, + const FixedPointCoordinate &query_location, + FixedPointCoordinate &nearest_location, + float &ratio) +{ + return perpendicular_distance_from_projected_coordinate( + segment_source, segment_target, query_location, + {mercator::lat2y(query_location.lat / COORDINATE_PRECISION), + query_location.lon / COORDINATE_PRECISION}, + nearest_location, ratio); +} + +float coordinate_calculation::perpendicular_distance_from_projected_coordinate( + const FixedPointCoordinate &source_coordinate, + const FixedPointCoordinate &target_coordinate, + const FixedPointCoordinate &query_location, + const std::pair &projected_coordinate) +{ + float ratio; + FixedPointCoordinate nearest_location; + + return perpendicular_distance_from_projected_coordinate(source_coordinate, target_coordinate, + query_location, projected_coordinate, + nearest_location, ratio); +} + +float coordinate_calculation::perpendicular_distance_from_projected_coordinate( + const FixedPointCoordinate &segment_source, + const FixedPointCoordinate &segment_target, + const FixedPointCoordinate &query_location, + const std::pair &projected_coordinate, + FixedPointCoordinate &nearest_location, + float &ratio) +{ + BOOST_ASSERT(query_location.is_valid()); + + // initialize values + const double x = projected_coordinate.first; + const double y = projected_coordinate.second; + const double a = mercator::lat2y(segment_source.lat / COORDINATE_PRECISION); + const double b = segment_source.lon / COORDINATE_PRECISION; + const double c = mercator::lat2y(segment_target.lat / COORDINATE_PRECISION); + const double d = segment_target.lon / COORDINATE_PRECISION; + double p, q /*,mX*/, nY; + if (std::abs(a - c) > std::numeric_limits::epsilon()) + { + const double m = (d - b) / (c - a); // slope + // Projection of (x,y) on line joining (a,b) and (c,d) + p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m); + q = b + m * (p - a); + } + else + { + p = c; + q = y; + } + nY = (d * p - c * q) / (a * d - b * c); + + // discretize the result to coordinate precision. it's a hack! + if (std::abs(nY) < (1.f / COORDINATE_PRECISION)) + { + nY = 0.f; + } + + // compute ratio + ratio = + static_cast((p - nY * a) / c); // These values are actually n/m+n and m/m+n , we need + // not calculate the explicit values of m an n as we + // are just interested in the ratio + if (std::isnan(ratio)) + { + ratio = (segment_target == query_location ? 1.f : 0.f); + } + else if (std::abs(ratio) <= std::numeric_limits::epsilon()) + { + ratio = 0.f; + } + else if (std::abs(ratio - 1.f) <= std::numeric_limits::epsilon()) + { + ratio = 1.f; + } + + // compute nearest location + BOOST_ASSERT(!std::isnan(ratio)); + if (ratio <= 0.f) + { + nearest_location = segment_source; + } + else if (ratio >= 1.f) + { + nearest_location = segment_target; + } + else + { + // point lies in between + nearest_location.lat = static_cast(mercator::y2lat(p) * COORDINATE_PRECISION); + nearest_location.lon = static_cast(q * COORDINATE_PRECISION); + } + BOOST_ASSERT(nearest_location.is_valid()); + + const float approximate_distance = + coordinate_calculation::euclidean_distance(query_location, nearest_location); + BOOST_ASSERT(0.f <= approximate_distance); + return approximate_distance; +} + +void coordinate_calculation::lat_or_lon_to_string(const int value, std::string &output) +{ + char buffer[12]; + buffer[11] = 0; // zero termination + output = printInt<11, 6>(buffer, value); +} + +float coordinate_calculation::deg_to_rad(const float degree) +{ + return degree * (static_cast(M_PI) / 180.f); +} + +float coordinate_calculation::rad_to_deg(const float radian) +{ + return radian * (180.f * static_cast(M_1_PI)); +} + +float coordinate_calculation::bearing(const FixedPointCoordinate &first_coordinate, + const FixedPointCoordinate &second_coordinate) +{ + const float lon_diff = + second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION; + const float lon_delta = deg_to_rad(lon_diff); + const float lat1 = deg_to_rad(first_coordinate.lat / COORDINATE_PRECISION); + const float lat2 = deg_to_rad(second_coordinate.lat / COORDINATE_PRECISION); + const float y = std::sin(lon_delta) * std::cos(lat2); + const float x = + std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta); + float result = rad_to_deg(std::atan2(y, x)); + while (result < 0.f) + { + result += 360.f; + } + + while (result >= 360.f) + { + result -= 360.f; + } + return result; +} diff --git a/3party/osrm/osrm-backend/data_structures/coordinate_calculation.hpp b/3party/osrm/osrm-backend/data_structures/coordinate_calculation.hpp new file mode 100755 index 0000000000..73183dfa4d --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/coordinate_calculation.hpp @@ -0,0 +1,82 @@ +/* + +Copyright (c) 2015, 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 COORDINATE_CALCULATION +#define COORDINATE_CALCULATION + +struct FixedPointCoordinate; + +#include +#include + +struct coordinate_calculation +{ + static double + great_circle_distance(const int lat1, const int lon1, const int lat2, const int lon2); + + static double great_circle_distance(const FixedPointCoordinate &first_coordinate, + const FixedPointCoordinate &second_coordinate); + + static float euclidean_distance(const FixedPointCoordinate &first_coordinate, + const FixedPointCoordinate &second_coordinate); + + static float euclidean_distance(const int lat1, const int lon1, const int lat2, const int lon2); + + static void lat_or_lon_to_string(const int value, std::string &output); + + static float perpendicular_distance(const FixedPointCoordinate &segment_source, + const FixedPointCoordinate &segment_target, + const FixedPointCoordinate &query_location); + + static float perpendicular_distance(const FixedPointCoordinate &segment_source, + const FixedPointCoordinate &segment_target, + const FixedPointCoordinate &query_location, + FixedPointCoordinate &nearest_location, + float &ratio); + + static float perpendicular_distance_from_projected_coordinate( + const FixedPointCoordinate &segment_source, + const FixedPointCoordinate &segment_target, + const FixedPointCoordinate &query_location, + const std::pair &projected_coordinate); + + static float perpendicular_distance_from_projected_coordinate( + const FixedPointCoordinate &segment_source, + const FixedPointCoordinate &segment_target, + const FixedPointCoordinate &query_location, + const std::pair &projected_coordinate, + FixedPointCoordinate &nearest_location, + float &ratio); + + static float deg_to_rad(const float degree); + static float rad_to_deg(const float radian); + + static float bearing(const FixedPointCoordinate &first_coordinate, + const FixedPointCoordinate &second_coordinate); +}; + +#endif // COORDINATE_CALCULATION diff --git a/3party/osrm/osrm-backend/DataStructures/DeallocatingVector.h b/3party/osrm/osrm-backend/data_structures/deallocating_vector.hpp old mode 100644 new mode 100755 similarity index 80% rename from 3party/osrm/osrm-backend/DataStructures/DeallocatingVector.h rename to 3party/osrm/osrm-backend/data_structures/deallocating_vector.hpp index 422dd5f19d..de5a24d85f --- a/3party/osrm/osrm-backend/DataStructures/DeallocatingVector.h +++ b/3party/osrm/osrm-backend/data_structures/deallocating_vector.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,19 +25,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DEALLOCATINGVECTOR_H_ -#define DEALLOCATINGVECTOR_H_ +#ifndef DEALLOCATING_VECTOR_HPP +#define DEALLOCATING_VECTOR_HPP -#include "Range.h" +#include "../util/integer_range.hpp" #include +#include #include #include template struct DeallocatingVectorIteratorState { - DeallocatingVectorIteratorState() : index(-1), bucket_list(nullptr) {} + DeallocatingVectorIteratorState() + : index(std::numeric_limits::max()), bucket_list(nullptr) + { + } explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r) : index(r.index), bucket_list(r.bucket_list) { @@ -50,7 +54,7 @@ template struct DeallocatingVectorIteratorState std::size_t index; std::vector *bucket_list; - inline DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &other) + DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &other) { index = other.index; bucket_list = other.bucket_list; @@ -171,17 +175,20 @@ class DeallocatingVector // this forward-only iterator deallocates all buckets that have been visited using deallocation_iterator = DeallocatingVectorRemoveIterator; - DeallocatingVector() : current_size(0) { bucket_list.emplace_back(new ElementT[ELEMENTS_PER_BLOCK]); } + DeallocatingVector() : current_size(0) + { + bucket_list.emplace_back(new ElementT[ELEMENTS_PER_BLOCK]); + } ~DeallocatingVector() { clear(); } - inline void swap(DeallocatingVector &other) + void swap(DeallocatingVector &other) { std::swap(current_size, other.current_size); bucket_list.swap(other.bucket_list); } - inline void clear() + void clear() { // Delete[]'ing ptr's to all Buckets for (auto bucket : bucket_list) @@ -192,11 +199,12 @@ class DeallocatingVector bucket = nullptr; } } - bucket_list.clear(); bucket_list.shrink_to_fit(); + bucket_list.clear(); + bucket_list.shrink_to_fit(); current_size = 0; } - inline void push_back(const ElementT &element) + void push_back(const ElementT &element) { const std::size_t current_capacity = capacity(); if (current_size == current_capacity) @@ -209,7 +217,7 @@ class DeallocatingVector ++current_size; } - template inline void emplace_back(Ts &&... element) + template void emplace_back(Ts &&... element) { const std::size_t current_capacity = capacity(); if (current_size == current_capacity) @@ -222,9 +230,9 @@ class DeallocatingVector ++current_size; } - inline void reserve(const std::size_t) const { /* don't do anything */ } + void reserve(const std::size_t) const { /* don't do anything */} - inline void resize(const std::size_t new_size) + void resize(const std::size_t new_size) { if (new_size >= current_size) { @@ -234,9 +242,10 @@ class DeallocatingVector } } else - { // down-size + { // down-size const std::size_t number_of_necessary_buckets = 1 + (new_size / ELEMENTS_PER_BLOCK); - for (const auto bucket_index : osrm::irange(number_of_necessary_buckets, bucket_list.size())) + for (const auto bucket_index : + osrm::irange(number_of_necessary_buckets, bucket_list.size())) { if (nullptr != bucket_list[bucket_index]) { @@ -248,58 +257,50 @@ class DeallocatingVector current_size = new_size; } - inline std::size_t size() const { return current_size; } + std::size_t size() const { return current_size; } - inline std::size_t capacity() const { return bucket_list.size() * ELEMENTS_PER_BLOCK; } + std::size_t capacity() const { return bucket_list.size() * ELEMENTS_PER_BLOCK; } - inline iterator begin() { return iterator(static_cast(0), &bucket_list); } + iterator begin() { return iterator(static_cast(0), &bucket_list); } - inline iterator end() { return iterator(size(), &bucket_list); } + iterator end() { return iterator(size(), &bucket_list); } - inline deallocation_iterator dbegin() + deallocation_iterator dbegin() { return deallocation_iterator(static_cast(0), &bucket_list); } - inline deallocation_iterator dend() { return deallocation_iterator(size(), &bucket_list); } + deallocation_iterator dend() { return deallocation_iterator(size(), &bucket_list); } - inline const_iterator begin() const + const_iterator begin() const { return const_iterator(static_cast(0), &bucket_list); } - inline const_iterator end() const { return const_iterator(size(), &bucket_list); } + const_iterator end() const { return const_iterator(size(), &bucket_list); } - inline ElementT &operator[](const std::size_t index) + ElementT &operator[](const std::size_t index) { const std::size_t _bucket = index / ELEMENTS_PER_BLOCK; const std::size_t _index = index % ELEMENTS_PER_BLOCK; return (bucket_list[_bucket][_index]); } - const inline ElementT &operator[](const std::size_t index) const + ElementT &operator[](const std::size_t index) const { const std::size_t _bucket = index / ELEMENTS_PER_BLOCK; const std::size_t _index = index % ELEMENTS_PER_BLOCK; return (bucket_list[_bucket][_index]); } - inline ElementT &back() + ElementT &back() const { const std::size_t _bucket = current_size / ELEMENTS_PER_BLOCK; const std::size_t _index = current_size % ELEMENTS_PER_BLOCK; return (bucket_list[_bucket][_index]); } - const inline ElementT &back() const - { - const std::size_t _bucket = current_size / ELEMENTS_PER_BLOCK; - const std::size_t _index = current_size % ELEMENTS_PER_BLOCK; - return (bucket_list[_bucket][_index]); - } - - template - const inline void append(InputIterator first, const InputIterator last) + template void append(InputIterator first, const InputIterator last) { InputIterator position = first; while (position != last) @@ -310,4 +311,4 @@ class DeallocatingVector } }; -#endif /* DEALLOCATINGVECTOR_H_ */ +#endif /* DEALLOCATING_VECTOR_HPP */ diff --git a/3party/osrm/osrm-backend/DataStructures/DynamicGraph.h b/3party/osrm/osrm-backend/data_structures/dynamic_graph.hpp old mode 100644 new mode 100755 similarity index 66% rename from 3party/osrm/osrm-backend/DataStructures/DynamicGraph.h rename to 3party/osrm/osrm-backend/data_structures/dynamic_graph.hpp index 81b1afe117..43e6c3aca4 --- a/3party/osrm/osrm-backend/DataStructures/DynamicGraph.h +++ b/3party/osrm/osrm-backend/data_structures/dynamic_graph.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,20 +25,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DYNAMICGRAPH_H -#define DYNAMICGRAPH_H +#ifndef DYNAMICGRAPH_HPP +#define DYNAMICGRAPH_HPP -#include "DeallocatingVector.h" -#include "Range.h" +#include "deallocating_vector.hpp" +#include "../util/integer_range.hpp" +#include "../typedefs.h" #include #include #include -#include -#include #include +#include +#include +#include template class DynamicGraph { @@ -55,26 +57,29 @@ template class DynamicGraph NodeIterator target; EdgeDataT data; - InputEdge() : source(std::numeric_limits::max()), target(std::numeric_limits::max()) { } - - template - InputEdge(NodeIterator source, NodeIterator target, Ts &&...data) : source(source), target(target), data(std::forward(data)...) { } - - bool operator<(const InputEdge &right) const + InputEdge() + : source(std::numeric_limits::max()), + target(std::numeric_limits::max()) { - if (source != right.source) - { - return source < right.source; - } - return target < right.target; + } + + template + InputEdge(NodeIterator source, NodeIterator target, Ts &&... data) + : source(source), target(target), data(std::forward(data)...) + { + } + + bool operator<(const InputEdge &rhs) const + { + return std::tie(source, target) < std::tie(rhs.source, rhs.target); } }; // Constructs an empty graph with a given number of nodes. explicit DynamicGraph(NodeIterator nodes) : number_of_nodes(nodes), number_of_edges(0) { - node_list.reserve(number_of_nodes); - node_list.resize(number_of_nodes); + node_array.reserve(number_of_nodes); + node_array.resize(number_of_nodes); edge_list.reserve(number_of_nodes * 1.1); edge_list.resize(number_of_nodes); @@ -83,30 +88,30 @@ template class DynamicGraph template DynamicGraph(const NodeIterator nodes, const ContainerT &graph) { number_of_nodes = nodes; - number_of_edges = (EdgeIterator)graph.size(); - node_list.reserve(number_of_nodes + 1); - node_list.resize(number_of_nodes + 1); + number_of_edges = static_cast(graph.size()); + // node_array.reserve(number_of_nodes + 1); + node_array.resize(number_of_nodes + 1); EdgeIterator edge = 0; EdgeIterator position = 0; for (const auto node : osrm::irange(0u, number_of_nodes)) { - EdgeIterator lastEdge = edge; + EdgeIterator last_edge = edge; while (edge < number_of_edges && graph[edge].source == node) { ++edge; } - node_list[node].firstEdge = position; - node_list[node].edges = edge - lastEdge; - position += node_list[node].edges; + node_array[node].first_edge = position; + node_array[node].edges = edge - last_edge; + position += node_array[node].edges; } - node_list.back().firstEdge = position; - edge_list.reserve((std::size_t)edge_list.size() * 1.1); + node_array.back().first_edge = position; + edge_list.reserve(static_cast(edge_list.size() * 1.1)); edge_list.resize(position); edge = 0; for (const auto node : osrm::irange(0u, number_of_nodes)) { - for (const auto i : osrm::irange(node_list[node].firstEdge, - node_list[node].firstEdge + node_list[node].edges)) + for (const auto i : osrm::irange(node_array[node].first_edge, + node_array[node].first_edge + node_array[node].edges)) { edge_list[i].target = graph[edge].target; edge_list[i].data = graph[edge].data; @@ -121,7 +126,7 @@ template class DynamicGraph unsigned GetNumberOfEdges() const { return number_of_edges; } - unsigned GetOutDegree(const NodeIterator n) const { return node_list[n].edges; } + unsigned GetOutDegree(const NodeIterator n) const { return node_array[n].edges; } unsigned GetDirectedOutDegree(const NodeIterator n) const { @@ -146,12 +151,12 @@ template class DynamicGraph EdgeIterator BeginEdges(const NodeIterator n) const { - return EdgeIterator(node_list[n].firstEdge); + return EdgeIterator(node_array[n].first_edge); } EdgeIterator EndEdges(const NodeIterator n) const { - return EdgeIterator(node_list[n].firstEdge + node_list[n].edges); + return EdgeIterator(node_array[n].first_edge + node_array[n].edges); } EdgeRange GetAdjacentEdgeRange(const NodeIterator node) const @@ -161,7 +166,7 @@ template class DynamicGraph NodeIterator InsertNode() { - node_list.emplace_back(node_list.back()); + node_array.emplace_back(node_array.back()); number_of_nodes += 1; return number_of_nodes; @@ -170,14 +175,14 @@ template class DynamicGraph // adds an edge. Invalidates edge iterators for the source node EdgeIterator InsertEdge(const NodeIterator from, const NodeIterator to, const EdgeDataT &data) { - Node &node = node_list[from]; - EdgeIterator newFirstEdge = node.edges + node.firstEdge; + Node &node = node_array[from]; + EdgeIterator newFirstEdge = node.edges + node.first_edge; if (newFirstEdge >= edge_list.size() || !isDummy(newFirstEdge)) { - if (node.firstEdge != 0 && isDummy(node.firstEdge - 1)) + if (node.first_edge != 0 && isDummy(node.first_edge - 1)) { - node.firstEdge--; - edge_list[node.firstEdge] = edge_list[node.firstEdge + node.edges]; + node.first_edge--; + edge_list[node.first_edge] = edge_list[node.first_edge + node.edges]; } else { @@ -192,32 +197,32 @@ template class DynamicGraph edge_list.resize(edge_list.size() + newSize); for (const auto i : osrm::irange(0u, node.edges)) { - edge_list[newFirstEdge + i] = edge_list[node.firstEdge + i]; - makeDummy(node.firstEdge + i); + edge_list[newFirstEdge + i] = edge_list[node.first_edge + i]; + makeDummy(node.first_edge + i); } for (const auto i : osrm::irange(node.edges + 1, newSize)) { makeDummy(newFirstEdge + i); } - node.firstEdge = newFirstEdge; + node.first_edge = newFirstEdge; } } - Edge &edge = edge_list[node.firstEdge + node.edges]; + Edge &edge = edge_list[node.first_edge + node.edges]; edge.target = to; edge.data = data; ++number_of_edges; ++node.edges; - return EdgeIterator(node.firstEdge + node.edges); + return EdgeIterator(node.first_edge + node.edges); } // removes an edge. Invalidates edge iterators for the source node void DeleteEdge(const NodeIterator source, const EdgeIterator e) { - Node &node = node_list[source]; + Node &node = node_array[source]; --number_of_edges; --node.edges; BOOST_ASSERT(std::numeric_limits::max() != node.edges); - const unsigned last = node.firstEdge + node.edges; + const unsigned last = node.first_edge + node.edges; BOOST_ASSERT(std::numeric_limits::max() != last); // swap with last edge edge_list[e] = edge_list[last]; @@ -242,7 +247,7 @@ template class DynamicGraph } number_of_edges -= deleted; - node_list[source].edges -= deleted; + node_array[source].edges -= deleted; return deleted; } @@ -257,7 +262,46 @@ template class DynamicGraph return i; } } - return EndEdges(from); + return SPECIAL_EDGEID; + } + + // searches for a specific edge + EdgeIterator FindSmallestEdge(const NodeIterator from, const NodeIterator to) const + { + EdgeIterator smallest_edge = SPECIAL_EDGEID; + EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT; + for (auto edge : GetAdjacentEdgeRange(from)) + { + const NodeID target = GetTarget(edge); + const EdgeWeight weight = GetEdgeData(edge).distance; + if (target == to && weight < smallest_weight) + { + smallest_edge = edge; + smallest_weight = weight; + } + } + return smallest_edge; + } + + EdgeIterator FindEdgeInEitherDirection(const NodeIterator from, const NodeIterator to) const + { + EdgeIterator tmp = FindEdge(from, to); + return (SPECIAL_NODEID != tmp ? tmp : FindEdge(to, from)); + } + + EdgeIterator + FindEdgeIndicateIfReverse(const NodeIterator from, const NodeIterator to, bool &result) const + { + EdgeIterator current_iterator = FindEdge(from, to); + if (SPECIAL_NODEID == current_iterator) + { + current_iterator = FindEdge(to, from); + if (SPECIAL_NODEID != current_iterator) + { + result = true; + } + } + return current_iterator; } protected: @@ -274,7 +318,7 @@ template class DynamicGraph struct Node { // index of the first edge - EdgeIterator firstEdge; + EdgeIterator first_edge; // amount of edges unsigned edges; }; @@ -288,8 +332,8 @@ template class DynamicGraph NodeIterator number_of_nodes; std::atomic_uint number_of_edges; - std::vector node_list; + std::vector node_array; DeallocatingVector edge_list; }; -#endif // DYNAMICGRAPH_H +#endif // DYNAMICGRAPH_HPP diff --git a/3party/osrm/osrm-backend/data_structures/edge_based_node.hpp b/3party/osrm/osrm-backend/data_structures/edge_based_node.hpp new file mode 100755 index 0000000000..72a585a139 --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/edge_based_node.hpp @@ -0,0 +1,109 @@ +/* + +Copyright (c) 2015, 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 EDGE_BASED_NODE_HPP +#define EDGE_BASED_NODE_HPP + +#include "../data_structures/travel_mode.hpp" +#include "../typedefs.h" + +#include + +#include + +#include + +struct EdgeBasedNode +{ + EdgeBasedNode() + : forward_edge_based_node_id(SPECIAL_NODEID), reverse_edge_based_node_id(SPECIAL_NODEID), + u(SPECIAL_NODEID), v(SPECIAL_NODEID), name_id(0), + forward_weight(INVALID_EDGE_WEIGHT >> 1), reverse_weight(INVALID_EDGE_WEIGHT >> 1), + forward_offset(0), reverse_offset(0), packed_geometry_id(SPECIAL_EDGEID), + component_id(-1), fwd_segment_position(std::numeric_limits::max()), + forward_travel_mode(TRAVEL_MODE_INACCESSIBLE), + backward_travel_mode(TRAVEL_MODE_INACCESSIBLE) + { + } + + explicit EdgeBasedNode(NodeID forward_edge_based_node_id, + NodeID reverse_edge_based_node_id, + NodeID u, + NodeID v, + unsigned name_id, + int forward_weight, + int reverse_weight, + int forward_offset, + int reverse_offset, + unsigned packed_geometry_id, + unsigned component_id, + unsigned short fwd_segment_position, + TravelMode forward_travel_mode, + TravelMode backward_travel_mode) + : forward_edge_based_node_id(forward_edge_based_node_id), + reverse_edge_based_node_id(reverse_edge_based_node_id), u(u), v(v), name_id(name_id), + forward_weight(forward_weight), reverse_weight(reverse_weight), + forward_offset(forward_offset), reverse_offset(reverse_offset), + packed_geometry_id(packed_geometry_id), component_id(component_id), + fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode), + backward_travel_mode(backward_travel_mode) + { + BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) || + (reverse_edge_based_node_id != SPECIAL_NODEID)); + } + + static inline FixedPointCoordinate Centroid(const FixedPointCoordinate &a, + const FixedPointCoordinate &b) + { + FixedPointCoordinate centroid; + // The coordinates of the midpoint are given by: + centroid.lat = (a.lat + b.lat) / 2; + centroid.lon = (a.lon + b.lon) / 2; + return centroid; + } + + bool IsCompressed() const { return packed_geometry_id != SPECIAL_EDGEID; } + + bool is_in_tiny_cc() const { return 0 != component_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 + NodeID v; // indices into the coordinates array + unsigned name_id; // id of the edge name + int forward_weight; // weight of the edge + int reverse_weight; // weight in the other direction (may be different) + int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice + int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice + unsigned packed_geometry_id; // if set, then the edge represents a packed geometry + unsigned component_id; + unsigned short fwd_segment_position; // segment id in a compressed geometry + TravelMode forward_travel_mode : 4; + TravelMode backward_travel_mode : 4; +}; + +#endif // EDGE_BASED_NODE_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/ImportNode.cpp b/3party/osrm/osrm-backend/data_structures/external_memory_node.cpp old mode 100644 new mode 100755 similarity index 62% rename from 3party/osrm/osrm-backend/DataStructures/ImportNode.cpp rename to 3party/osrm/osrm-backend/data_structures/external_memory_node.cpp index 8975d408ab..72b8198f9c --- a/3party/osrm/osrm-backend/DataStructures/ImportNode.cpp +++ b/3party/osrm/osrm-backend/data_structures/external_memory_node.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2014, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,19 +25,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "ImportNode.h" +#include "external_memory_node.hpp" +#include "query_node.hpp" #include ExternalMemoryNode::ExternalMemoryNode( - int lat, int lon, unsigned int node_id, bool bollard, bool traffic_light) - : NodeInfo(lat, lon, node_id), bollard(bollard), trafficLight(traffic_light) + int lat, int lon, unsigned int node_id, bool barrier, bool traffic_lights) + : QueryNode(lat, lon, node_id), barrier(barrier), traffic_lights(traffic_lights) { } -ExternalMemoryNode::ExternalMemoryNode() : bollard(false), trafficLight(false) -{ -} +ExternalMemoryNode::ExternalMemoryNode() : barrier(false), traffic_lights(false) {} ExternalMemoryNode ExternalMemoryNode::min_value() { @@ -46,19 +45,22 @@ ExternalMemoryNode ExternalMemoryNode::min_value() ExternalMemoryNode ExternalMemoryNode::max_value() { - return ExternalMemoryNode(std::numeric_limits::max(), - std::numeric_limits::max(), - std::numeric_limits::max(), - false, - false); + return ExternalMemoryNode(std::numeric_limits::max(), std::numeric_limits::max(), + std::numeric_limits::max(), false, false); } -void ImportNode::Clear() +bool ExternalMemoryNodeSTXXLCompare::operator()(const ExternalMemoryNode &left, + const ExternalMemoryNode &right) const { - keyVals.Clear(); - lat = 0; - lon = 0; - node_id = 0; - bollard = false; - trafficLight = false; + return left.node_id < right.node_id; +} + +ExternalMemoryNodeSTXXLCompare::value_type ExternalMemoryNodeSTXXLCompare::max_value() +{ + return ExternalMemoryNode::max_value(); +} + +ExternalMemoryNodeSTXXLCompare::value_type ExternalMemoryNodeSTXXLCompare::min_value() +{ + return ExternalMemoryNode::min_value(); } diff --git a/3party/osrm/osrm-backend/DataStructures/ImportNode.h b/3party/osrm/osrm-backend/data_structures/external_memory_node.hpp old mode 100644 new mode 100755 similarity index 69% rename from 3party/osrm/osrm-backend/DataStructures/ImportNode.h rename to 3party/osrm/osrm-backend/data_structures/external_memory_node.hpp index b8a945120a..83b88e7592 --- a/3party/osrm/osrm-backend/DataStructures/ImportNode.h +++ b/3party/osrm/osrm-backend/data_structures/external_memory_node.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,17 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef IMPORTNODE_H_ -#define IMPORTNODE_H_ +#ifndef EXTERNAL_MEMORY_NODE_HPP_ +#define EXTERNAL_MEMORY_NODE_HPP_ -#include "QueryNode.h" -#include "../DataStructures/HashTable.h" +#include "query_node.hpp" -#include +#include "../typedefs.h" -struct ExternalMemoryNode : NodeInfo +struct ExternalMemoryNode : QueryNode { - ExternalMemoryNode(int lat, int lon, unsigned int id, bool bollard, bool traffic_light); + ExternalMemoryNode(int lat, int lon, NodeID id, bool barrier, bool traffic_light); ExternalMemoryNode(); @@ -43,15 +42,16 @@ struct ExternalMemoryNode : NodeInfo static ExternalMemoryNode max_value(); - bool bollard; - bool trafficLight; + bool barrier; + bool traffic_lights; }; -struct ImportNode : public ExternalMemoryNode +struct ExternalMemoryNodeSTXXLCompare { - HashTable keyVals; - - inline void Clear(); + using value_type = ExternalMemoryNode; + bool operator()(const ExternalMemoryNode &left, const ExternalMemoryNode &right) const; + value_type max_value(); + value_type min_value(); }; -#endif /* IMPORTNODE_H_ */ +#endif /* EXTERNAL_MEMORY_NODE_HPP_ */ diff --git a/3party/osrm/osrm-backend/DataStructures/FixedPointNumber.h b/3party/osrm/osrm-backend/data_structures/fixed_point_number.hpp old mode 100644 new mode 100755 similarity index 98% rename from 3party/osrm/osrm-backend/DataStructures/FixedPointNumber.h rename to 3party/osrm/osrm-backend/data_structures/fixed_point_number.hpp index 77de365aa2..c7ed257e52 --- a/3party/osrm/osrm-backend/DataStructures/FixedPointNumber.h +++ b/3party/osrm/osrm-backend/data_structures/fixed_point_number.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef OSRM_FIXED_POINT_NUMBER_H -#define OSRM_FIXED_POINT_NUMBER_H +#ifndef FIXED_POINT_NUMBER_HPP +#define FIXED_POINT_NUMBER_HPP #include #include @@ -213,4 +213,4 @@ class FixedPointNumber static_assert(4 == sizeof(FixedPointNumber<1>), "FP19 has wrong size != 4"); } -#endif // OSRM_FIXED_POINT_NUMBER_H +#endif // FIXED_POINT_NUMBER_HPP diff --git a/3party/osrm/osrm-backend/data_structures/hidden_markov_model.hpp b/3party/osrm/osrm-backend/data_structures/hidden_markov_model.hpp new file mode 100755 index 0000000000..cccaf7b5d2 --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/hidden_markov_model.hpp @@ -0,0 +1,158 @@ +/* + +Copyright (c) 2015, 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 HIDDEN_MARKOV_MODEL +#define HIDDEN_MARKOV_MODEL + +#include "../util/integer_range.hpp" + +#include + +#include + +#include +#include + +namespace osrm +{ +namespace matching +{ +static const double log_2_pi = std::log(2. * M_PI); +static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits::infinity(); +static const double MINIMAL_LOG_PROB = std::numeric_limits::lowest(); +static const std::size_t INVALID_STATE = std::numeric_limits::max(); +} // namespace matching +} // namespace osrm + +// closures to precompute log -> only simple floating point operations +struct EmissionLogProbability +{ + double sigma_z; + double log_sigma_z; + + EmissionLogProbability(const double sigma_z) : sigma_z(sigma_z), log_sigma_z(std::log(sigma_z)) + { + } + + double operator()(const double distance) const + { + return -0.5 * (osrm::matching::log_2_pi + (distance / sigma_z) * (distance / sigma_z)) - + log_sigma_z; + } +}; + +struct TransitionLogProbability +{ + double beta; + double log_beta; + TransitionLogProbability(const double beta) : beta(beta), log_beta(std::log(beta)) {} + + double operator()(const double d_t) const { return -log_beta - d_t / beta; } +}; + +template struct HiddenMarkovModel +{ + std::vector> viterbi; + std::vector>> parents; + std::vector> path_lengths; + std::vector> pruned; + std::vector> suspicious; + std::vector breakage; + + const CandidateLists &candidates_list; + const EmissionLogProbability &emission_log_probability; + + HiddenMarkovModel(const CandidateLists &candidates_list, + const EmissionLogProbability &emission_log_probability) + : breakage(candidates_list.size()), candidates_list(candidates_list), + emission_log_probability(emission_log_probability) + { + for (const auto &l : candidates_list) + { + viterbi.emplace_back(l.size()); + parents.emplace_back(l.size()); + path_lengths.emplace_back(l.size()); + suspicious.emplace_back(l.size()); + pruned.emplace_back(l.size()); + } + + clear(0); + } + + void clear(std::size_t initial_timestamp) + { + BOOST_ASSERT(viterbi.size() == parents.size() && parents.size() == path_lengths.size() && + path_lengths.size() == pruned.size() && pruned.size() == breakage.size()); + + for (const auto t : osrm::irange(initial_timestamp, viterbi.size())) + { + std::fill(viterbi[t].begin(), viterbi[t].end(), osrm::matching::IMPOSSIBLE_LOG_PROB); + std::fill(parents[t].begin(), parents[t].end(), std::make_pair(0u, 0u)); + std::fill(path_lengths[t].begin(), path_lengths[t].end(), 0); + std::fill(suspicious[t].begin(), suspicious[t].end(), true); + std::fill(pruned[t].begin(), pruned[t].end(), true); + } + std::fill(breakage.begin() + initial_timestamp, breakage.end(), true); + } + + std::size_t initialize(std::size_t initial_timestamp) + { + BOOST_ASSERT(initial_timestamp < candidates_list.size()); + + do + { + for (const auto s : osrm::irange(0u, viterbi[initial_timestamp].size())) + { + viterbi[initial_timestamp][s] = + emission_log_probability(candidates_list[initial_timestamp][s].second); + parents[initial_timestamp][s] = std::make_pair(initial_timestamp, s); + pruned[initial_timestamp][s] = + viterbi[initial_timestamp][s] < osrm::matching::MINIMAL_LOG_PROB; + suspicious[initial_timestamp][s] = false; + + breakage[initial_timestamp] = + breakage[initial_timestamp] && pruned[initial_timestamp][s]; + } + + ++initial_timestamp; + } while (breakage[initial_timestamp - 1]); + + if (initial_timestamp >= viterbi.size()) + { + return osrm::matching::INVALID_STATE; + } + + BOOST_ASSERT(initial_timestamp > 0); + --initial_timestamp; + + BOOST_ASSERT(breakage[initial_timestamp] == false); + + return initial_timestamp; + } +}; + +#endif // HIDDEN_MARKOV_MODEL diff --git a/3party/osrm/osrm-backend/DataStructures/HilbertValue.cpp b/3party/osrm/osrm-backend/data_structures/hilbert_value.cpp old mode 100644 new mode 100755 similarity index 96% rename from 3party/osrm/osrm-backend/DataStructures/HilbertValue.cpp rename to 3party/osrm/osrm-backend/data_structures/hilbert_value.cpp index 9cb88c79f3..c097731184 --- a/3party/osrm/osrm-backend/DataStructures/HilbertValue.cpp +++ b/3party/osrm/osrm-backend/data_structures/hilbert_value.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "HilbertValue.h" +#include "hilbert_value.hpp" -#include +#include uint64_t HilbertCode::operator()(const FixedPointCoordinate ¤t_coordinate) const { diff --git a/3party/osrm/osrm-backend/DataStructures/HilbertValue.h b/3party/osrm/osrm-backend/data_structures/hilbert_value.hpp old mode 100644 new mode 100755 similarity index 92% rename from 3party/osrm/osrm-backend/DataStructures/HilbertValue.h rename to 3party/osrm/osrm-backend/data_structures/hilbert_value.hpp index 9de23724f0..7b8bffa938 --- a/3party/osrm/osrm-backend/DataStructures/HilbertValue.h +++ b/3party/osrm/osrm-backend/data_structures/hilbert_value.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HILBERTVALUE_H_ -#define HILBERTVALUE_H_ +#ifndef HILBERT_VALUE_HPP +#define HILBERT_VALUE_HPP #include @@ -46,4 +46,4 @@ class HilbertCode inline void TransposeCoordinate(uint32_t *X) const; }; -#endif /* HILBERTVALUE_H_ */ +#endif /* HILBERT_VALUE_HPP */ diff --git a/3party/osrm/osrm-backend/DataStructures/ImportEdge.cpp b/3party/osrm/osrm-backend/data_structures/import_edge.cpp old mode 100644 new mode 100755 similarity index 90% rename from 3party/osrm/osrm-backend/DataStructures/ImportEdge.cpp rename to 3party/osrm/osrm-backend/data_structures/import_edge.cpp index e214aeafc8..f41b066b1a --- a/3party/osrm/osrm-backend/DataStructures/ImportEdge.cpp +++ b/3party/osrm/osrm-backend/data_structures/import_edge.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2014, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,9 +25,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "ImportEdge.h" +#include "import_edge.hpp" -#include +#include "travel_mode.hpp" +#include "../typedefs.h" bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const { @@ -46,8 +47,7 @@ bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const return source < other.source; } -NodeBasedEdge::NodeBasedEdge(unsigned way_id, - NodeID source, +NodeBasedEdge::NodeBasedEdge(NodeID source, NodeID target, NodeID name_id, EdgeWeight weight, @@ -58,8 +58,8 @@ NodeBasedEdge::NodeBasedEdge(unsigned way_id, bool access_restricted, TravelMode travel_mode, bool is_split) - : 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), + : 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) { } diff --git a/3party/osrm/osrm-backend/DataStructures/ImportEdge.h b/3party/osrm/osrm-backend/data_structures/import_edge.hpp old mode 100644 new mode 100755 similarity index 90% rename from 3party/osrm/osrm-backend/DataStructures/ImportEdge.h rename to 3party/osrm/osrm-backend/data_structures/import_edge.hpp index e6d09b099e..f422de116f --- a/3party/osrm/osrm-backend/DataStructures/ImportEdge.h +++ b/3party/osrm/osrm-backend/data_structures/import_edge.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,18 +25,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef IMPORT_EDGE_H -#define IMPORT_EDGE_H +#ifndef IMPORT_EDGE_HPP +#define IMPORT_EDGE_HPP -#include "../DataStructures/TravelMode.h" +#include "../data_structures/travel_mode.hpp" #include "../typedefs.h" struct NodeBasedEdge { bool operator<(const NodeBasedEdge &e) const; - explicit NodeBasedEdge(unsigned way_id, - NodeID source, + explicit NodeBasedEdge(NodeID source, NodeID target, NodeID name_id, EdgeWeight weight, @@ -48,7 +47,6 @@ struct NodeBasedEdge TravelMode travel_mode, bool is_split); - unsigned way_id; NodeID source; NodeID target; NodeID name_id; @@ -90,4 +88,4 @@ struct EdgeBasedEdge using ImportEdge = NodeBasedEdge; -#endif /* IMPORT_EDGE_H */ +#endif /* IMPORT_EDGE_HPP */ diff --git a/3party/osrm/osrm-backend/DataStructures/RawRouteData.h b/3party/osrm/osrm-backend/data_structures/internal_route_result.hpp old mode 100644 new mode 100755 similarity index 75% rename from 3party/osrm/osrm-backend/DataStructures/RawRouteData.h rename to 3party/osrm/osrm-backend/data_structures/internal_route_result.hpp index 9191a90113..068b63a800 --- a/3party/osrm/osrm-backend/DataStructures/RawRouteData.h +++ b/3party/osrm/osrm-backend/data_structures/internal_route_result.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -28,22 +28,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef RAW_ROUTE_DATA_H #define RAW_ROUTE_DATA_H -#include "../DataStructures/PhantomNodes.h" -#include "../DataStructures/TravelMode.h" -#include "../DataStructures/TurnInstructions.h" +#include "../data_structures/phantom_node.hpp" +#include "../data_structures/travel_mode.hpp" +#include "../data_structures/turn_instructions.hpp" #include "../typedefs.h" -#include "../Include/osrm/Coordinate.h" +#include #include struct PathData { PathData() - : node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT), - segment_duration(INVALID_EDGE_WEIGHT), - turn_instruction(TurnInstruction::NoTurn), - travel_mode(TRAVEL_MODE_INACCESSIBLE) + : node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT), segment_duration(INVALID_EDGE_WEIGHT), + turn_instruction(TurnInstruction::NoTurn), travel_mode(TRAVEL_MODE_INACCESSIBLE) { } @@ -52,8 +50,8 @@ struct PathData TurnInstruction turn_instruction, EdgeWeight segment_duration, TravelMode travel_mode) - : node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction), - travel_mode(travel_mode) + : node(node), name_id(name_id), segment_duration(segment_duration), + turn_instruction(turn_instruction), travel_mode(travel_mode) { } NodeID node; @@ -63,17 +61,15 @@ struct PathData TravelMode travel_mode : 4; }; -struct RawRouteData +struct InternalRouteResult { std::vector> unpacked_path_segments; std::vector unpacked_alternative; std::vector segment_end_coordinates; - std::vector raw_via_node_coordinates; std::vector source_traversed_in_reverse; std::vector target_traversed_in_reverse; std::vector alt_source_traversed_in_reverse; std::vector alt_target_traversed_in_reverse; - unsigned check_sum; int shortest_path_length; int alternative_path_length; @@ -82,10 +78,8 @@ struct RawRouteData return (leg != unpacked_path_segments.size() - 1); } - RawRouteData() - : check_sum(SPECIAL_NODEID), - shortest_path_length(INVALID_EDGE_WEIGHT), - alternative_path_length(INVALID_EDGE_WEIGHT) + InternalRouteResult() + : shortest_path_length(INVALID_EDGE_WEIGHT), alternative_path_length(INVALID_EDGE_WEIGHT) { } }; diff --git a/3party/osrm/osrm-backend/DataStructures/LRUCache.h b/3party/osrm/osrm-backend/data_structures/lru_cache.hpp old mode 100644 new mode 100755 similarity index 93% rename from 3party/osrm/osrm-backend/DataStructures/LRUCache.h rename to 3party/osrm/osrm-backend/data_structures/lru_cache.hpp index 75b9139d76..155ab1ef49 --- a/3party/osrm/osrm-backend/DataStructures/LRUCache.h +++ b/3party/osrm/osrm-backend/data_structures/lru_cache.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LRUCACHE_H -#define LRUCACHE_H +#ifndef LRUCACHE_HPP +#define LRUCACHE_HPP #include #include @@ -86,7 +86,7 @@ template class LRUCache result = e.value; // move to front - itemsInCache.splice(positionMap.find(key)->second, itemsInCache, itemsInCache.begin()); + itemsInCache.splice(itemsInCache.begin(), itemsInCache, positionMap.find(key)->second); positionMap.find(key)->second = itemsInCache.begin(); return true; } @@ -94,4 +94,4 @@ template class LRUCache } unsigned Size() const { return itemsInCache.size(); } }; -#endif // LRUCACHE_H +#endif // LRUCACHE_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/NodeBasedGraph.h b/3party/osrm/osrm-backend/data_structures/node_based_graph.hpp old mode 100644 new mode 100755 similarity index 65% rename from 3party/osrm/osrm-backend/DataStructures/NodeBasedGraph.h rename to 3party/osrm/osrm-backend/data_structures/node_based_graph.hpp index 94c62f3307..54e07a7ec6 --- a/3party/osrm/osrm-backend/DataStructures/NodeBasedGraph.h +++ b/3party/osrm/osrm-backend/data_structures/node_based_graph.hpp @@ -1,9 +1,36 @@ -#ifndef NODE_BASED_GRAPH_H_ -#define NODE_BASED_GRAPH_H_ +/* -#include "DynamicGraph.h" -#include "ImportEdge.h" -#include "../Util/simple_logger.hpp" +Copyright (c) 2015, 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 NODE_BASED_GRAPH_HPP +#define NODE_BASED_GRAPH_HPP + +#include "dynamic_graph.hpp" +#include "import_edge.hpp" +#include "../util/simple_logger.hpp" #include @@ -12,14 +39,13 @@ struct NodeBasedEdgeData { NodeBasedEdgeData() - : way_id(-1), distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID), - nameID(std::numeric_limits::max()), - isAccessRestricted(false), shortcut(false), forward(false), backward(false), - roundabout(false), ignore_in_grid(false), travel_mode(TRAVEL_MODE_INACCESSIBLE) + : distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID), + nameID(std::numeric_limits::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; @@ -59,7 +85,8 @@ using SimpleNodeBasedDynamicGraph = DynamicGraph; inline std::shared_ptr NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector &input_edge_list) { - static_assert(sizeof(NodeBasedEdgeData) == 20, "changing node based edge data size changes memory consumption"); + static_assert(sizeof(NodeBasedEdgeData) == 16, + "changing node based edge data size changes memory consumption"); DeallocatingVector edges_list; NodeBasedDynamicGraph::InputEdge edge; @@ -80,14 +107,12 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector(import_edge.weight), 1); BOOST_ASSERT(edge.data.distance > 0); edge.data.shortcut = false; edge.data.roundabout = import_edge.roundabout; @@ -110,7 +135,7 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector::max(); + forward_edge.data.distance = reverse_edge.data.distance = std::numeric_limits::max(); // remove parallel edges - while (i < edges_list.size() && edges_list[i].source == source && edges_list[i].target == target) + while (i < edges_list.size() && edges_list[i].source == source && + edges_list[i].target == target) { if (edges_list[i].data.forward) { @@ -146,7 +171,7 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector::max()) + if (static_cast(forward_edge.data.distance) != std::numeric_limits::max()) { forward_edge.data.backward = true; edges_list[edge_count++] = forward_edge; @@ -154,28 +179,31 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector::max()) + if (static_cast(forward_edge.data.distance) != std::numeric_limits::max()) { edges_list[edge_count++] = forward_edge; } - if ((int)reverse_edge.data.distance != std::numeric_limits::max()) + if (static_cast(reverse_edge.data.distance) != std::numeric_limits::max()) { edges_list[edge_count++] = reverse_edge; } } } edges_list.resize(edge_count); - SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size(); + SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " + << edges_list.size(); - auto graph = std::make_shared(static_cast(number_of_nodes), edges_list); + auto graph = std::make_shared( + static_cast(number_of_nodes), edges_list); return graph; } -template +template inline std::shared_ptr SimpleNodeBasedDynamicGraphFromEdges(int number_of_nodes, std::vector &input_edge_list) { - static_assert(sizeof(NodeBasedEdgeData) == 20, "changing node based edge data size changes memory consumption"); + static_assert(sizeof(NodeBasedEdgeData) == 16, + "changing node based edge data size changes memory consumption"); tbb::parallel_sort(input_edge_list.begin(), input_edge_list.end()); DeallocatingVector edges_list; @@ -194,10 +222,10 @@ SimpleNodeBasedDynamicGraphFromEdges(int number_of_nodes, std::vector(forward_edge.data.capacity) != INVALID_EDGE_WEIGHT) { edges_list[edge_count++] = forward_edge; } } else { // insert seperate edges - if (((int)forward_edge.data.capacity) != INVALID_EDGE_WEIGHT) + if (static_cast(forward_edge.data.capacity) != INVALID_EDGE_WEIGHT) { edges_list[edge_count++] = forward_edge; } - if ((int)reverse_edge.data.capacity != INVALID_EDGE_WEIGHT) + if (static_cast(reverse_edge.data.capacity) != INVALID_EDGE_WEIGHT) { edges_list[edge_count++] = reverse_edge; } } } - SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size(); + SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " + << edges_list.size(); auto graph = std::make_shared(number_of_nodes, edges_list); return graph; } -#endif // NODE_BASED_GRAPH_H_ +#endif // NODE_BASED_GRAPH_HPP diff --git a/3party/osrm/osrm-backend/extractor.cpp b/3party/osrm/osrm-backend/data_structures/node_id.hpp old mode 100644 new mode 100755 similarity index 77% rename from 3party/osrm/osrm-backend/extractor.cpp rename to 3party/osrm/osrm-backend/data_structures/node_id.hpp index 43a0296b1b..4d6fff0b2a --- a/3party/osrm/osrm-backend/extractor.cpp +++ b/3party/osrm/osrm-backend/data_structures/node_id.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,18 +25,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "Extractor/Extractor.h" -#include "Util/simple_logger.hpp" +#ifndef NODE_ID_HPP +#define NODE_ID_HPP -int main (int argc, char *argv[]) +#include "../typedefs.h" + +struct Cmp { - try - { - return Extractor().Run(argc, argv); - } - catch (const std::exception &e) - { - SimpleLogger().Write(logWARNING) << "[exception] " << e.what(); - } + using value_type = NodeID; + bool operator()(const NodeID left, const NodeID right) const { return left < right; } + value_type max_value() { return 0xffffffff; } + value_type min_value() { return 0x0; } +}; -} +#endif // NODE_ID_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/OriginalEdgeData.h b/3party/osrm/osrm-backend/data_structures/original_edge_data.hpp old mode 100644 new mode 100755 similarity index 83% rename from 3party/osrm/osrm-backend/DataStructures/OriginalEdgeData.h rename to 3party/osrm/osrm-backend/data_structures/original_edge_data.hpp index 3d7c543301..cbbc1b2760 --- a/3party/osrm/osrm-backend/DataStructures/OriginalEdgeData.h +++ b/3party/osrm/osrm-backend/data_structures/original_edge_data.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,11 +25,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ORIGINAL_EDGE_DATA_H -#define ORIGINAL_EDGE_DATA_H +#ifndef ORIGINAL_EDGE_DATA_HPP +#define ORIGINAL_EDGE_DATA_HPP -#include "TurnInstructions.h" -#include "../DataStructures/TravelMode.h" +#include "travel_mode.hpp" +#include "turn_instructions.hpp" #include "../typedefs.h" #include @@ -48,9 +48,8 @@ struct OriginalEdgeData OriginalEdgeData() : via_node(std::numeric_limits::max()), - name_id(std::numeric_limits::max()), - turn_instruction(TurnInstruction::NoTurn), compressed_geometry(false), - travel_mode(TRAVEL_MODE_INACCESSIBLE) + name_id(std::numeric_limits::max()), turn_instruction(TurnInstruction::NoTurn), + compressed_geometry(false), travel_mode(TRAVEL_MODE_INACCESSIBLE) { } @@ -61,4 +60,4 @@ struct OriginalEdgeData TravelMode travel_mode; }; -#endif // ORIGINAL_EDGE_DATA_H +#endif // ORIGINAL_EDGE_DATA_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/Percent.h b/3party/osrm/osrm-backend/data_structures/percent.hpp old mode 100644 new mode 100755 similarity index 93% rename from 3party/osrm/osrm-backend/DataStructures/Percent.h rename to 3party/osrm/osrm-backend/data_structures/percent.hpp index f201fc8084..392417e76a --- a/3party/osrm/osrm-backend/DataStructures/Percent.h +++ b/3party/osrm/osrm-backend/data_structures/percent.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PERCENT_H -#define PERCENT_H +#ifndef PERCENT_HPP +#define PERCENT_HPP #include #include @@ -36,7 +36,7 @@ class Percent public: explicit Percent(unsigned max_value, unsigned step = 5) { reinit(max_value, step); } - // Reinitializes + // Reinitializes void reinit(unsigned max_value, unsigned step = 5) { m_max_value = max_value; @@ -53,7 +53,7 @@ class Percent if (current_value >= m_next_threshold) { m_next_threshold += m_percent_interval; - printPercent(current_value / (double)m_max_value * 100); + printPercent(current_value / static_cast(m_max_value) * 100.); } if (current_value + 1 == m_max_value) std::cout << " 100%" << std::endl; @@ -98,4 +98,4 @@ class Percent } }; -#endif // PERCENT_H +#endif // PERCENT_HPP diff --git a/3party/osrm/osrm-backend/data_structures/phantom_node.cpp b/3party/osrm/osrm-backend/data_structures/phantom_node.cpp new file mode 100755 index 0000000000..eba6492cdd --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/phantom_node.cpp @@ -0,0 +1,106 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "phantom_node.hpp" + +#include "../typedefs.h" +#include "travel_mode.hpp" + +#include + +#include + +PhantomNode::PhantomNode(NodeID forward_node_id, + NodeID reverse_node_id, + unsigned name_id, + int forward_weight, + int reverse_weight, + int forward_offset, + int reverse_offset, + unsigned packed_geometry_id, + unsigned component_id, + FixedPointCoordinate &location, + unsigned short fwd_segment_position, + TravelMode forward_travel_mode, + TravelMode backward_travel_mode) + : forward_node_id(forward_node_id), reverse_node_id(reverse_node_id), name_id(name_id), + forward_weight(forward_weight), reverse_weight(reverse_weight), + forward_offset(forward_offset), reverse_offset(reverse_offset), + packed_geometry_id(packed_geometry_id), component_id(component_id), location(location), + fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode), + backward_travel_mode(backward_travel_mode) +{ +} + +PhantomNode::PhantomNode() + : forward_node_id(SPECIAL_NODEID), reverse_node_id(SPECIAL_NODEID), + name_id(std::numeric_limits::max()), forward_weight(INVALID_EDGE_WEIGHT), + reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0), + packed_geometry_id(SPECIAL_EDGEID), component_id(std::numeric_limits::max()), + fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE), + backward_travel_mode(TRAVEL_MODE_INACCESSIBLE) +{ +} + +int PhantomNode::GetForwardWeightPlusOffset() const +{ + if (SPECIAL_NODEID == forward_node_id) + { + return 0; + } + return forward_offset + forward_weight; +} + +int PhantomNode::GetReverseWeightPlusOffset() const +{ + if (SPECIAL_NODEID == reverse_node_id) + { + return 0; + } + return reverse_offset + reverse_weight; +} + +bool PhantomNode::is_bidirected() const +{ + return (forward_node_id != SPECIAL_NODEID) && (reverse_node_id != SPECIAL_NODEID); +} + +bool PhantomNode::is_compressed() const { return (forward_offset != 0) || (reverse_offset != 0); } + +bool PhantomNode::is_valid(const unsigned number_of_nodes) const +{ + return location.is_valid() && + ((forward_node_id < number_of_nodes) || (reverse_node_id < number_of_nodes)) && + ((forward_weight != INVALID_EDGE_WEIGHT) || (reverse_weight != INVALID_EDGE_WEIGHT)) && + (name_id != INVALID_NAMEID); +} + +bool PhantomNode::is_in_tiny_component() const { return component_id != 0; } + +bool PhantomNode::is_valid() const { return location.is_valid() && (name_id != INVALID_NAMEID); } + +bool PhantomNode::operator==(const PhantomNode &other) const { return location == other.location; } diff --git a/3party/osrm/osrm-backend/data_structures/phantom_node.hpp b/3party/osrm/osrm-backend/data_structures/phantom_node.hpp new file mode 100755 index 0000000000..b048eb7f21 --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/phantom_node.hpp @@ -0,0 +1,152 @@ +/* + +Copyright (c) 2015, 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 PHANTOM_NODES_H +#define PHANTOM_NODES_H + +#include "travel_mode.hpp" +#include "../typedefs.h" + +#include + +#include +#include +#include + +struct PhantomNode +{ + PhantomNode(NodeID forward_node_id, + NodeID reverse_node_id, + unsigned name_id, + int forward_weight, + int reverse_weight, + int forward_offset, + int reverse_offset, + unsigned packed_geometry_id, + unsigned component_id, + FixedPointCoordinate &location, + unsigned short fwd_segment_position, + TravelMode forward_travel_mode, + TravelMode backward_travel_mode); + + PhantomNode(); + + template PhantomNode(const OtherT &other, const FixedPointCoordinate &foot_point) + { + forward_node_id = other.forward_edge_based_node_id; + reverse_node_id = other.reverse_edge_based_node_id; + name_id = other.name_id; + + forward_weight = other.forward_weight; + reverse_weight = other.reverse_weight; + + forward_offset = other.forward_offset; + reverse_offset = other.reverse_offset; + + packed_geometry_id = other.packed_geometry_id; + component_id = other.component_id; + + location = foot_point; + fwd_segment_position = other.fwd_segment_position; + + forward_travel_mode = other.forward_travel_mode; + backward_travel_mode = other.backward_travel_mode; + } + + NodeID forward_node_id; + NodeID reverse_node_id; + unsigned name_id; + int forward_weight; + int reverse_weight; + int forward_offset; + int reverse_offset; + unsigned packed_geometry_id; + unsigned component_id; + FixedPointCoordinate location; + unsigned short fwd_segment_position; + TravelMode forward_travel_mode : 4; + TravelMode backward_travel_mode : 4; + + int GetForwardWeightPlusOffset() const; + + int GetReverseWeightPlusOffset() const; + + bool is_bidirected() const; + + bool is_compressed() const; + + bool is_valid(const unsigned numberOfNodes) const; + + bool is_valid() const; + + bool is_in_tiny_component() const; + + bool operator==(const PhantomNode &other) const; +}; + +using PhantomNodeArray = std::vector>; + +class phantom_node_pair : public std::pair +{ +}; + +struct PhantomNodeLists +{ + std::vector source_phantom_list; + std::vector target_phantom_list; +}; + +struct PhantomNodes +{ + PhantomNode source_phantom; + PhantomNode target_phantom; +}; + +inline std::ostream &operator<<(std::ostream &out, const PhantomNodes &pn) +{ + out << "source_coord: " << pn.source_phantom.location << "\n"; + out << "target_coord: " << pn.target_phantom.location << std::endl; + return out; +} + +inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn) +{ + out << "node1: " << pn.forward_node_id << ", " + << "node2: " << pn.reverse_node_id << ", " + << "name: " << pn.name_id << ", " + << "fwd-w: " << pn.forward_weight << ", " + << "rev-w: " << pn.reverse_weight << ", " + << "fwd-o: " << pn.forward_offset << ", " + << "rev-o: " << pn.reverse_offset << ", " + << "geom: " << pn.packed_geometry_id << ", " + << "comp: " << pn.component_id << ", " + << "pos: " << pn.fwd_segment_position << ", " + << "loc: " << pn.location; + return out; +} + +#endif // PHANTOM_NODES_H diff --git a/3party/osrm/osrm-backend/DataStructures/QueryEdge.h b/3party/osrm/osrm-backend/data_structures/query_edge.hpp old mode 100644 new mode 100755 similarity index 88% rename from 3party/osrm/osrm-backend/DataStructures/QueryEdge.h rename to 3party/osrm/osrm-backend/data_structures/query_edge.hpp index c9c71962c4..417bb4a13f --- a/3party/osrm/osrm-backend/DataStructures/QueryEdge.h +++ b/3party/osrm/osrm-backend/data_structures/query_edge.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,11 +25,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef QUERYEDGE_H_ -#define QUERYEDGE_H_ +#ifndef QUERYEDGE_HPP +#define QUERYEDGE_HPP #include "../typedefs.h" +#include + struct QueryEdge { NodeID source; @@ -60,13 +62,9 @@ struct QueryEdge { } - bool operator<(const QueryEdge &right) const + bool operator<(const QueryEdge &rhs) const { - if (source != right.source) - { - return source < right.source; - } - return target < right.target; + return std::tie(source, target) < std::tie(rhs.source, rhs.target); } bool operator==(const QueryEdge &right) const @@ -78,4 +76,4 @@ struct QueryEdge } }; -#endif /* QUERYEDGE_H_ */ +#endif // QUERYEDGE_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/QueryNode.h b/3party/osrm/osrm-backend/data_structures/query_node.hpp old mode 100644 new mode 100755 similarity index 69% rename from 3party/osrm/osrm-backend/DataStructures/QueryNode.h rename to 3party/osrm/osrm-backend/data_structures/query_node.hpp index a9d1aa92b7..f3e9904765 --- a/3party/osrm/osrm-backend/DataStructures/QueryNode.h +++ b/3party/osrm/osrm-backend/data_structures/query_node.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,24 +25,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef QUERY_NODE_H -#define QUERY_NODE_H +#ifndef QUERY_NODE_HPP +#define QUERY_NODE_HPP #include "../typedefs.h" -#include "../Include/osrm/Coordinate.h" - #include +#include + #include -struct NodeInfo +struct QueryNode { using key_type = NodeID; // type of NodeID - using value_type = int; // type of lat,lons + using value_type = int; // type of lat,lons - explicit NodeInfo(int lat, int lon, NodeID node_id) : lat(lat), lon(lon), node_id(node_id) {} - NodeInfo() + explicit QueryNode(int lat, int lon, NodeID node_id) : lat(lat), lon(lon), node_id(node_id) {} + QueryNode() : lat(std::numeric_limits::max()), lon(std::numeric_limits::max()), node_id(std::numeric_limits::max()) { @@ -52,18 +52,18 @@ struct NodeInfo int lon; NodeID node_id; - static NodeInfo min_value() + static QueryNode min_value() { - return NodeInfo(static_cast(-90 * COORDINATE_PRECISION), - static_cast(-180 * COORDINATE_PRECISION), - std::numeric_limits::min()); + return QueryNode(static_cast(-90 * COORDINATE_PRECISION), + static_cast(-180 * COORDINATE_PRECISION), + std::numeric_limits::min()); } - static NodeInfo max_value() + static QueryNode max_value() { - return NodeInfo(static_cast(90 * COORDINATE_PRECISION), - static_cast(180 * COORDINATE_PRECISION), - std::numeric_limits::max()); + return QueryNode(static_cast(90 * COORDINATE_PRECISION), + static_cast(180 * COORDINATE_PRECISION), + std::numeric_limits::max()); } value_type operator[](const std::size_t n) const @@ -78,8 +78,8 @@ struct NodeInfo break; } BOOST_ASSERT_MSG(false, "should not happen"); - return std::numeric_limits::max(); + return std::numeric_limits::lowest(); } }; -#endif // QUERY_NODE_H +#endif // QUERY_NODE_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/RangeTable.h b/3party/osrm/osrm-backend/data_structures/range_table.hpp old mode 100644 new mode 100755 similarity index 58% rename from 3party/osrm/osrm-backend/DataStructures/RangeTable.h rename to 3party/osrm/osrm-backend/data_structures/range_table.hpp index 46333aefb5..4662f06c0a --- a/3party/osrm/osrm-backend/DataStructures/RangeTable.h +++ b/3party/osrm/osrm-backend/data_structures/range_table.hpp @@ -1,9 +1,36 @@ -#ifndef RANGE_TABLE_H_ -#define RANGE_TABLE_H_ +/* -#include "Range.h" -#include "SharedMemoryFactory.h" -#include "SharedMemoryVectorWrapper.h" +Copyright (c) 2015, 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 RANGE_TABLE_HPP +#define RANGE_TABLE_HPP + +#include "../util/integer_range.hpp" +#include "shared_memory_factory.hpp" +#include "shared_memory_vector_wrapper.hpp" #include #include @@ -14,13 +41,13 @@ * and otherwise the compiler gets confused. */ -template class RangeTable; +template class RangeTable; -template -std::ostream& operator<<(std::ostream &out, const RangeTable &table); +template +std::ostream &operator<<(std::ostream &out, const RangeTable &table); -template -std::istream& operator>>(std::istream &in, RangeTable &table); +template +std::istream &operator>>(std::istream &in, RangeTable &table); /** * Stores adjacent ranges in a compressed format. @@ -31,33 +58,34 @@ std::istream& operator>>(std::istream &in, RangeTable -class RangeTable +template class RangeTable { -public: - + public: using BlockT = std::array; using BlockContainerT = typename ShM::vector; using OffsetContainerT = typename ShM::vector; using RangeT = osrm::range; - friend std::ostream& operator<< <>(std::ostream &out, const RangeTable &table); - friend std::istream& operator>> <>(std::istream &in, RangeTable &table); + friend std::ostream &operator<<<>(std::ostream &out, const RangeTable &table); + friend std::istream &operator>><>(std::istream &in, RangeTable &table); RangeTable() : sum_lengths(0) {} // for loading from shared memory - explicit RangeTable(OffsetContainerT& external_offsets, BlockContainerT& external_blocks, const unsigned sum_lengths) - : sum_lengths(sum_lengths) + explicit RangeTable(OffsetContainerT &external_offsets, + BlockContainerT &external_blocks, + const unsigned sum_lengths) + : sum_lengths(sum_lengths) { block_offsets.swap(external_offsets); diff_blocks.swap(external_blocks); } // construct table from length vector - explicit RangeTable(const std::vector& lengths) + explicit RangeTable(const std::vector &lengths) { - const unsigned number_of_blocks = [&lengths]() { + const unsigned number_of_blocks = [&lengths]() + { unsigned num = (lengths.size() + 1) / (BLOCK_SIZE + 1); if ((lengths.size() + 1) % (BLOCK_SIZE + 1) != 0) { @@ -89,8 +117,8 @@ public: block_sum += last_length; } - BOOST_ASSERT((block_idx == 0 && block_offsets[block_counter] == lengths_prefix_sum) - || lengths_prefix_sum == (block_offsets[block_counter]+block_sum)); + BOOST_ASSERT((block_idx == 0 && block_offsets[block_counter] == lengths_prefix_sum) || + lengths_prefix_sum == (block_offsets[block_counter] + block_sum)); // block is full if (BLOCK_SIZE == block_idx) @@ -109,7 +137,7 @@ public: } // Last block can't be finished because we didn't add the sentinel - BOOST_ASSERT (block_counter == (number_of_blocks - 1)); + BOOST_ASSERT(block_counter == (number_of_blocks - 1)); // one block missing: starts with guard value if (0 == block_idx) @@ -128,7 +156,8 @@ public: } diff_blocks.push_back(block); - BOOST_ASSERT(diff_blocks.size() == number_of_blocks && block_offsets.size() == number_of_blocks); + BOOST_ASSERT(diff_blocks.size() == number_of_blocks && + block_offsets.size() == number_of_blocks); sum_lengths = lengths_prefix_sum; } @@ -145,7 +174,7 @@ public: unsigned begin_idx = 0; unsigned end_idx = 0; begin_idx = block_offsets[block_idx]; - const BlockT& block = diff_blocks[block_idx]; + const BlockT &block = diff_blocks[block_idx]; if (internal_idx > 0) { begin_idx += PrefixSumAtIndex(internal_idx - 1, block); @@ -168,9 +197,9 @@ public: return osrm::irange(begin_idx, end_idx); } -private: - inline unsigned PrefixSumAtIndex(int index, const BlockT& block) const; + private: + inline unsigned PrefixSumAtIndex(int index, const BlockT &block) const; // contains offset for each differential block OffsetContainerT block_offsets; @@ -179,8 +208,9 @@ private: unsigned sum_lengths; }; -template -unsigned RangeTable::PrefixSumAtIndex(int index, const BlockT& block) const +template +unsigned RangeTable::PrefixSumAtIndex(int index, + const BlockT &block) const { // this loop looks inefficent, but a modern compiler // will emit nice SIMD here, at least for sensible block sizes. (I checked.) @@ -193,39 +223,39 @@ unsigned RangeTable::PrefixSumAtIndex(int index, return sum; } -template -std::ostream& operator<<(std::ostream &out, const RangeTable &table) +template +std::ostream &operator<<(std::ostream &out, const RangeTable &table) { // write number of block const unsigned number_of_blocks = table.diff_blocks.size(); - out.write((char *) &number_of_blocks, sizeof(unsigned)); + out.write((char *)&number_of_blocks, sizeof(unsigned)); // write total length - out.write((char *) &table.sum_lengths, sizeof(unsigned)); + out.write((char *)&table.sum_lengths, sizeof(unsigned)); // write block offsets - out.write((char *) table.block_offsets.data(), sizeof(unsigned) * table.block_offsets.size()); + out.write((char *)table.block_offsets.data(), sizeof(unsigned) * table.block_offsets.size()); // write blocks - out.write((char *) table.diff_blocks.data(), BLOCK_SIZE * table.diff_blocks.size()); + out.write((char *)table.diff_blocks.data(), BLOCK_SIZE * table.diff_blocks.size()); return out; } -template -std::istream& operator>>(std::istream &in, RangeTable &table) +template +std::istream &operator>>(std::istream &in, RangeTable &table) { // read number of block unsigned number_of_blocks; - in.read((char *) &number_of_blocks, sizeof(unsigned)); + in.read((char *)&number_of_blocks, sizeof(unsigned)); // read total length - in.read((char *) &table.sum_lengths, sizeof(unsigned)); + in.read((char *)&table.sum_lengths, sizeof(unsigned)); table.block_offsets.resize(number_of_blocks); table.diff_blocks.resize(number_of_blocks); // read block offsets - in.read((char *) table.block_offsets.data(), sizeof(unsigned) * number_of_blocks); + in.read((char *)table.block_offsets.data(), sizeof(unsigned) * number_of_blocks); // read blocks - in.read((char *) table.diff_blocks.data(), BLOCK_SIZE * number_of_blocks); + in.read((char *)table.diff_blocks.data(), BLOCK_SIZE * number_of_blocks); return in; } -#endif //RANGE_TABLE_H_ +#endif // RANGE_TABLE_HPP diff --git a/3party/osrm/osrm-backend/data_structures/rectangle.hpp b/3party/osrm/osrm-backend/data_structures/rectangle.hpp new file mode 100755 index 0000000000..55720a37da --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/rectangle.hpp @@ -0,0 +1,211 @@ +/* + +Copyright (c) 2015, 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 RECTANGLE_HPP +#define RECTANGLE_HPP + +#include "coordinate_calculation.hpp" + +#include + +#include + +#include +#include +#include + +// TODO: Make template type, add tests +struct RectangleInt2D +{ + RectangleInt2D() + : min_lon(std::numeric_limits::max()), + max_lon(std::numeric_limits::min()), + min_lat(std::numeric_limits::max()), max_lat(std::numeric_limits::min()) + { + } + + int32_t min_lon, max_lon; + int32_t min_lat, max_lat; + + void MergeBoundingBoxes(const RectangleInt2D &other) + { + min_lon = std::min(min_lon, other.min_lon); + max_lon = std::max(max_lon, other.max_lon); + min_lat = std::min(min_lat, other.min_lat); + max_lat = std::max(max_lat, other.max_lat); + BOOST_ASSERT(min_lat != std::numeric_limits::min()); + BOOST_ASSERT(min_lon != std::numeric_limits::min()); + BOOST_ASSERT(max_lat != std::numeric_limits::min()); + BOOST_ASSERT(max_lon != std::numeric_limits::min()); + } + + FixedPointCoordinate Centroid() const + { + FixedPointCoordinate centroid; + // The coordinates of the midpoints are given by: + // x = (x1 + x2) /2 and y = (y1 + y2) /2. + centroid.lon = (min_lon + max_lon) / 2; + centroid.lat = (min_lat + max_lat) / 2; + return centroid; + } + + bool Intersects(const RectangleInt2D &other) const + { + FixedPointCoordinate upper_left(other.max_lat, other.min_lon); + FixedPointCoordinate upper_right(other.max_lat, other.max_lon); + FixedPointCoordinate lower_right(other.min_lat, other.max_lon); + FixedPointCoordinate lower_left(other.min_lat, other.min_lon); + + return (Contains(upper_left) || Contains(upper_right) || Contains(lower_right) || + Contains(lower_left)); + } + + float GetMinDist(const FixedPointCoordinate &location) const + { + const bool is_contained = Contains(location); + if (is_contained) + { + return 0.0f; + } + + enum Direction + { + INVALID = 0, + NORTH = 1, + SOUTH = 2, + EAST = 4, + NORTH_EAST = 5, + SOUTH_EAST = 6, + WEST = 8, + NORTH_WEST = 9, + SOUTH_WEST = 10 + }; + + Direction d = INVALID; + if (location.lat > max_lat) + d = (Direction)(d | NORTH); + else if (location.lat < min_lat) + d = (Direction)(d | SOUTH); + if (location.lon > max_lon) + d = (Direction)(d | EAST); + else if (location.lon < min_lon) + d = (Direction)(d | WEST); + + BOOST_ASSERT(d != INVALID); + + float min_dist = std::numeric_limits::max(); + switch (d) + { + case NORTH: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(max_lat, location.lon)); + break; + case SOUTH: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(min_lat, location.lon)); + break; + case WEST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(location.lat, min_lon)); + break; + case EAST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(location.lat, max_lon)); + break; + case NORTH_EAST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(max_lat, max_lon)); + break; + case NORTH_WEST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(max_lat, min_lon)); + break; + case SOUTH_EAST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(min_lat, max_lon)); + break; + case SOUTH_WEST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(min_lat, min_lon)); + break; + default: + break; + } + + BOOST_ASSERT(min_dist < std::numeric_limits::max()); + + return min_dist; + } + + float GetMinMaxDist(const FixedPointCoordinate &location) const + { + float min_max_dist = std::numeric_limits::max(); + // Get minmax distance to each of the four sides + const FixedPointCoordinate upper_left(max_lat, min_lon); + const FixedPointCoordinate upper_right(max_lat, max_lon); + const FixedPointCoordinate lower_right(min_lat, max_lon); + const FixedPointCoordinate lower_left(min_lat, min_lon); + + min_max_dist = + std::min(min_max_dist, + std::max(coordinate_calculation::euclidean_distance(location, upper_left), + coordinate_calculation::euclidean_distance(location, upper_right))); + + min_max_dist = + std::min(min_max_dist, + std::max(coordinate_calculation::euclidean_distance(location, upper_right), + coordinate_calculation::euclidean_distance(location, lower_right))); + + min_max_dist = + std::min(min_max_dist, + std::max(coordinate_calculation::euclidean_distance(location, lower_right), + coordinate_calculation::euclidean_distance(location, lower_left))); + + min_max_dist = + std::min(min_max_dist, + std::max(coordinate_calculation::euclidean_distance(location, lower_left), + coordinate_calculation::euclidean_distance(location, upper_left))); + return min_max_dist; + } + + bool Contains(const FixedPointCoordinate &location) const + { + const bool lats_contained = (location.lat >= min_lat) && (location.lat <= max_lat); + const bool lons_contained = (location.lon >= min_lon) && (location.lon <= max_lon); + return lats_contained && lons_contained; + } + + friend std::ostream &operator<<(std::ostream &out, const RectangleInt2D &rect) + { + out << rect.min_lat / COORDINATE_PRECISION << "," << rect.min_lon / COORDINATE_PRECISION + << " " << rect.max_lat / COORDINATE_PRECISION << "," + << rect.max_lon / COORDINATE_PRECISION; + return out; + } +}; + +#endif diff --git a/3party/osrm/osrm-backend/DataStructures/Restriction.h b/3party/osrm/osrm-backend/data_structures/restriction.hpp old mode 100644 new mode 100755 similarity index 52% rename from 3party/osrm/osrm-backend/DataStructures/Restriction.h rename to 3party/osrm/osrm-backend/data_structures/restriction.hpp index bda0f01961..b808d3070b --- a/3party/osrm/osrm-backend/DataStructures/Restriction.h +++ b/3party/osrm/osrm-backend/data_structures/restriction.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef RESTRICTION_H -#define RESTRICTION_H +#ifndef RESTRICTION_HPP +#define RESTRICTION_HPP #include "../typedefs.h" @@ -34,19 +34,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct TurnRestriction { - NodeID viaNode; - NodeID fromNode; - NodeID toNode; + union WayOrNode + { + NodeID node; + EdgeID way; + }; + WayOrNode via; + WayOrNode from; + WayOrNode to; + struct Bits { // mostly unused Bits() - : isOnly(false), unused1(false), unused2(false), unused3(false), unused4(false), + : is_only(false), uses_via_way(false), unused2(false), unused3(false), unused4(false), unused5(false), unused6(false), unused7(false) { } - bool isOnly : 1; - bool unused1 : 1; + bool is_only : 1; + bool uses_via_way : 1; bool unused2 : 1; bool unused3 : 1; bool unused4 : 1; @@ -55,72 +61,70 @@ struct TurnRestriction bool unused7 : 1; } flags; - explicit TurnRestriction(NodeID viaNode) - : viaNode(viaNode), fromNode(std::numeric_limits::max()), - toNode(std::numeric_limits::max()) + explicit TurnRestriction(NodeID node) { + via.node = node; + from.node = SPECIAL_NODEID; + to.node = SPECIAL_NODEID; } - explicit TurnRestriction(const bool isOnly = false) - : viaNode(std::numeric_limits::max()), - fromNode(std::numeric_limits::max()), - toNode(std::numeric_limits::max()) + explicit TurnRestriction(const bool is_only = false) { - flags.isOnly = isOnly; + via.node = SPECIAL_NODEID; + from.node = SPECIAL_NODEID; + to.node = SPECIAL_NODEID; + flags.is_only = is_only; } }; struct InputRestrictionContainer { - EdgeID fromWay; - EdgeID toWay; - unsigned viaNode; + // EdgeID fromWay; + // EdgeID toWay; + // NodeID via_node; TurnRestriction restriction; - InputRestrictionContainer(EdgeID fromWay, EdgeID toWay, NodeID vn, unsigned vw) - : fromWay(fromWay), toWay(toWay), viaNode(vw) + InputRestrictionContainer(EdgeID fromWay, EdgeID toWay, EdgeID vw) { - restriction.viaNode = vn; + restriction.from.way = fromWay; + restriction.to.way = toWay; + restriction.via.way = vw; } - explicit InputRestrictionContainer(bool isOnly = false) - : fromWay(std::numeric_limits::max()), - toWay(std::numeric_limits::max()), viaNode(std::numeric_limits::max()) + explicit InputRestrictionContainer(bool is_only = false) { - restriction.flags.isOnly = isOnly; + restriction.from.way = SPECIAL_EDGEID; + restriction.to.way = SPECIAL_EDGEID; + restriction.via.node = SPECIAL_NODEID; + restriction.flags.is_only = is_only; } - static InputRestrictionContainer min_value() { return InputRestrictionContainer(0, 0, 0, 0); } + static InputRestrictionContainer min_value() { return InputRestrictionContainer(0, 0, 0); } static InputRestrictionContainer max_value() { - return InputRestrictionContainer(std::numeric_limits::max(), - std::numeric_limits::max(), - std::numeric_limits::max(), - std::numeric_limits::max()); + return InputRestrictionContainer(SPECIAL_EDGEID, SPECIAL_EDGEID, SPECIAL_EDGEID); } }; struct CmpRestrictionContainerByFrom { using value_type = InputRestrictionContainer; - inline bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) - const + bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const { - return a.fromWay < b.fromWay; - } - inline value_type max_value() const { return InputRestrictionContainer::max_value(); } - inline value_type min_value() const { return InputRestrictionContainer::min_value(); } -}; - -struct CmpRestrictionContainerByTo -{ - using value_type = InputRestrictionContainer; - inline bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) - const - { - return a.toWay < b.toWay; + return a.restriction.from.way < b.restriction.from.way; } value_type max_value() const { return InputRestrictionContainer::max_value(); } value_type min_value() const { return InputRestrictionContainer::min_value(); } }; -#endif // RESTRICTION_H +struct CmpRestrictionContainerByTo +{ + using value_type = InputRestrictionContainer; + bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const + { + return a.restriction.to.way < b.restriction.to.way; + } + value_type max_value() const { return InputRestrictionContainer::max_value(); } + value_type min_value() const { return InputRestrictionContainer::min_value(); } +}; + +#endif // RESTRICTION_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/RestrictionMap.cpp b/3party/osrm/osrm-backend/data_structures/restriction_map.cpp old mode 100644 new mode 100755 similarity index 67% rename from 3party/osrm/osrm-backend/DataStructures/RestrictionMap.cpp rename to 3party/osrm/osrm-backend/data_structures/restriction_map.cpp index f2c56e0cfd..017ee32513 --- a/3party/osrm/osrm-backend/DataStructures/RestrictionMap.cpp +++ b/3party/osrm/osrm-backend/data_structures/restriction_map.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,28 +25,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "RestrictionMap.h" -#include "NodeBasedGraph.h" +#include "restriction_map.hpp" -bool RestrictionMap::IsViaNode(const NodeID node) const -{ - return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end(); -} - -RestrictionMap::RestrictionMap(const std::shared_ptr &graph, - const std::vector &restriction_list) - : m_count(0), m_graph(graph) +RestrictionMap::RestrictionMap(const std::vector &restriction_list) : m_count(0) { // decompose restriction consisting of a start, via and end node into a // a pair of starting edge and a list of all end nodes for (auto &restriction : restriction_list) { - m_restriction_start_nodes.insert(restriction.fromNode); - m_no_turn_via_node_set.insert(restriction.viaNode); + m_restriction_start_nodes.insert(restriction.from.node); + m_no_turn_via_node_set.insert(restriction.via.node); - RestrictionSource restriction_source = {restriction.fromNode, restriction.viaNode}; + RestrictionSource restriction_source = {restriction.from.node, restriction.via.node}; - unsigned index; + std::size_t index; auto restriction_iter = m_restriction_map.find(restriction_source); if (restriction_iter == m_restriction_map.end()) { @@ -62,7 +54,7 @@ RestrictionMap::RestrictionMap(const std::shared_ptr &gra { continue; } - else if (restriction.flags.isOnly) + else if (restriction.flags.is_only) { // We are going to insert an is_only_*-restriction. There can be only one. m_count -= m_restriction_bucket_list.at(index).size(); @@ -71,54 +63,13 @@ RestrictionMap::RestrictionMap(const std::shared_ptr &gra } ++m_count; m_restriction_bucket_list.at(index) - .emplace_back(restriction.toNode, restriction.flags.isOnly); + .emplace_back(restriction.to.node, restriction.flags.is_only); } } -// Replace end v with w in each turn restriction containing u as via node -void RestrictionMap::FixupArrivingTurnRestriction(const NodeID node_u, - const NodeID node_v, - const NodeID node_w) +bool RestrictionMap::IsViaNode(const NodeID node) const { - BOOST_ASSERT(node_u != SPECIAL_NODEID); - BOOST_ASSERT(node_v != SPECIAL_NODEID); - BOOST_ASSERT(node_w != SPECIAL_NODEID); - - if (!IsViaNode(node_u)) - { - return; - } - - // find all potential start edges. It is more efficent to get a (small) list - // of potential start edges than iterating over all buckets - std::vector predecessors; - for (const EdgeID current_edge_id : m_graph->GetAdjacentEdgeRange(node_u)) - { - const NodeID target = m_graph->GetTarget(current_edge_id); - if (node_v != target) - { - predecessors.push_back(target); - } - } - - for (const NodeID node_x : predecessors) - { - const auto restriction_iterator = m_restriction_map.find({node_x, node_u}); - if (restriction_iterator == m_restriction_map.end()) - { - continue; - } - - const unsigned index = restriction_iterator->second; - auto &bucket = m_restriction_bucket_list.at(index); - for (RestrictionTarget &restriction_target : bucket) - { - if (node_v == restriction_target.target_node) - { - restriction_target.target_node = node_w; - } - } - } + return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end(); } // Replaces start edge (v, w) with (u, w). Only start node changes. @@ -191,18 +142,25 @@ bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u, } const auto restriction_iter = m_restriction_map.find({node_u, node_v}); - if (restriction_iter != m_restriction_map.end()) + if (restriction_iter == m_restriction_map.end()) { - const unsigned index = restriction_iter->second; - const auto &bucket = m_restriction_bucket_list.at(index); - for (const RestrictionTarget &restriction_target : bucket) + return false; + } + + const unsigned index = restriction_iter->second; + const auto &bucket = m_restriction_bucket_list.at(index); + + for (const RestrictionTarget &restriction_target : bucket) + { + if (node_w == restriction_target.target_node && // target found + !restriction_target.is_only) // and not an only_-restr. { - if ((node_w == restriction_target.target_node) && // target found - (!restriction_target.is_only) // and not an only_-restr. - ) - { - return true; - } + return true; + } + if (node_w != restriction_target.target_node && // target not found + restriction_target.is_only) // and is an only restriction + { + return true; } } return false; diff --git a/3party/osrm/osrm-backend/DataStructures/RestrictionMap.h b/3party/osrm/osrm-backend/data_structures/restriction_map.hpp old mode 100644 new mode 100755 similarity index 53% rename from 3party/osrm/osrm-backend/DataStructures/RestrictionMap.h rename to 3party/osrm/osrm-backend/data_structures/restriction_map.hpp index 3945a3982b..27a6698dbc --- a/3party/osrm/osrm-backend/DataStructures/RestrictionMap.h +++ b/3party/osrm/osrm-backend/data_structures/restriction_map.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,28 +25,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef RESTRICTION_MAP_H_ -#define RESTRICTION_MAP_H_ +#ifndef RESTRICTION_MAP_HPP +#define RESTRICTION_MAP_HPP -#include - -#include "DynamicGraph.h" -#include "Restriction.h" -#include "NodeBasedGraph.h" -#include "../Util/StdHashExtensions.h" +#include "restriction.hpp" +#include "../util/std_hash.hpp" #include "../typedefs.h" +#include + +#include #include #include +#include struct RestrictionSource { NodeID start_node; NodeID via_node; - RestrictionSource(NodeID start, NodeID via) : start_node(start), via_node(via) - { - } + RestrictionSource(NodeID start, NodeID via) : start_node(start), via_node(via) {} friend inline bool operator==(const RestrictionSource &lhs, const RestrictionSource &rhs) { @@ -59,9 +57,7 @@ struct RestrictionTarget NodeID target_node; bool is_only; - explicit RestrictionTarget(NodeID target, bool only) : target_node(target), is_only(only) - { - } + explicit RestrictionTarget(NodeID target, bool only) : target_node(target), is_only(only) {} friend inline bool operator==(const RestrictionTarget &lhs, const RestrictionTarget &rhs) { @@ -95,26 +91,79 @@ template <> struct hash class RestrictionMap { public: - RestrictionMap(const std::shared_ptr &graph, - const std::vector &input_restrictions_list); + RestrictionMap(const std::vector &restriction_list); - void FixupArrivingTurnRestriction(const NodeID u, const NodeID v, const NodeID w); - void FixupStartingTurnRestriction(const NodeID u, const NodeID v, const NodeID w); - NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const; - bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const; - bool IsViaNode(const NodeID node) const; - std::size_t size() + // Replace end v with w in each turn restriction containing u as via node + template + void FixupArrivingTurnRestriction(const NodeID node_u, + const NodeID node_v, + const NodeID node_w, + const std::shared_ptr &graph) { - return m_count; + BOOST_ASSERT(node_u != SPECIAL_NODEID); + BOOST_ASSERT(node_v != SPECIAL_NODEID); + BOOST_ASSERT(node_w != SPECIAL_NODEID); + + if (!IsViaNode(node_u)) + { + return; + } + + // find all potential start edges. It is more efficent to get a (small) list + // of potential start edges than iterating over all buckets + std::vector predecessors; + for (const EdgeID current_edge_id : graph->GetAdjacentEdgeRange(node_u)) + { + const NodeID target = graph->GetTarget(current_edge_id); + if (node_v != target) + { + predecessors.push_back(target); + } + } + + for (const NodeID node_x : predecessors) + { + const auto restriction_iterator = m_restriction_map.find({node_x, node_u}); + if (restriction_iterator == m_restriction_map.end()) + { + continue; + } + + const unsigned index = restriction_iterator->second; + auto &bucket = m_restriction_bucket_list.at(index); + + for (RestrictionTarget &restriction_target : bucket) + { + if (node_v == restriction_target.target_node) + { + restriction_target.target_node = node_w; + } + } + } } + bool IsViaNode(const NodeID node) const; + + // Replaces start edge (v, w) with (u, w). Only start node changes. + void + FixupStartingTurnRestriction(const NodeID node_u, const NodeID node_v, const NodeID node_w); + + // Check if edge (u, v) is the start of any turn restriction. + // If so returns id of first target node. + NodeID CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const; + // Checks if turn is actually a turn restriction. + bool + CheckIfTurnIsRestricted(const NodeID node_u, const NodeID node_v, const NodeID node_w) const; + + std::size_t size() { return m_count; } + private: + // check of node is the start of any restriction bool IsSourceNode(const NodeID node) const; + using EmanatingRestrictionsVector = std::vector; - using EdgeData = NodeBasedDynamicGraph::EdgeData; std::size_t m_count; - std::shared_ptr m_graph; //! index -> list of (target, isOnly) std::vector m_restriction_bucket_list; //! maps (start, via) -> bucket index @@ -123,4 +172,4 @@ class RestrictionMap std::unordered_set m_no_turn_via_node_set; }; -#endif //RESTRICTION_MAP_H_ +#endif // RESTRICTION_MAP_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/RouteParameters.cpp b/3party/osrm/osrm-backend/data_structures/route_parameters.cpp old mode 100644 new mode 100755 similarity index 81% rename from 3party/osrm/osrm-backend/DataStructures/RouteParameters.cpp rename to 3party/osrm/osrm-backend/data_structures/route_parameters.cpp index 1019a9149e..3b615e2c41 --- a/3party/osrm/osrm-backend/DataStructures/RouteParameters.cpp +++ b/3party/osrm/osrm-backend/data_structures/route_parameters.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,15 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include - #include #include #include +#include + RouteParameters::RouteParameters() : zoom_level(18), print_instructions(false), alternate_route(true), geometry(true), - compression(true), deprecatedAPI(false), uturn_default(false), check_sum(-1), num_results(1) + compression(true), deprecatedAPI(false), uturn_default(false), classify(false), + matching_beta(-1.0), gps_precision(-1.0), check_sum(-1), num_results(1) { } @@ -83,6 +84,12 @@ void RouteParameters::setInstructionFlag(const bool flag) { print_instructions = void RouteParameters::setService(const std::string &service_string) { service = service_string; } +void RouteParameters::setClassify(const bool flag) { classify = flag; } + +void RouteParameters::setMatchingBeta(const double beta) { matching_beta = beta; } + +void RouteParameters::setGPSPrecision(const double precision) { gps_precision = precision; } + void RouteParameters::setOutputFormat(const std::string &format) { output_format = format; } void RouteParameters::setJSONpParameter(const std::string ¶meter) @@ -99,6 +106,15 @@ void RouteParameters::addHint(const std::string &hint) } } +void RouteParameters::addTimestamp(const unsigned timestamp) +{ + timestamps.resize(coordinates.size()); + if (!timestamps.empty()) + { + timestamps.back() = timestamp; + } +} + void RouteParameters::setLanguage(const std::string &language_string) { language = language_string; @@ -108,10 +124,10 @@ void RouteParameters::setGeometryFlag(const bool flag) { geometry = flag; } void RouteParameters::setCompressionFlag(const bool flag) { compression = flag; } -void -RouteParameters::addCoordinate(const boost::fusion::vector &transmitted_coordinates) +void RouteParameters::addCoordinate( + const boost::fusion::vector &received_coordinates) { coordinates.emplace_back( - static_cast(COORDINATE_PRECISION * boost::fusion::at_c<0>(transmitted_coordinates)), - static_cast(COORDINATE_PRECISION * boost::fusion::at_c<1>(transmitted_coordinates))); + static_cast(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)), + static_cast(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates))); } diff --git a/3party/osrm/osrm-backend/DataStructures/SearchEngine.h b/3party/osrm/osrm-backend/data_structures/search_engine.hpp old mode 100644 new mode 100755 similarity index 69% rename from 3party/osrm/osrm-backend/DataStructures/SearchEngine.h rename to 3party/osrm/osrm-backend/data_structures/search_engine.hpp index 58f5e774d6..7e47b1f5df --- a/3party/osrm/osrm-backend/DataStructures/SearchEngine.h +++ b/3party/osrm/osrm-backend/data_structures/search_engine.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,13 +25,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SEARCHENGINE_H -#define SEARCHENGINE_H +#ifndef SEARCH_ENGINE_HPP +#define SEARCH_ENGINE_HPP -#include "SearchEngineData.h" -#include "../RoutingAlgorithms/AlternativePathRouting.h" -#include "../RoutingAlgorithms/ManyToManyRouting.h" -#include "../RoutingAlgorithms/ShortestPathRouting.h" +#include "search_engine_data.hpp" +#include "../routing_algorithms/alternative_path.hpp" +#include "../routing_algorithms/many_to_many.hpp" +#include "../routing_algorithms/map_matching.hpp" +#include "../routing_algorithms/shortest_path.hpp" #include @@ -45,16 +46,21 @@ template class SearchEngine ShortestPathRouting shortest_path; AlternativeRouting alternative_path; ManyToManyRouting distance_table; + MapMatching map_matching; explicit SearchEngine(DataFacadeT *facade) - : facade(facade), shortest_path(facade, engine_working_data), - alternative_path(facade, engine_working_data), distance_table(facade, engine_working_data) + : facade(facade), + shortest_path(facade, engine_working_data), + alternative_path(facade, engine_working_data), + distance_table(facade, engine_working_data), + map_matching(facade, engine_working_data) { static_assert(!std::is_pointer::value, "don't instantiate with ptr type"); - static_assert(std::is_object::value, "don't instantiate with void, function, or reference"); + static_assert(std::is_object::value, + "don't instantiate with void, function, or reference"); } ~SearchEngine() {} }; -#endif // SEARCHENGINE_H +#endif // SEARCH_ENGINE_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/SearchEngineData.cpp b/3party/osrm/osrm-backend/data_structures/search_engine_data.cpp old mode 100644 new mode 100755 similarity index 67% rename from 3party/osrm/osrm-backend/DataStructures/SearchEngineData.cpp rename to 3party/osrm/osrm-backend/data_structures/search_engine_data.cpp index a5e4bfcd88..3282a0ccb2 --- a/3party/osrm/osrm-backend/DataStructures/SearchEngineData.cpp +++ b/3party/osrm/osrm-backend/data_structures/search_engine_data.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,69 +25,69 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "SearchEngineData.h" +#include "search_engine_data.hpp" -#include "BinaryHeap.h" +#include "binary_heap.hpp" void SearchEngineData::InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes) { - if (forwardHeap.get()) + if (forward_heap_1.get()) { - forwardHeap->Clear(); + forward_heap_1->Clear(); } else { - forwardHeap.reset(new QueryHeap(number_of_nodes)); + forward_heap_1.reset(new QueryHeap(number_of_nodes)); } - if (backwardHeap.get()) + if (reverse_heap_1.get()) { - backwardHeap->Clear(); + reverse_heap_1->Clear(); } else { - backwardHeap.reset(new QueryHeap(number_of_nodes)); + reverse_heap_1.reset(new QueryHeap(number_of_nodes)); } } void SearchEngineData::InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes) { - if (forwardHeap2.get()) + if (forward_heap_2.get()) { - forwardHeap2->Clear(); + forward_heap_2->Clear(); } else { - forwardHeap2.reset(new QueryHeap(number_of_nodes)); + forward_heap_2.reset(new QueryHeap(number_of_nodes)); } - if (backwardHeap2.get()) + if (reverse_heap_2.get()) { - backwardHeap2->Clear(); + reverse_heap_2->Clear(); } else { - backwardHeap2.reset(new QueryHeap(number_of_nodes)); + reverse_heap_2.reset(new QueryHeap(number_of_nodes)); } } void SearchEngineData::InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes) { - if (forwardHeap3.get()) + if (forward_heap_3.get()) { - forwardHeap3->Clear(); + forward_heap_3->Clear(); } else { - forwardHeap3.reset(new QueryHeap(number_of_nodes)); + forward_heap_3.reset(new QueryHeap(number_of_nodes)); } - if (backwardHeap3.get()) + if (reverse_heap_3.get()) { - backwardHeap3->Clear(); + reverse_heap_3->Clear(); } else { - backwardHeap3.reset(new QueryHeap(number_of_nodes)); + reverse_heap_3.reset(new QueryHeap(number_of_nodes)); } } diff --git a/3party/osrm/osrm-backend/DataStructures/SearchEngineData.h b/3party/osrm/osrm-backend/data_structures/search_engine_data.hpp old mode 100644 new mode 100755 similarity index 76% rename from 3party/osrm/osrm-backend/DataStructures/SearchEngineData.h rename to 3party/osrm/osrm-backend/data_structures/search_engine_data.hpp index 378ff95496..8c1c1619e0 --- a/3party/osrm/osrm-backend/DataStructures/SearchEngineData.h +++ b/3party/osrm/osrm-backend/data_structures/search_engine_data.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,13 +25,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SEARCH_ENGINE_DATA_H -#define SEARCH_ENGINE_DATA_H +#ifndef SEARCH_ENGINE_DATA_HPP +#define SEARCH_ENGINE_DATA_HPP -#include +#include #include "../typedefs.h" -#include "BinaryHeap.h" +#include "binary_heap.hpp" struct HeapData { @@ -42,14 +42,14 @@ struct HeapData struct SearchEngineData { using QueryHeap = BinaryHeap>; - using SearchEngineHeapPtr = boost::scoped_ptr; + using SearchEngineHeapPtr = boost::thread_specific_ptr; - static SearchEngineHeapPtr forwardHeap; - static SearchEngineHeapPtr backwardHeap; - static SearchEngineHeapPtr forwardHeap2; - static SearchEngineHeapPtr backwardHeap2; - static SearchEngineHeapPtr forwardHeap3; - static SearchEngineHeapPtr backwardHeap3; + static SearchEngineHeapPtr forward_heap_1; + static SearchEngineHeapPtr reverse_heap_1; + static SearchEngineHeapPtr forward_heap_2; + static SearchEngineHeapPtr reverse_heap_2; + static SearchEngineHeapPtr forward_heap_3; + static SearchEngineHeapPtr reverse_heap_3; void InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes); @@ -58,4 +58,4 @@ struct SearchEngineData void InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes); }; -#endif // SEARCH_ENGINE_DATA_H +#endif // SEARCH_ENGINE_DATA_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/SegmentInformation.h b/3party/osrm/osrm-backend/data_structures/segment_information.hpp old mode 100644 new mode 100755 similarity index 92% rename from 3party/osrm/osrm-backend/DataStructures/SegmentInformation.h rename to 3party/osrm/osrm-backend/data_structures/segment_information.hpp index 6e8d683974..7118a320e8 --- a/3party/osrm/osrm-backend/DataStructures/SegmentInformation.h +++ b/3party/osrm/osrm-backend/data_structures/segment_information.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,15 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SEGMENT_INFORMATION_H -#define SEGMENT_INFORMATION_H +#ifndef SEGMENT_INFORMATION_HPP +#define SEGMENT_INFORMATION_HPP -#include "TurnInstructions.h" +#include "turn_instructions.hpp" -#include "../DataStructures/TravelMode.h" +#include "../data_structures/travel_mode.hpp" #include "../typedefs.h" -#include +#include // Struct fits everything in one cache line struct SegmentInformation @@ -75,4 +75,4 @@ struct SegmentInformation } }; -#endif /* SEGMENT_INFORMATION_H */ +#endif /* SEGMENT_INFORMATION_HPP */ diff --git a/3party/osrm/osrm-backend/DataStructures/SharedMemoryFactory.h b/3party/osrm/osrm-backend/data_structures/shared_memory_factory.hpp old mode 100644 new mode 100755 similarity index 86% rename from 3party/osrm/osrm-backend/DataStructures/SharedMemoryFactory.h rename to 3party/osrm/osrm-backend/data_structures/shared_memory_factory.hpp index 7a0c0790b0..58fed9bb3f --- a/3party/osrm/osrm-backend/DataStructures/SharedMemoryFactory.h +++ b/3party/osrm/osrm-backend/data_structures/shared_memory_factory.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,25 +25,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SHARED_MEMORY_FACTORY_H -#define SHARED_MEMORY_FACTORY_H +#ifndef SHARED_MEMORY_FACTORY_HPP +#define SHARED_MEMORY_FACTORY_HPP -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" +#include "../util/osrm_exception.hpp" +#include "../util/simple_logger.hpp" #include #include #include -#if !defined(WIN32) && !defined(__ANDROID__) +#ifndef WIN32 #include #else #include #endif -//#ifdef __linux__ -//#include -//#include -//#endif +#ifdef __linux__ +#include +#include +#endif // #include #include @@ -61,7 +61,7 @@ struct OSRMLockFile } }; -#if !defined(WIN32) && !defined(__ANDROID__) +#ifndef WIN32 class SharedMemory { @@ -123,8 +123,8 @@ class SharedMemory { Remove(key); } - shm = boost::interprocess::xsi_shared_memory( - boost::interprocess::open_or_create, key, size); + shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_or_create, key, + size); #ifdef __linux__ if (-1 == shmctl(shm.get_shmid(), SHM_LOCK, 0)) { @@ -150,7 +150,10 @@ class SharedMemory boost::interprocess::xsi_key key(lock_file().string().c_str(), id); result = RegionExists(key); } - catch (...) { result = false; } + catch (...) + { + result = false; + } return result; } @@ -165,8 +168,14 @@ class SharedMemory static bool RegionExists(const boost::interprocess::xsi_key &key) { bool result = true; - try { boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key); } - catch (...) { result = false; } + try + { + boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key); + } + catch (...) + { + result = false; + } return result; } @@ -198,12 +207,12 @@ class SharedMemory // Windows - specific code class SharedMemory { - SharedMemory(const SharedMemory&) = delete; + SharedMemory(const SharedMemory &) = delete; // Remove shared memory on destruction class shm_remove { private: - shm_remove(const shm_remove&) = delete; + shm_remove(const shm_remove &) = delete; char *m_shmid; bool m_initialized; @@ -242,8 +251,7 @@ class SharedMemory if (0 == size) { // read_only shm = boost::interprocess::shared_memory_object( - boost::interprocess::open_only, - key, + boost::interprocess::open_only, key, read_write ? boost::interprocess::read_write : boost::interprocess::read_only); region = boost::interprocess::mapped_region( shm, read_write ? boost::interprocess::read_write : boost::interprocess::read_only); @@ -255,8 +263,8 @@ class SharedMemory { Remove(key); } - shm = boost::interprocess::shared_memory_object( - boost::interprocess::open_or_create, key, boost::interprocess::read_write); + shm = boost::interprocess::shared_memory_object(boost::interprocess::open_or_create, + key, boost::interprocess::read_write); shm.truncate(size); region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write); @@ -274,7 +282,10 @@ class SharedMemory build_key(id, k); result = RegionExists(k); } - catch (...) { result = false; } + catch (...) + { + result = false; + } return result; } @@ -286,20 +297,20 @@ class SharedMemory } private: - static void build_key(int id, char *key) - { - sprintf(key, "%s.%d", "osrm.lock", id); - } + static void build_key(int id, char *key) { sprintf(key, "%s.%d", "osrm.lock", id); } static bool RegionExists(const char *key) { bool result = true; try { - boost::interprocess::shared_memory_object shm( - boost::interprocess::open_only, key, boost::interprocess::read_write); + boost::interprocess::shared_memory_object shm(boost::interprocess::open_only, key, + boost::interprocess::read_write); + } + catch (...) + { + result = false; } - catch (...) { result = false; } return result; } @@ -344,7 +355,7 @@ template class SharedMemoryFactory_tmpl { if (0 == size) { - throw OSRMException("lock file does not exist, exiting"); + throw osrm::exception("lock file does not exist, exiting"); } else { @@ -358,7 +369,7 @@ template class SharedMemoryFactory_tmpl { SimpleLogger().Write(logWARNING) << "caught exception: " << e.what() << ", code " << e.get_error_code(); - throw OSRMException(e.what()); + throw osrm::exception(e.what()); } } @@ -368,4 +379,4 @@ template class SharedMemoryFactory_tmpl using SharedMemoryFactory = SharedMemoryFactory_tmpl<>; -#endif /* SHARED_MEMORY_POINTER_FACTORY_H */ +#endif // SHARED_MEMORY_FACTORY_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/SharedMemoryVectorWrapper.h b/3party/osrm/osrm-backend/data_structures/shared_memory_vector_wrapper.hpp old mode 100644 new mode 100755 similarity index 93% rename from 3party/osrm/osrm-backend/DataStructures/SharedMemoryVectorWrapper.h rename to 3party/osrm/osrm-backend/data_structures/shared_memory_vector_wrapper.hpp index bcc30a7f2c..dc51cff0d4 --- a/3party/osrm/osrm-backend/DataStructures/SharedMemoryVectorWrapper.h +++ b/3party/osrm/osrm-backend/data_structures/shared_memory_vector_wrapper.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SHARED_MEMORY_VECTOR_WRAPPER_H -#define SHARED_MEMORY_VECTOR_WRAPPER_H +#ifndef SHARED_MEMORY_VECTOR_WRAPPER_HPP +#define SHARED_MEMORY_VECTOR_WRAPPER_HPP #include @@ -147,8 +147,8 @@ template <> class SharedMemoryWrapper template struct ShM { using vector = typename std::conditional, - std::vector>::type; + SharedMemoryWrapper, + std::vector>::type; }; -#endif // SHARED_MEMORY_VECTOR_WRAPPER_H +#endif // SHARED_MEMORY_VECTOR_WRAPPER_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/StaticGraph.h b/3party/osrm/osrm-backend/data_structures/static_graph.hpp old mode 100644 new mode 100755 similarity index 85% rename from 3party/osrm/osrm-backend/DataStructures/StaticGraph.h rename to 3party/osrm/osrm-backend/data_structures/static_graph.hpp index b18ac0dfda..7434b56de6 --- a/3party/osrm/osrm-backend/DataStructures/StaticGraph.h +++ b/3party/osrm/osrm-backend/data_structures/static_graph.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,12 +25,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STATIC_GRAPH_H -#define STATIC_GRAPH_H +#ifndef STATIC_GRAPH_HPP +#define STATIC_GRAPH_HPP -#include "Percent.h" -#include "Range.h" -#include "SharedMemoryVectorWrapper.h" +#include "percent.hpp" +#include "shared_memory_vector_wrapper.hpp" +#include "../util/integer_range.hpp" #include "../typedefs.h" #include @@ -55,8 +55,11 @@ template class StaticGraph NodeIterator target; EdgeDataT data; - template - InputEdge(NodeIterator source, NodeIterator target, Ts &&...data) : source(source), target(target), data(std::forward(data)...) { } + template + InputEdge(NodeIterator source, NodeIterator target, Ts &&... data) + : source(source), target(target), data(std::forward(data)...) + { + } bool operator<(const InputEdge &right) const { if (source != right.source) @@ -86,13 +89,12 @@ template class StaticGraph StaticGraph(const int nodes, std::vector &graph) { - std::sort(graph.begin(), graph.end()); number_of_nodes = nodes; - number_of_edges = (EdgeIterator)graph.size(); + number_of_edges = static_cast(graph.size()); node_array.resize(number_of_nodes + 1); EdgeIterator edge = 0; EdgeIterator position = 0; - for (const auto node : osrm::irange(0u, number_of_nodes+1)) + for (const auto node : osrm::irange(0u, number_of_nodes + 1)) { EdgeIterator last_edge = edge; while (edge < number_of_edges && graph[edge].source == node) @@ -107,11 +109,10 @@ template class StaticGraph for (const auto node : osrm::irange(0u, number_of_nodes)) { EdgeIterator e = node_array[node + 1].first_edge; - for (EdgeIterator i = node_array[node].first_edge; i != e; ++i) + for (const auto i : osrm::irange(node_array[node].first_edge, e)) { edge_array[i].target = graph[edge].target; edge_array[i].data = graph[edge].data; - BOOST_ASSERT(edge_array[i].data.distance > 0); edge++; } } @@ -138,7 +139,7 @@ template class StaticGraph return NodeIterator(edge_array[e].target); } - inline EdgeDataT &GetEdgeData(const EdgeIterator e) { return edge_array[e].data; } + EdgeDataT &GetEdgeData(const EdgeIterator e) { return edge_array[e].data; } const EdgeDataT &GetEdgeData(const EdgeIterator e) const { return edge_array[e].data; } @@ -154,6 +155,19 @@ template class StaticGraph // searches for a specific edge EdgeIterator FindEdge(const NodeIterator from, const NodeIterator to) const + { + for (const auto i : osrm::irange(BeginEdges(from), EndEdges(from))) + { + if (to == edge_array[i].target) + { + return i; + } + } + return SPECIAL_EDGEID; + } + + // searches for a specific edge + EdgeIterator FindSmallestEdge(const NodeIterator from, const NodeIterator to) const { EdgeIterator smallest_edge = SPECIAL_EDGEID; EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT; @@ -199,4 +213,4 @@ template class StaticGraph typename ShM::vector edge_array; }; -#endif // STATIC_GRAPH_H +#endif // STATIC_GRAPH_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/StaticKDTree.h b/3party/osrm/osrm-backend/data_structures/static_kdtree.hpp old mode 100644 new mode 100755 similarity index 96% rename from 3party/osrm/osrm-backend/DataStructures/StaticKDTree.h rename to 3party/osrm/osrm-backend/data_structures/static_kdtree.hpp index 4e93884472..1e65dc8449 --- a/3party/osrm/osrm-backend/DataStructures/StaticKDTree.h +++ b/3party/osrm/osrm-backend/data_structures/static_kdtree.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -27,8 +27,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // KD Tree coded by Christian Vetter, Monav Project -#ifndef STATICKDTREE_H_INCLUDED -#define STATICKDTREE_H_INCLUDED +#ifndef STATICKDTREE_HPP +#define STATICKDTREE_HPP #include #include @@ -138,8 +138,8 @@ class StaticKDTree continue; Iterator middle = tree.left + (tree.right - tree.left) / 2; - std::nth_element( - kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less(tree.dimension)); + std::nth_element(kdtree + tree.left, kdtree + middle, kdtree + tree.right, + Less(tree.dimension)); s.push(Tree(tree.left, middle, (tree.dimension + 1) % k)); s.push(Tree(middle + 1, tree.right, (tree.dimension + 1) % k)); } @@ -257,4 +257,4 @@ class StaticKDTree }; } -#endif // STATICKDTREE_H_INCLUDED +#endif // STATICKDTREE_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/StaticRTree.h b/3party/osrm/osrm-backend/data_structures/static_rtree.hpp old mode 100644 new mode 100755 similarity index 56% rename from 3party/osrm/osrm-backend/DataStructures/StaticRTree.h rename to 3party/osrm/osrm-backend/data_structures/static_rtree.hpp index 260a9ca4ca..f219a64755 --- a/3party/osrm/osrm-backend/DataStructures/StaticRTree.h +++ b/3party/osrm/osrm-backend/data_structures/static_rtree.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,31 +25,38 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STATICRTREE_H -#define STATICRTREE_H +#ifndef STATIC_RTREE_HPP +#define STATIC_RTREE_HPP -#include "DeallocatingVector.h" -#include "HilbertValue.h" -#include "PhantomNodes.h" -#include "QueryNode.h" -#include "SharedMemoryFactory.h" -#include "SharedMemoryVectorWrapper.h" +#include "deallocating_vector.hpp" +#include "hilbert_value.hpp" +#include "phantom_node.hpp" +#include "query_node.hpp" +#include "rectangle.hpp" +#include "shared_memory_factory.hpp" +#include "shared_memory_vector_wrapper.hpp" +#include "upper_bound.hpp" -#include "../ThirdParty/variant/variant.hpp" -#include "../Util/floating_point.hpp" -#include "../Util/MercatorUtil.h" -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" -#include "../Util/TimingUtil.h" +#include "../util/floating_point.hpp" +#include "../util/integer_range.hpp" +#include "../util/mercator.hpp" +#include "../util/osrm_exception.hpp" +#include "../util/simple_logger.hpp" +#include "../util/timing_util.hpp" #include "../typedefs.h" -#include +#include #include #include #include #include +#include +#include + +#include + #include #include #include @@ -62,8 +69,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. template , bool UseSharedMemory = false, - uint32_t BRANCHING_FACTOR=64, - uint32_t LEAF_NODE_SIZE=1024> + uint32_t BRANCHING_FACTOR = 64, + uint32_t LEAF_NODE_SIZE = 1024> class StaticRTree { public: @@ -76,23 +83,19 @@ class StaticRTree inline void InitializeMBRectangle(const std::array &objects, const uint32_t element_count, - const std::vector &coordinate_list) + const std::vector &coordinate_list) { for (uint32_t i = 0; i < element_count; ++i) { - min_lon = std::min(min_lon, - std::min(coordinate_list.at(objects[i].u).lon, - coordinate_list.at(objects[i].v).lon)); - max_lon = std::max(max_lon, - std::max(coordinate_list.at(objects[i].u).lon, - coordinate_list.at(objects[i].v).lon)); + min_lon = std::min(min_lon, std::min(coordinate_list.at(objects[i].u).lon, + coordinate_list.at(objects[i].v).lon)); + max_lon = std::max(max_lon, std::max(coordinate_list.at(objects[i].u).lon, + coordinate_list.at(objects[i].v).lon)); - min_lat = std::min(min_lat, - std::min(coordinate_list.at(objects[i].u).lat, - coordinate_list.at(objects[i].v).lat)); - max_lat = std::max(max_lat, - std::max(coordinate_list.at(objects[i].u).lat, - coordinate_list.at(objects[i].v).lat)); + min_lat = std::min(min_lat, std::min(coordinate_list.at(objects[i].u).lat, + coordinate_list.at(objects[i].v).lat)); + max_lat = std::max(max_lat, std::max(coordinate_list.at(objects[i].u).lat, + coordinate_list.at(objects[i].v).lat)); } BOOST_ASSERT(min_lat != std::numeric_limits::min()); BOOST_ASSERT(min_lon != std::numeric_limits::min()); @@ -143,58 +146,66 @@ class StaticRTree enum Direction { - INVALID = 0, - NORTH = 1, - SOUTH = 2, - EAST = 4, + INVALID = 0, + NORTH = 1, + SOUTH = 2, + EAST = 4, NORTH_EAST = 5, SOUTH_EAST = 6, - WEST = 8, + WEST = 8, NORTH_WEST = 9, SOUTH_WEST = 10 }; Direction d = INVALID; if (location.lat > max_lat) - d = (Direction) (d | NORTH); + d = (Direction)(d | NORTH); else if (location.lat < min_lat) - d = (Direction) (d | SOUTH); + d = (Direction)(d | SOUTH); if (location.lon > max_lon) - d = (Direction) (d | EAST); + d = (Direction)(d | EAST); else if (location.lon < min_lon) - d = (Direction) (d | WEST); + d = (Direction)(d | WEST); BOOST_ASSERT(d != INVALID); float min_dist = std::numeric_limits::max(); switch (d) { - case NORTH: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, location.lon)); - break; - case SOUTH: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, location.lon)); - break; - case WEST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, min_lon)); - break; - case EAST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, max_lon)); - break; - case NORTH_EAST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, max_lon)); - break; - case NORTH_WEST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, min_lon)); - break; - case SOUTH_EAST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, max_lon)); - break; - case SOUTH_WEST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, min_lon)); - break; - default: - break; + case NORTH: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(max_lat, location.lon)); + break; + case SOUTH: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(min_lat, location.lon)); + break; + case WEST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(location.lat, min_lon)); + break; + case EAST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(location.lat, max_lon)); + break; + case NORTH_EAST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(max_lat, max_lon)); + break; + case NORTH_WEST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(max_lat, min_lon)); + break; + case SOUTH_EAST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(min_lat, max_lon)); + break; + case SOUTH_WEST: + min_dist = coordinate_calculation::euclidean_distance( + location, FixedPointCoordinate(min_lat, min_lon)); + break; + default: + break; } BOOST_ASSERT(min_dist != std::numeric_limits::max()); @@ -213,25 +224,23 @@ class StaticRTree min_max_dist = std::min( min_max_dist, - std::max( - FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left), - FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right))); + std::max(coordinate_calculation::euclidean_distance(location, upper_left), + coordinate_calculation::euclidean_distance(location, upper_right))); min_max_dist = std::min( min_max_dist, - std::max( - FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right), - FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right))); + std::max(coordinate_calculation::euclidean_distance(location, upper_right), + coordinate_calculation::euclidean_distance(location, lower_right))); min_max_dist = std::min( min_max_dist, - std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right), - FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left))); + std::max(coordinate_calculation::euclidean_distance(location, lower_right), + coordinate_calculation::euclidean_distance(location, lower_left))); min_max_dist = std::min( min_max_dist, - std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left), - FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left))); + std::max(coordinate_calculation::euclidean_distance(location, lower_left), + coordinate_calculation::euclidean_distance(location, upper_left))); return min_max_dist; } @@ -338,7 +347,7 @@ class StaticRTree explicit StaticRTree(std::vector &input_data_vector, const std::string tree_node_filename, const std::string leaf_node_filename, - const std::vector &coordinate_list) + const std::vector &coordinate_list) : m_element_count(input_data_vector.size()), m_leaf_node_filename(leaf_node_filename) { SimpleLogger().Write() << "constructing r-tree of " << m_element_count @@ -351,31 +360,39 @@ class StaticRTree HilbertCode get_hilbert_number; // generate auxiliary vector of hilbert-values - 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; + tbb::parallel_for( + tbb::blocked_range(0, m_element_count), + [&input_data_vector, &input_wrapper_vector, &get_hilbert_number, &coordinate_list]( + const tbb::blocked_range &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; - 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 * + mercator::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 - sort(input_wrapper_vector.begin(), input_wrapper_vector.end()); + tbb::parallel_sort(input_wrapper_vector.begin(), input_wrapper_vector.end()); std::vector tree_nodes_in_level; // pack M elements into leaf node and write to leaf file @@ -402,8 +419,8 @@ class StaticRTree } // generate tree node that resemble the objects in leaf and store it for next level - current_node.minimum_bounding_rectangle.InitializeMBRectangle( - current_leaf.objects, current_leaf.object_count, coordinate_list); + InitializeMBRectangle(current_node.minimum_bounding_rectangle, current_leaf.objects, + current_leaf.object_count, coordinate_list); current_node.child_is_on_disk = true; current_node.children[0] = tree_nodes_in_level.size(); tree_nodes_in_level.emplace_back(current_node); @@ -426,8 +443,7 @@ class StaticRTree TreeNode parent_node; // pack BRANCHING_FACTOR elements into tree_nodes each for (uint32_t current_child_node_index = 0; - BRANCHING_FACTOR > current_child_node_index; - ++current_child_node_index) + BRANCHING_FACTOR > current_child_node_index; ++current_child_node_index) { if (processed_tree_nodes_in_level < tree_nodes_in_level.size()) { @@ -457,17 +473,20 @@ class StaticRTree std::reverse(m_search_tree.begin(), m_search_tree.end()); uint32_t search_tree_size = m_search_tree.size(); - - 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; - } - } + tbb::parallel_for(tbb::blocked_range(0, search_tree_size), + [this, &search_tree_size](const tbb::blocked_range &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; + } + } + }); // open tree file boost::filesystem::ofstream tree_node_file(tree_node_filename, std::ios::binary); @@ -495,11 +514,11 @@ class StaticRTree if (!boost::filesystem::exists(node_file)) { - throw OSRMException("ram index file does not exist"); + throw osrm::exception("ram index file does not exist"); } if (0 == boost::filesystem::file_size(node_file)) { - throw OSRMException("ram index file is empty"); + throw osrm::exception("ram index file is empty"); } boost::filesystem::ifstream tree_node_file(node_file, std::ios::binary); @@ -515,11 +534,11 @@ class StaticRTree // open leaf node file and store thread specific pointer if (!boost::filesystem::exists(leaf_file)) { - throw OSRMException("mem index file does not exist"); + throw osrm::exception("mem index file does not exist"); } if (0 == boost::filesystem::file_size(leaf_file)) { - throw OSRMException("mem index file is empty"); + throw osrm::exception("mem index file is empty"); } leaves_stream.open(leaf_file, std::ios::binary); @@ -539,11 +558,11 @@ class StaticRTree // open leaf node file and store thread specific pointer if (!boost::filesystem::exists(leaf_file)) { - throw OSRMException("mem index file does not exist"); + throw osrm::exception("mem index file does not exist"); } if (0 == boost::filesystem::file_size(leaf_file)) { - throw OSRMException("mem index file is empty"); + throw osrm::exception("mem index file is empty"); } leaves_stream.open(leaf_file, std::ios::binary); @@ -584,17 +603,15 @@ class StaticRTree for (uint32_t i = 0; i < current_leaf_node.object_count; ++i) { EdgeDataT const ¤t_edge = current_leaf_node.objects[i]; - if (ignore_tiny_components && current_edge.is_in_tiny_cc) + if (ignore_tiny_components && current_edge.component_id != 0) { continue; } - float current_minimum_distance = - FixedPointCoordinate::ApproximateEuclideanDistance( - input_coordinate.lat, - input_coordinate.lon, - m_coordinate_list->at(current_edge.u).lat, - m_coordinate_list->at(current_edge.u).lon); + float current_minimum_distance = coordinate_calculation::euclidean_distance( + input_coordinate.lat, input_coordinate.lon, + m_coordinate_list->at(current_edge.u).lat, + m_coordinate_list->at(current_edge.u).lon); if (current_minimum_distance < min_dist) { // found a new minimum @@ -602,12 +619,10 @@ class StaticRTree result_coordinate = m_coordinate_list->at(current_edge.u); } - current_minimum_distance = - FixedPointCoordinate::ApproximateEuclideanDistance( - input_coordinate.lat, - input_coordinate.lon, - m_coordinate_list->at(current_edge.v).lat, - m_coordinate_list->at(current_edge.v).lon); + current_minimum_distance = coordinate_calculation::euclidean_distance( + input_coordinate.lat, input_coordinate.lon, + m_coordinate_list->at(current_edge.v).lat, + m_coordinate_list->at(current_edge.v).lon); if (current_minimum_distance < min_dist) { @@ -619,39 +634,33 @@ class StaticRTree } else { - min_max_dist = ExploreTreeNode(current_tree_node, - input_coordinate, - min_dist, - min_max_dist, - traversal_queue); + min_max_dist = ExploreTreeNode(current_tree_node, input_coordinate, min_dist, + min_max_dist, traversal_queue); } } } - return result_coordinate.isValid(); + return result_coordinate.is_valid(); } - // implementation of the Hjaltason/Samet query [3], a BFS traversal of the tree - bool - IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, - std::vector &result_phantom_node_vector, - const unsigned zoom_level, - const unsigned number_of_results, - const unsigned max_checked_segments = 4*LEAF_NODE_SIZE) + bool IncrementalFindPhantomNodeForCoordinate( + const FixedPointCoordinate &input_coordinate, + std::vector &result_phantom_node_vector, + const unsigned max_number_of_phantom_nodes, + const unsigned max_checked_elements = 4 * LEAF_NODE_SIZE) { - // TIMER_START(samet); - // SimpleLogger().Write(logDEBUG) << "searching for " << number_of_results << " results"; - std::vector min_found_distances(number_of_results, std::numeric_limits::max()); + unsigned inspected_elements = 0; + unsigned number_of_elements_from_big_cc = 0; + unsigned number_of_elements_from_tiny_cc = 0; - unsigned dequeues = 0; - unsigned inspected_mbrs = 0; - unsigned loaded_leafs = 0; - unsigned inspected_segments = 0; +#ifdef NDEBUG unsigned pruned_elements = 0; - unsigned ignored_segments = 0; - unsigned ignored_mbrs = 0; +#endif + std::pair projected_coordinate = { + mercator::lat2y(input_coordinate.lat / COORDINATE_PRECISION), + input_coordinate.lon / COORDINATE_PRECISION}; - unsigned number_of_results_found_in_big_cc = 0; - unsigned number_of_results_found_in_tiny_cc = 0; + // upper bound pruning technique + upper_bound pruning_bound(max_number_of_phantom_nodes); // initialize queue with root element std::priority_queue traversal_queue; @@ -662,202 +671,152 @@ class StaticRTree const IncrementalQueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop(); - ++dequeues; - - const float current_min_dist = min_found_distances[number_of_results-1]; - - if (current_query_node.min_dist > current_min_dist) - { - ++pruned_elements; - continue; - } - if (current_query_node.node.template is()) - { - const TreeNode & current_tree_node = current_query_node.node.template get(); + { // current object is a tree node + const TreeNode ¤t_tree_node = + current_query_node.node.template get(); if (current_tree_node.child_is_on_disk) { - ++loaded_leafs; - // SimpleLogger().Write(logDEBUG) << "loading leaf: " << current_tree_node.children[0] << " w/ mbr [" << - // current_tree_node.minimum_bounding_rectangle.min_lat/COORDINATE_PRECISION << "," << - // current_tree_node.minimum_bounding_rectangle.min_lon/COORDINATE_PRECISION << "," << - // current_tree_node.minimum_bounding_rectangle.max_lat/COORDINATE_PRECISION << "-" << - // current_tree_node.minimum_bounding_rectangle.max_lon/COORDINATE_PRECISION << "]"; - LeafNode current_leaf_node; LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node); - // Add all objects from leaf into queue - for (uint32_t i = 0; i < current_leaf_node.object_count; ++i) + + // current object represents a block on disk + for (const auto i : osrm::irange(0u, current_leaf_node.object_count)) { const auto ¤t_edge = current_leaf_node.objects[i]; - const float current_perpendicular_distance = - FixedPointCoordinate::ComputePerpendicularDistance( + const float current_perpendicular_distance = coordinate_calculation:: + perpendicular_distance_from_projected_coordinate( m_coordinate_list->at(current_edge.u), - m_coordinate_list->at(current_edge.v), - input_coordinate); + m_coordinate_list->at(current_edge.v), input_coordinate, + projected_coordinate); // distance must be non-negative - BOOST_ASSERT(0. <= current_perpendicular_distance); + BOOST_ASSERT(0.f <= current_perpendicular_distance); - if (current_perpendicular_distance < current_min_dist) + if (pruning_bound.get() >= current_perpendicular_distance || + current_edge.is_in_tiny_cc()) { + pruning_bound.insert(current_perpendicular_distance); traversal_queue.emplace(current_perpendicular_distance, current_edge); } +#ifdef NDEBUG else { - ++ignored_segments; + ++pruned_elements; } +#endif } - // SimpleLogger().Write(logDEBUG) << "added " << current_leaf_node.object_count << " roads into queue of " << traversal_queue.size(); } else { - ++inspected_mbrs; - // explore inner node - // SimpleLogger().Write(logDEBUG) << "explore inner node w/ mbr [" << - // current_tree_node.minimum_bounding_rectangle.min_lat/COORDINATE_PRECISION << "," << - // current_tree_node.minimum_bounding_rectangle.min_lon/COORDINATE_PRECISION << "," << - // current_tree_node.minimum_bounding_rectangle.max_lat/COORDINATE_PRECISION << "-" << - // current_tree_node.minimum_bounding_rectangle.max_lon/COORDINATE_PRECISION << "," << "]"; - - // for each child mbr - for (uint32_t i = 0; i < current_tree_node.child_count; ++i) + // for each child mbr get a lower bound and enqueue it + for (const auto i : osrm::irange(0u, current_tree_node.child_count)) { const int32_t child_id = current_tree_node.children[i]; const TreeNode &child_tree_node = m_search_tree[child_id]; - const RectangleT &child_rectangle = child_tree_node.minimum_bounding_rectangle; - const float lower_bound_to_element = child_rectangle.GetMinDist(input_coordinate); + const RectangleT &child_rectangle = + child_tree_node.minimum_bounding_rectangle; + const float lower_bound_to_element = + child_rectangle.GetMinDist(input_coordinate); + BOOST_ASSERT(0.f <= lower_bound_to_element); - // TODO - enough elements found, i.e. nearest distance > maximum distance? - // ie. some measure of 'confidence of accuracy' - - // check if it needs to be explored by mindist - if (lower_bound_to_element < current_min_dist) - { - traversal_queue.emplace(lower_bound_to_element, child_tree_node); - } - else - { - ++ignored_mbrs; - } + traversal_queue.emplace(lower_bound_to_element, child_tree_node); } - // SimpleLogger().Write(logDEBUG) << "added " << current_tree_node.child_count << " mbrs into queue of " << traversal_queue.size(); } } else - { - ++inspected_segments; + { // current object is a leaf node + ++inspected_elements; // inspecting an actual road segment - const EdgeDataT & current_segment = current_query_node.node.template get(); + const EdgeDataT ¤t_segment = + current_query_node.node.template get(); - // don't collect too many results from small components - if (number_of_results_found_in_big_cc == number_of_results && !current_segment.is_in_tiny_cc) - { - continue; - } - - // don't collect too many results from big components - if (number_of_results_found_in_tiny_cc == number_of_results && current_segment.is_in_tiny_cc) + // continue searching for the first segment from a big component + if (number_of_elements_from_big_cc == 0 && + number_of_elements_from_tiny_cc >= max_number_of_phantom_nodes && + current_segment.is_in_tiny_cc()) { continue; } // check if it is smaller than what we had before - float current_ratio = 0.; + float current_ratio = 0.f; FixedPointCoordinate foot_point_coordinate_on_segment; - const float current_perpendicular_distance = - FixedPointCoordinate::ComputePerpendicularDistance( - m_coordinate_list->at(current_segment.u), - m_coordinate_list->at(current_segment.v), - input_coordinate, - foot_point_coordinate_on_segment, - current_ratio); - BOOST_ASSERT(0. <= current_perpendicular_distance); + // const float current_perpendicular_distance = + coordinate_calculation::perpendicular_distance_from_projected_coordinate( + m_coordinate_list->at(current_segment.u), + m_coordinate_list->at(current_segment.v), input_coordinate, + projected_coordinate, foot_point_coordinate_on_segment, current_ratio); - if ((current_perpendicular_distance < current_min_dist) && - !osrm::epsilon_compare(current_perpendicular_distance, current_min_dist)) - { - // store phantom node in result vector - result_phantom_node_vector.emplace_back( - current_segment.forward_edge_based_node_id, - current_segment.reverse_edge_based_node_id, - current_segment.name_id, - current_segment.forward_weight, - current_segment.reverse_weight, - current_segment.forward_offset, - current_segment.reverse_offset, - current_segment.packed_geometry_id, - foot_point_coordinate_on_segment, - current_segment.fwd_segment_position, - current_segment.forward_travel_mode, - current_segment.backward_travel_mode); + // store phantom node in result vector + result_phantom_node_vector.emplace_back(current_segment, + foot_point_coordinate_on_segment); - // Hack to fix rounding errors and wandering via nodes. - FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back()); + // Hack to fix rounding errors and wandering via nodes. + FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back()); - // set forward and reverse weights on the phantom node - SetForwardAndReverseWeightsOnPhantomNode(current_segment, - result_phantom_node_vector.back()); + // set forward and reverse weights on the phantom node + SetForwardAndReverseWeightsOnPhantomNode(current_segment, + result_phantom_node_vector.back()); - // do we have results only in a small scc - if (current_segment.is_in_tiny_cc) - { - ++number_of_results_found_in_tiny_cc; - } - else - { - // found an element in a large component - min_found_distances[number_of_results_found_in_big_cc] = current_perpendicular_distance; - ++number_of_results_found_in_big_cc; - // SimpleLogger().Write(logDEBUG) << std::setprecision(8) << foot_point_coordinate_on_segment << " at " << current_perpendicular_distance; - } + // update counts on what we found from which result class + if (current_segment.is_in_tiny_cc()) + { // found an element in tiny component + ++number_of_elements_from_tiny_cc; + } + else + { // found an element in a big component + ++number_of_elements_from_big_cc; } } - // TODO add indicator to prune if maxdist > threshold - if (number_of_results == number_of_results_found_in_big_cc || inspected_segments >= max_checked_segments) + // stop the search by flushing the queue + if ((result_phantom_node_vector.size() >= max_number_of_phantom_nodes && + number_of_elements_from_big_cc > 0) || + inspected_elements >= max_checked_elements) { - // SimpleLogger().Write(logDEBUG) << "flushing queue of " << traversal_queue.size() << " elements"; - // work-around for traversal_queue.clear(); traversal_queue = std::priority_queue{}; } } - - // for (const PhantomNode& result_node : result_phantom_node_vector) - // { - // SimpleLogger().Write(logDEBUG) << std::setprecision(8) << "found location " << result_node.forward_node_id << " at " << result_node.location; - // } - // SimpleLogger().Write(logDEBUG) << "dequeues: " << dequeues; - // SimpleLogger().Write(logDEBUG) << "inspected_mbrs: " << inspected_mbrs; - // SimpleLogger().Write(logDEBUG) << "loaded_leafs: " << loaded_leafs; - // SimpleLogger().Write(logDEBUG) << "inspected_segments: " << inspected_segments; - // SimpleLogger().Write(logDEBUG) << "pruned_elements: " << pruned_elements; - // SimpleLogger().Write(logDEBUG) << "ignored_segments: " << ignored_segments; - // SimpleLogger().Write(logDEBUG) << "ignored_mbrs: " << ignored_mbrs; - - // SimpleLogger().Write(logDEBUG) << "number_of_results_found_in_big_cc: " << number_of_results_found_in_big_cc; - // SimpleLogger().Write(logDEBUG) << "number_of_results_found_in_tiny_cc: " << number_of_results_found_in_tiny_cc; - // TIMER_STOP(samet); - // SimpleLogger().Write() << "query took " << TIMER_MSEC(samet) << "ms"; - - // if we found an element in either category, then we are good +#ifdef NDEBUG +// SimpleLogger().Write() << "result_phantom_node_vector.size(): " << +// result_phantom_node_vector.size(); +// SimpleLogger().Write() << "max_number_of_phantom_nodes: " << max_number_of_phantom_nodes; +// SimpleLogger().Write() << "number_of_elements_from_big_cc: " << +// number_of_elements_from_big_cc; +// SimpleLogger().Write() << "number_of_elements_from_tiny_cc: " << +// number_of_elements_from_tiny_cc; +// SimpleLogger().Write() << "inspected_elements: " << inspected_elements; +// SimpleLogger().Write() << "max_checked_elements: " << max_checked_elements; +// SimpleLogger().Write() << "pruned_elements: " << pruned_elements; +#endif return !result_phantom_node_vector.empty(); } - // implementation of the Hjaltason/Samet query [3], a BFS traversal of the tree - bool - IncrementalFindPhantomNodeForCoordinateWithDistance(const FixedPointCoordinate &input_coordinate, - std::vector> &result_phantom_node_vector, - const unsigned zoom_level, - const unsigned number_of_results, - const unsigned max_checked_segments = 4*LEAF_NODE_SIZE) + // Returns elements within max_distance. + // If the minium of elements could not be found in the search radius, widen + // it until the minimum can be satisfied. + // At the number of returned nodes is capped at the given maximum. + bool IncrementalFindPhantomNodeForCoordinateWithDistance( + const FixedPointCoordinate &input_coordinate, + std::vector> &result_phantom_node_vector, + const double max_distance, + const unsigned min_number_of_phantom_nodes, + const unsigned max_number_of_phantom_nodes, + const unsigned max_checked_elements = 4 * LEAF_NODE_SIZE) { - std::vector min_found_distances(number_of_results, std::numeric_limits::max()); + unsigned inspected_elements = 0; + unsigned number_of_elements_from_big_cc = 0; + unsigned number_of_elements_from_tiny_cc = 0; - unsigned number_of_results_found_in_big_cc = 0; - unsigned number_of_results_found_in_tiny_cc = 0; + unsigned pruned_elements = 0; - unsigned inspected_segments = 0; + std::pair projected_coordinate = { + mercator::lat2y(input_coordinate.lat / COORDINATE_PRECISION), + input_coordinate.lon / COORDINATE_PRECISION}; + + // upper bound pruning technique + upper_bound pruning_bound(max_number_of_phantom_nodes); // initialize queue with root element std::priority_queue traversal_queue; @@ -868,144 +827,141 @@ class StaticRTree const IncrementalQueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop(); - const float current_min_dist = min_found_distances[number_of_results-1]; - - if (current_query_node.min_dist > current_min_dist) - { - continue; - } - - if (current_query_node.RepresentsTreeNode()) - { - const TreeNode & current_tree_node = current_query_node.node.template get(); + if (current_query_node.node.template is()) + { // current object is a tree node + const TreeNode ¤t_tree_node = + current_query_node.node.template get(); if (current_tree_node.child_is_on_disk) { LeafNode current_leaf_node; LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node); - // Add all objects from leaf into queue - for (uint32_t i = 0; i < current_leaf_node.object_count; ++i) + + // current object represents a block on disk + for (const auto i : osrm::irange(0u, current_leaf_node.object_count)) { const auto ¤t_edge = current_leaf_node.objects[i]; - const float current_perpendicular_distance = - FixedPointCoordinate::ComputePerpendicularDistance( + const float current_perpendicular_distance = coordinate_calculation:: + perpendicular_distance_from_projected_coordinate( m_coordinate_list->at(current_edge.u), - m_coordinate_list->at(current_edge.v), - input_coordinate); + m_coordinate_list->at(current_edge.v), input_coordinate, + projected_coordinate); // distance must be non-negative - BOOST_ASSERT(0. <= current_perpendicular_distance); + BOOST_ASSERT(0.f <= current_perpendicular_distance); - if (current_perpendicular_distance < current_min_dist) + if (pruning_bound.get() >= current_perpendicular_distance || + current_edge.is_in_tiny_cc()) { + pruning_bound.insert(current_perpendicular_distance); traversal_queue.emplace(current_perpendicular_distance, current_edge); } + else + { + ++pruned_elements; + } } } else { - // for each child mbr - for (uint32_t i = 0; i < current_tree_node.child_count; ++i) + // for each child mbr get a lower bound and enqueue it + for (const auto i : osrm::irange(0u, current_tree_node.child_count)) { const int32_t child_id = current_tree_node.children[i]; const TreeNode &child_tree_node = m_search_tree[child_id]; - const RectangleT &child_rectangle = child_tree_node.minimum_bounding_rectangle; - const float lower_bound_to_element = child_rectangle.GetMinDist(input_coordinate); + const RectangleT &child_rectangle = + child_tree_node.minimum_bounding_rectangle; + const float lower_bound_to_element = + child_rectangle.GetMinDist(input_coordinate); + BOOST_ASSERT(0.f <= lower_bound_to_element); - // TODO - enough elements found, i.e. nearest distance > maximum distance? - // ie. some measure of 'confidence of accuracy' - - // check if it needs to be explored by mindist - if (lower_bound_to_element < current_min_dist) - { - traversal_queue.emplace(lower_bound_to_element, child_tree_node); - } + traversal_queue.emplace(lower_bound_to_element, child_tree_node); } - // SimpleLogger().Write(logDEBUG) << "added " << current_tree_node.child_count << " mbrs into queue of " << traversal_queue.size(); } } else - { - ++inspected_segments; + { // current object is a leaf node + ++inspected_elements; // inspecting an actual road segment - const EdgeDataT & current_segment = current_query_node.node.template get(); + const EdgeDataT ¤t_segment = + current_query_node.node.template get(); - // don't collect too many results from small components - if (number_of_results_found_in_big_cc == number_of_results && !current_segment.is_in_tiny_cc) - { - continue; - } - - // don't collect too many results from big components - if (number_of_results_found_in_tiny_cc == number_of_results && current_segment.is_in_tiny_cc) + // continue searching for the first segment from a big component + if (number_of_elements_from_big_cc == 0 && + number_of_elements_from_tiny_cc >= max_number_of_phantom_nodes - 1 && + current_segment.is_in_tiny_cc()) { continue; } // check if it is smaller than what we had before - float current_ratio = 0.; + float current_ratio = 0.f; FixedPointCoordinate foot_point_coordinate_on_segment; + const float current_perpendicular_distance = - FixedPointCoordinate::ComputePerpendicularDistance( + coordinate_calculation::perpendicular_distance_from_projected_coordinate( m_coordinate_list->at(current_segment.u), - m_coordinate_list->at(current_segment.v), - input_coordinate, - foot_point_coordinate_on_segment, - current_ratio); + m_coordinate_list->at(current_segment.v), input_coordinate, + projected_coordinate, foot_point_coordinate_on_segment, current_ratio); - BOOST_ASSERT(0. <= current_perpendicular_distance); - - if ((current_perpendicular_distance < current_min_dist) && - !osrm::epsilon_compare(current_perpendicular_distance, current_min_dist)) + if (number_of_elements_from_big_cc > 0 && + result_phantom_node_vector.size() >= min_number_of_phantom_nodes && + current_perpendicular_distance >= max_distance) { - // store phantom node in result vector - result_phantom_node_vector.emplace_back( + traversal_queue = std::priority_queue{}; + continue; + } + + // store phantom node in result vector + result_phantom_node_vector.emplace_back( + PhantomNode( current_segment.forward_edge_based_node_id, - current_segment.reverse_edge_based_node_id, - current_segment.name_id, - current_segment.forward_weight, - current_segment.reverse_weight, - current_segment.forward_offset, - current_segment.reverse_offset, - current_segment.packed_geometry_id, - foot_point_coordinate_on_segment, - current_segment.fwd_segment_position, - current_perpendicular_distance); + current_segment.reverse_edge_based_node_id, current_segment.name_id, + current_segment.forward_weight, current_segment.reverse_weight, + current_segment.forward_offset, current_segment.reverse_offset, + current_segment.packed_geometry_id, current_segment.component_id, + foot_point_coordinate_on_segment, current_segment.fwd_segment_position, + current_segment.forward_travel_mode, current_segment.backward_travel_mode), + current_perpendicular_distance); - // Hack to fix rounding errors and wandering via nodes. - FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back()); + // Hack to fix rounding errors and wandering via nodes. + FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back().first); - // set forward and reverse weights on the phantom node - SetForwardAndReverseWeightsOnPhantomNode(current_segment, - result_phantom_node_vector.back()); + // set forward and reverse weights on the phantom node + SetForwardAndReverseWeightsOnPhantomNode(current_segment, + result_phantom_node_vector.back().first); - // do we have results only in a small scc - if (current_segment.is_in_tiny_cc) - { - ++number_of_results_found_in_tiny_cc; - } - else - { - // found an element in a large component - min_found_distances[number_of_results_found_in_big_cc] = current_perpendicular_distance; - ++number_of_results_found_in_big_cc; - // SimpleLogger().Write(logDEBUG) << std::setprecision(8) << foot_point_coordinate_on_segment << " at " << current_perpendicular_distance; - } + // update counts on what we found from which result class + if (current_segment.is_in_tiny_cc()) + { // found an element in tiny component + ++number_of_elements_from_tiny_cc; + } + else + { // found an element in a big component + ++number_of_elements_from_big_cc; } } - // TODO add indicator to prune if maxdist > threshold - if (number_of_results == number_of_results_found_in_big_cc || inspected_segments >= max_checked_segments) + // stop the search by flushing the queue + if ((result_phantom_node_vector.size() >= max_number_of_phantom_nodes && + number_of_elements_from_big_cc > 0) || + inspected_elements >= max_checked_elements) { - // SimpleLogger().Write(logDEBUG) << "flushing queue of " << traversal_queue.size() << " elements"; - // work-around for traversal_queue.clear(); traversal_queue = std::priority_queue{}; } } + // SimpleLogger().Write() << "result_phantom_node_vector.size(): " << + // result_phantom_node_vector.size(); + // SimpleLogger().Write() << "max_number_of_phantom_nodes: " << max_number_of_phantom_nodes; + // SimpleLogger().Write() << "number_of_elements_from_big_cc: " << + // number_of_elements_from_big_cc; + // SimpleLogger().Write() << "number_of_elements_from_tiny_cc: " << + // number_of_elements_from_tiny_cc; + // SimpleLogger().Write() << "inspected_elements: " << inspected_elements; + // SimpleLogger().Write() << "max_checked_elements: " << max_checked_elements; + // SimpleLogger().Write() << "pruned_elements: " << pruned_elements; return !result_phantom_node_vector.empty(); } - - bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, PhantomNode &result_phantom_node, const unsigned zoom_level) @@ -1036,7 +992,7 @@ class StaticRTree for (uint32_t i = 0; i < current_leaf_node.object_count; ++i) { const EdgeDataT ¤t_edge = current_leaf_node.objects[i]; - if (ignore_tiny_components && current_edge.is_in_tiny_cc) + if (ignore_tiny_components && current_edge.component_id != 0) { continue; } @@ -1044,11 +1000,9 @@ class StaticRTree float current_ratio = 0.; FixedPointCoordinate nearest; const float current_perpendicular_distance = - FixedPointCoordinate::ComputePerpendicularDistance( + coordinate_calculation::perpendicular_distance( m_coordinate_list->at(current_edge.u), - m_coordinate_list->at(current_edge.v), - input_coordinate, - nearest, + m_coordinate_list->at(current_edge.v), input_coordinate, nearest, current_ratio); BOOST_ASSERT(0. <= current_perpendicular_distance); @@ -1065,6 +1019,7 @@ class StaticRTree current_edge.forward_offset, current_edge.reverse_offset, current_edge.packed_geometry_id, + current_edge.component_id, nearest, current_edge.fwd_segment_position, current_edge.forward_travel_mode, @@ -1075,16 +1030,13 @@ class StaticRTree } else { - min_max_dist = ExploreTreeNode(current_tree_node, - input_coordinate, - min_dist, - min_max_dist, - traversal_queue); + min_max_dist = ExploreTreeNode(current_tree_node, input_coordinate, min_dist, + min_max_dist, traversal_queue); } } } - if (result_phantom_node.location.isValid()) + if (result_phantom_node.location.is_valid()) { // Hack to fix rounding errors and wandering via nodes. FixUpRoundingIssue(input_coordinate, result_phantom_node); @@ -1092,42 +1044,50 @@ class StaticRTree // set forward and reverse weights on the phantom node SetForwardAndReverseWeightsOnPhantomNode(nearest_edge, result_phantom_node); } - return result_phantom_node.location.isValid(); + return result_phantom_node.location.is_valid(); } private: - - inline void SetForwardAndReverseWeightsOnPhantomNode(const EdgeDataT & nearest_edge, + inline void SetForwardAndReverseWeightsOnPhantomNode(const EdgeDataT &nearest_edge, PhantomNode &result_phantom_node) const { - const float distance_1 = FixedPointCoordinate::ApproximateEuclideanDistance( + const float distance_1 = coordinate_calculation::euclidean_distance( m_coordinate_list->at(nearest_edge.u), result_phantom_node.location); - const float distance_2 = FixedPointCoordinate::ApproximateEuclideanDistance( + const float distance_2 = coordinate_calculation::euclidean_distance( m_coordinate_list->at(nearest_edge.u), m_coordinate_list->at(nearest_edge.v)); const float ratio = std::min(1.f, distance_1 / distance_2); + using TreeWeightType = decltype(result_phantom_node.forward_weight); + static_assert(std::is_same::value, + "forward and reverse weight type in tree must be the same"); + if (SPECIAL_NODEID != result_phantom_node.forward_node_id) { - result_phantom_node.forward_weight *= ratio; + const auto new_weight = + static_cast(result_phantom_node.forward_weight * ratio); + result_phantom_node.forward_weight = new_weight; } if (SPECIAL_NODEID != result_phantom_node.reverse_node_id) { - result_phantom_node.reverse_weight *= (1.f - ratio); + const auto new_weight = + static_cast(result_phantom_node.reverse_weight * (1.f - ratio)); + result_phantom_node.reverse_weight = new_weight; } } // fixup locations if too close to inputs inline void FixUpRoundingIssue(const FixedPointCoordinate &input_coordinate, - PhantomNode &result_phantom_node) const + PhantomNode &result_phantom_node) const { - if (1 == std::abs(input_coordinate.lon - result_phantom_node.location.lon)) - { - result_phantom_node.location.lon = input_coordinate.lon; - } - if (1 == std::abs(input_coordinate.lat - result_phantom_node.location.lat)) - { - result_phantom_node.location.lat = input_coordinate.lat; - } + if (1 == std::abs(input_coordinate.lon - result_phantom_node.location.lon)) + { + result_phantom_node.location.lon = input_coordinate.lon; + } + if (1 == std::abs(input_coordinate.lat - result_phantom_node.location.lat)) + { + result_phantom_node.location.lat = input_coordinate.lat; + } } template @@ -1173,8 +1133,7 @@ class StaticRTree } const uint64_t seek_pos = sizeof(uint64_t) + leaf_id * sizeof(LeafNode); leaves_stream.seekg(seek_pos); - BOOST_ASSERT_MSG(leaves_stream.good(), - "Seeking to position in leaf file failed."); + BOOST_ASSERT_MSG(leaves_stream.good(), "Seeking to position in leaf file failed."); leaves_stream.read((char *)&result_node, sizeof(LeafNode)); BOOST_ASSERT_MSG(leaves_stream.good(), "Reading from leaf file failed."); } @@ -1186,10 +1145,37 @@ class StaticRTree { return (a == b && c == d) || (a == c && b == d) || (a == d && b == c); } + + inline void InitializeMBRectangle(RectangleT &rectangle, + const std::array &objects, + const uint32_t element_count, + const std::vector &coordinate_list) + { + for (uint32_t i = 0; i < element_count; ++i) + { + rectangle.min_lon = + std::min(rectangle.min_lon, std::min(coordinate_list.at(objects[i].u).lon, + coordinate_list.at(objects[i].v).lon)); + rectangle.max_lon = + std::max(rectangle.max_lon, std::max(coordinate_list.at(objects[i].u).lon, + coordinate_list.at(objects[i].v).lon)); + + rectangle.min_lat = + std::min(rectangle.min_lat, std::min(coordinate_list.at(objects[i].u).lat, + coordinate_list.at(objects[i].v).lat)); + rectangle.max_lat = + std::max(rectangle.max_lat, std::max(coordinate_list.at(objects[i].u).lat, + coordinate_list.at(objects[i].v).lat)); + } + BOOST_ASSERT(rectangle.min_lat != std::numeric_limits::min()); + BOOST_ASSERT(rectangle.min_lon != std::numeric_limits::min()); + BOOST_ASSERT(rectangle.max_lat != std::numeric_limits::min()); + BOOST_ASSERT(rectangle.max_lon != std::numeric_limits::min()); + } }; //[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403 //[2] "Nearest Neighbor Queries", N. Roussopulos et al; 1995; DOI: 10.1145/223784.223794 //[3] "Distance Browsing in Spatial Databases"; G. Hjaltason, H. Samet; 1999; ACM Trans. DB Sys // Vol.24 No.2, pp.265-318 -#endif // STATICRTREE_H +#endif // STATIC_RTREE_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/TravelMode.h b/3party/osrm/osrm-backend/data_structures/travel_mode.hpp old mode 100644 new mode 100755 similarity index 91% rename from 3party/osrm/osrm-backend/DataStructures/TravelMode.h rename to 3party/osrm/osrm-backend/data_structures/travel_mode.hpp index 7ccc24d215..2bbe463177 --- a/3party/osrm/osrm-backend/DataStructures/TravelMode.h +++ b/3party/osrm/osrm-backend/data_structures/travel_mode.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,11 +25,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef TRAVEL_MODE_H -#define TRAVEL_MODE_H +#ifndef TRAVEL_MODE_HPP +#define TRAVEL_MODE_HPP +namespace +{ using TravelMode = unsigned char; static const TravelMode TRAVEL_MODE_INACCESSIBLE = 0; static const TravelMode TRAVEL_MODE_DEFAULT = 1; - -#endif /* TRAVEL_MODE_H */ +} +#endif /* TRAVEL_MODE_HPP */ diff --git a/3party/osrm/osrm-backend/data_structures/tribool.hpp b/3party/osrm/osrm-backend/data_structures/tribool.hpp new file mode 100755 index 0000000000..2d4b6108dd --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/tribool.hpp @@ -0,0 +1,40 @@ +/* + +Copyright (c) 2015, 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 TRIBOOL_HPP +#define TRIBOOL_HPP + +namespace osrm +{ +enum class tribool : char +{ + yes, + no, + indeterminate +}; +} +#endif // TRIBOOL_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/TurnInstructions.h b/3party/osrm/osrm-backend/data_structures/turn_instructions.hpp old mode 100644 new mode 100755 similarity index 78% rename from 3party/osrm/osrm-backend/DataStructures/TurnInstructions.h rename to 3party/osrm/osrm-backend/data_structures/turn_instructions.hpp index 611b574ddd..1ca065f680 --- a/3party/osrm/osrm-backend/DataStructures/TurnInstructions.h +++ b/3party/osrm/osrm-backend/data_structures/turn_instructions.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,15 +25,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef TURN_INSTRUCTIONS_H -#define TURN_INSTRUCTIONS_H +#ifndef TURN_INSTRUCTIONS_HPP +#define TURN_INSTRUCTIONS_HPP enum class TurnInstruction : unsigned char { - NoTurn = 0, GoStraight, TurnSlightRight, TurnRight, TurnSharpRight, UTurn, - TurnSharpLeft, TurnLeft, TurnSlightLeft, ReachViaLocation, HeadOn, EnterRoundAbout, - LeaveRoundAbout, StayOnRoundAbout, StartAtEndOfStreet, ReachedYourDestination, - EnterAgainstAllowedDirection, LeaveAgainstAllowedDirection, + NoTurn = 0, + GoStraight, + TurnSlightRight, + TurnRight, + TurnSharpRight, + UTurn, + TurnSharpLeft, + TurnLeft, + TurnSlightLeft, + ReachViaLocation, + HeadOn, + EnterRoundAbout, + LeaveRoundAbout, + StayOnRoundAbout, + StartAtEndOfStreet, + ReachedYourDestination, + EnterAgainstAllowedDirection, + LeaveAgainstAllowedDirection, InverseAccessRestrictionFlag = 127, AccessRestrictionFlag = 128, AccessRestrictionPenalty = 129 @@ -42,7 +56,7 @@ enum class TurnInstruction : unsigned char struct TurnInstructionsClass { TurnInstructionsClass() = delete; - TurnInstructionsClass(const TurnInstructionsClass&) = delete; + TurnInstructionsClass(const TurnInstructionsClass &) = delete; static inline TurnInstruction GetTurnDirectionOfInstruction(const double angle) { @@ -79,7 +93,8 @@ struct TurnInstructionsClass static inline bool TurnIsNecessary(const TurnInstruction turn_instruction) { - if (TurnInstruction::NoTurn == turn_instruction || TurnInstruction::StayOnRoundAbout == turn_instruction) + if (TurnInstruction::NoTurn == turn_instruction || + TurnInstruction::StayOnRoundAbout == turn_instruction) { return false; } @@ -87,4 +102,4 @@ struct TurnInstructionsClass } }; -#endif /* TURN_INSTRUCTIONS_H */ +#endif /* TURN_INSTRUCTIONS_HPP */ diff --git a/3party/osrm/osrm-backend/data_structures/upper_bound.hpp b/3party/osrm/osrm-backend/data_structures/upper_bound.hpp new file mode 100755 index 0000000000..80695f2c51 --- /dev/null +++ b/3party/osrm/osrm-backend/data_structures/upper_bound.hpp @@ -0,0 +1,77 @@ +/* + +Copyright (c) 2015, 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 LOWER_BOUND_HPP +#define LOWER_BOUND_HPP + +#include +#include +#include +#include + +// max pq holds k elements +// insert if key is smaller than max +// if size > k then remove element +// get() always yields a bound to the k smallest element in the stream + +template class upper_bound +{ + private: + using parameter_type = + typename std::conditional::value, key_type, key_type &>::type; + + public: + upper_bound() = delete; + upper_bound(std::size_t size) : size(size) {} + + key_type get() const + { + if (queue.size() < size) + { + return std::numeric_limits::max(); + } + return queue.top(); + } + + void insert(const parameter_type key) + { + if (key < get()) + { + queue.emplace(key); + while (queue.size() > size) + { + queue.pop(); + } + } + } + + private: + std::priority_queue, std::less> queue; + const std::size_t size; +}; + +#endif // LOWER_BOUND_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/XORFastHash.h b/3party/osrm/osrm-backend/data_structures/xor_fast_hash.hpp old mode 100644 new mode 100755 similarity index 88% rename from 3party/osrm/osrm-backend/DataStructures/XORFastHash.h rename to 3party/osrm/osrm-backend/data_structures/xor_fast_hash.hpp index aba6ef40a8..3af5ab1dbd --- a/3party/osrm/osrm-backend/DataStructures/XORFastHash.h +++ b/3party/osrm/osrm-backend/data_structures/xor_fast_hash.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef XOR_FAST_HASH_H -#define XOR_FAST_HASH_H +#ifndef XOR_FAST_HASH_HPP +#define XOR_FAST_HASH_HPP #include #include @@ -61,8 +61,8 @@ class XORFastHash table2.resize(2 << 16); for (unsigned i = 0; i < (2 << 16); ++i) { - table1[i] = i; - table2[i] = i; + table1[i] = static_cast(i); + table2[i] = static_cast(i); } std::random_shuffle(table1.begin(), table1.end()); std::random_shuffle(table2.begin(), table2.end()); @@ -92,10 +92,10 @@ class XORMiniHash table4.resize(1 << 8); for (unsigned i = 0; i < (1 << 8); ++i) { - table1[i] = i; - table2[i] = i; - table3[i] = i; - table4[i] = i; + table1[i] = static_cast(i); + table2[i] = static_cast(i); + table3[i] = static_cast(i); + table4[i] = static_cast(i); } std::random_shuffle(table1.begin(), table1.end()); std::random_shuffle(table2.begin(), table2.end()); @@ -112,4 +112,4 @@ class XORMiniHash } }; -#endif // XOR_FAST_HASH_H +#endif // XOR_FAST_HASH_HPP diff --git a/3party/osrm/osrm-backend/DataStructures/XORFastHashStorage.h b/3party/osrm/osrm-backend/data_structures/xor_fast_hash_storage.hpp old mode 100644 new mode 100755 similarity index 70% rename from 3party/osrm/osrm-backend/DataStructures/XORFastHashStorage.h rename to 3party/osrm/osrm-backend/data_structures/xor_fast_hash_storage.hpp index 18de3c52c8..ff65717a3a --- a/3party/osrm/osrm-backend/DataStructures/XORFastHashStorage.h +++ b/3party/osrm/osrm-backend/data_structures/xor_fast_hash_storage.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,10 +25,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef XOR_FAST_HASH_STORAGE_H -#define XOR_FAST_HASH_STORAGE_H +#ifndef XOR_FAST_HASH_STORAGE_HPP +#define XOR_FAST_HASH_STORAGE_HPP -#include "XORFastHash.h" +#include "xor_fast_hash.hpp" #include #include @@ -38,22 +38,24 @@ template class XORFastHashStorage public: struct HashCell { - Key key; - NodeID id; unsigned time; + NodeID id; + Key key; HashCell() - : key(std::numeric_limits::max()), id(std::numeric_limits::max()), - time(std::numeric_limits::max()) + : time(std::numeric_limits::max()), id(std::numeric_limits::max()), + key(std::numeric_limits::max()) { } - HashCell(const HashCell &other) : key(other.key), id(other.id), time(other.time) {} + HashCell(const HashCell &other) : time(other.key), id(other.id), key(other.time) {} operator Key() const { return key; } - void operator=(const Key &key_to_insert) { key = key_to_insert; } + void operator=(const Key key_to_insert) { key = key_to_insert; } }; + XORFastHashStorage() = delete; + explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {} HashCell &operator[](const NodeID node) @@ -64,26 +66,36 @@ template class XORFastHashStorage ++position %= (2 << 16); } - positions[position].id = node; positions[position].time = current_timestamp; + positions[position].id = node; return positions[position]; } + // peek into table, get key for node, think of it as a read-only operator[] + Key peek_index(const NodeID node) const + { + unsigned short position = fast_hasher(node); + while ((positions[position].time == current_timestamp) && (positions[position].id != node)) + { + ++position %= (2 << 16); + } + return positions[position].key; + } + void Clear() { ++current_timestamp; if (std::numeric_limits::max() == current_timestamp) { positions.clear(); - positions.resize((2 << 16)); + positions.resize(2 << 16); } } private: - XORFastHashStorage() : positions(2 << 16), current_timestamp(0) {} std::vector positions; XORFastHash fast_hasher; unsigned current_timestamp; }; -#endif // XOR_FAST_HASH_STORAGE_H +#endif // XOR_FAST_HASH_STORAGE_HPP diff --git a/3party/osrm/osrm-backend/datastore.cpp b/3party/osrm/osrm-backend/datastore.cpp old mode 100644 new mode 100755 index e26ab4b8ac..3c032a2a96 --- a/3party/osrm/osrm-backend/datastore.cpp +++ b/3party/osrm/osrm-backend/datastore.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,24 +25,28 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "DataStructures/OriginalEdgeData.h" -#include "DataStructures/RangeTable.h" -#include "DataStructures/QueryEdge.h" -#include "DataStructures/SharedMemoryFactory.h" -#include "DataStructures/SharedMemoryVectorWrapper.h" -#include "DataStructures/StaticGraph.h" -#include "DataStructures/StaticRTree.h" -#include "DataStructures/TurnInstructions.h" -#include "Server/DataStructures/BaseDataFacade.h" -#include "Server/DataStructures/SharedDataType.h" -#include "Server/DataStructures/SharedBarriers.h" -#include "Util/BoostFileSystemFix.h" -#include "Util/DataStoreOptions.h" -#include "Util/simple_logger.hpp" -#include "Util/FingerPrint.h" +#include "data_structures/original_edge_data.hpp" +#include "data_structures/range_table.hpp" +#include "data_structures/query_edge.hpp" +#include "data_structures/query_node.hpp" +#include "data_structures/shared_memory_factory.hpp" +#include "data_structures/shared_memory_vector_wrapper.hpp" +#include "data_structures/static_graph.hpp" +#include "data_structures/static_rtree.hpp" +#include "data_structures/travel_mode.hpp" +#include "data_structures/turn_instructions.hpp" +#include "server/data_structures/datafacade_base.hpp" +#include "server/data_structures/shared_datatype.hpp" +#include "server/data_structures/shared_barriers.hpp" +#include "util/boost_filesystem_2_fix.hpp" +#include "util/datastore_options.hpp" +#include "util/simple_logger.hpp" +#include "util/osrm_exception.hpp" +#include "util/fingerprint.hpp" #include "typedefs.h" -#include +#include +#include using RTreeLeaf = BaseDataFacade::RTreeLeaf; using RTreeNode = StaticRTree::vector, true>::TreeNode; @@ -102,7 +106,8 @@ int main(const int argc, const char *argv[]) const bool lock_flags = MCL_CURRENT | MCL_FUTURE; if (-1 == mlockall(lock_flags)) { - SimpleLogger().Write(logWARNING) << "Process " << argv[0] << " could not request RAM lock"; + SimpleLogger().Write(logWARNING) << "Process " << argv[0] + << " could not request RAM lock"; } #endif try @@ -133,31 +138,31 @@ int main(const int argc, const char *argv[]) if (server_paths.find("hsgrdata") == server_paths.end()) { - throw OSRMException("no hsgr file found"); + throw osrm::exception("no hsgr file found"); } if (server_paths.find("ramindex") == server_paths.end()) { - throw OSRMException("no ram index file found"); + throw osrm::exception("no ram index file found"); } if (server_paths.find("fileindex") == server_paths.end()) { - throw OSRMException("no leaf index file found"); + throw osrm::exception("no leaf index file found"); } if (server_paths.find("nodesdata") == server_paths.end()) { - throw OSRMException("no nodes file found"); + throw osrm::exception("no nodes file found"); } if (server_paths.find("edgesdata") == server_paths.end()) { - throw OSRMException("no edges file found"); + throw osrm::exception("no edges file found"); } if (server_paths.find("namesdata") == server_paths.end()) { - throw OSRMException("no names file found"); + throw osrm::exception("no names file found"); } if (server_paths.find("geometry") == server_paths.end()) { - throw OSRMException("no geometry file found"); + throw osrm::exception("no geometry file found"); } ServerPaths::const_iterator paths_iterator = server_paths.find("hsgrdata"); @@ -339,8 +344,8 @@ int main(const int argc, const char *argv[]) geometry_input_stream.read((char *)&number_of_geometries_indices, sizeof(unsigned)); shared_layout_ptr->SetBlockSize(SharedDataLayout::GEOMETRIES_INDEX, number_of_geometries_indices); - boost::iostreams::seek( - geometry_input_stream, number_of_geometries_indices * sizeof(unsigned), BOOST_IOS::cur); + boost::iostreams::seek(geometry_input_stream, + number_of_geometries_indices * sizeof(unsigned), BOOST_IOS::cur); geometry_input_stream.read((char *)&number_of_compressed_geometries, sizeof(unsigned)); shared_layout_ptr->SetBlockSize(SharedDataLayout::GEOMETRIES_LIST, number_of_compressed_geometries); @@ -409,9 +414,8 @@ int main(const int argc, const char *argv[]) unsigned *name_id_ptr = shared_layout_ptr->GetBlockPtr( shared_memory_ptr, SharedDataLayout::NAME_ID_LIST); - TravelMode *travel_mode_ptr = - shared_layout_ptr->GetBlockPtr( - shared_memory_ptr, SharedDataLayout::TRAVEL_MODE); + TravelMode *travel_mode_ptr = shared_layout_ptr->GetBlockPtr( + shared_memory_ptr, SharedDataLayout::TRAVEL_MODE); TurnInstruction *turn_instructions_ptr = shared_layout_ptr->GetBlockPtr( @@ -481,10 +485,10 @@ int main(const int argc, const char *argv[]) shared_layout_ptr->GetBlockPtr( shared_memory_ptr, SharedDataLayout::COORDINATE_LIST); - NodeInfo current_node; + QueryNode current_node; for (unsigned i = 0; i < coordinate_list_size; ++i) { - nodes_input_stream.read((char *)¤t_node, sizeof(NodeInfo)); + nodes_input_stream.read((char *)¤t_node, sizeof(QueryNode)); coordinates_ptr[i] = FixedPointCoordinate(current_node.lat, current_node.lon); } nodes_input_stream.close(); diff --git a/3party/osrm/osrm-backend/descriptors/description_factory.cpp b/3party/osrm/osrm-backend/descriptors/description_factory.cpp new file mode 100755 index 0000000000..e4665622f0 --- /dev/null +++ b/3party/osrm/osrm-backend/descriptors/description_factory.cpp @@ -0,0 +1,244 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "description_factory.hpp" + +#include "../algorithms/polyline_formatter.hpp" +#include "../data_structures/coordinate_calculation.hpp" +#include "../data_structures/internal_route_result.hpp" +#include "../data_structures/turn_instructions.hpp" +#include "../util/container.hpp" +#include "../util/integer_range.hpp" +#include "../typedefs.h" + +DescriptionFactory::DescriptionFactory() : entire_length(0) { via_indices.push_back(0); } + +std::vector const &DescriptionFactory::GetViaIndices() const { return via_indices; } + +void DescriptionFactory::SetStartSegment(const PhantomNode &source, const bool traversed_in_reverse) +{ + start_phantom = source; + const EdgeWeight segment_duration = + (traversed_in_reverse ? source.reverse_weight : source.forward_weight); + const TravelMode travel_mode = + (traversed_in_reverse ? source.backward_travel_mode : source.forward_travel_mode); + AppendSegment(source.location, PathData(0, source.name_id, TurnInstruction::HeadOn, + segment_duration, travel_mode)); + BOOST_ASSERT(path_description.back().duration == segment_duration); +} + +void DescriptionFactory::SetEndSegment(const PhantomNode &target, + const bool traversed_in_reverse, + const bool is_via_location) +{ + target_phantom = target; + const EdgeWeight segment_duration = + (traversed_in_reverse ? target.reverse_weight : target.forward_weight); + const TravelMode travel_mode = + (traversed_in_reverse ? target.backward_travel_mode : target.forward_travel_mode); + path_description.emplace_back(target.location, target.name_id, segment_duration, 0.f, + is_via_location ? TurnInstruction::ReachViaLocation + : TurnInstruction::NoTurn, + true, true, travel_mode); + BOOST_ASSERT(path_description.back().duration == segment_duration); +} + +void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate, + const PathData &path_point) +{ + // if the start location is on top of a node, the first movement might be zero-length, + // in which case we dont' add a new description, but instead update the existing one + if ((1 == path_description.size()) && (path_description.front().location == coordinate)) + { + if (path_point.segment_duration > 0) + { + path_description.front().name_id = path_point.name_id; + path_description.front().travel_mode = path_point.travel_mode; + } + return; + } + + // make sure mode changes are announced, even when there otherwise is no turn + const TurnInstruction turn = [&]() -> TurnInstruction + { + if (TurnInstruction::NoTurn == path_point.turn_instruction && + path_description.front().travel_mode != path_point.travel_mode && + path_point.segment_duration > 0) + { + return TurnInstruction::GoStraight; + } + return path_point.turn_instruction; + }(); + + path_description.emplace_back(coordinate, path_point.name_id, path_point.segment_duration, 0.f, + turn, path_point.travel_mode); +} + +osrm::json::Value DescriptionFactory::AppendGeometryString(const bool return_encoded) +{ + if (return_encoded) + { + return PolylineFormatter().printEncodedString(path_description); + } + return PolylineFormatter().printUnencodedString(path_description); +} + +void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time) +{ + summary.source_name_id = start_phantom.name_id; + summary.target_name_id = target_phantom.name_id; + summary.BuildDurationAndLengthStrings(distance, time); +} + +void DescriptionFactory::Run(const unsigned zoom_level) +{ + if (path_description.empty()) + { + return; + } + + /** starts at index 1 */ + path_description[0].length = 0.f; + for (const auto i : osrm::irange(1, path_description.size())) + { + // move down names by one, q&d hack + path_description[i - 1].name_id = path_description[i].name_id; + path_description[i].length = coordinate_calculation::euclidean_distance( + path_description[i - 1].location, path_description[i].location); + } + + /*Simplify turn instructions + Input : + 10. Turn left on B 36 for 20 km + 11. Continue on B 35; B 36 for 2 km + 12. Continue on B 36 for 13 km + + becomes: + 10. Turn left on B 36 for 35 km + */ + // TODO: rework to check only end and start of string. + // stl string is way to expensive + + // unsigned lastTurn = 0; + // for(unsigned i = 1; i < path_description.size(); ++i) { + // string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id); + // if(TurnInstruction::GoStraight == path_description[i].turn_instruction) { + // if(std::string::npos != string0.find(string1+";") + // || std::string::npos != string0.find(";"+string1) + // || std::string::npos != string0.find(string1+" ;") + // || std::string::npos != string0.find("; "+string1) + // ){ + // SimpleLogger().Write() << "->next correct: " << string0 << " contains " << + // string1; + // for(; lastTurn != i; ++lastTurn) + // path_description[lastTurn].name_id = path_description[i].name_id; + // path_description[i].turn_instruction = TurnInstruction::NoTurn; + // } else if(std::string::npos != string1.find(string0+";") + // || std::string::npos != string1.find(";"+string0) + // || std::string::npos != string1.find(string0+" ;") + // || std::string::npos != string1.find("; "+string0) + // ){ + // SimpleLogger().Write() << "->prev correct: " << string1 << " contains " << + // string0; + // path_description[i].name_id = path_description[i-1].name_id; + // path_description[i].turn_instruction = TurnInstruction::NoTurn; + // } + // } + // if (TurnInstruction::NoTurn != path_description[i].turn_instruction) { + // lastTurn = i; + // } + // string0 = string1; + // } + + float segment_length = 0.; + EdgeWeight segment_duration = 0; + std::size_t segment_start_index = 0; + + for (const auto i : osrm::irange(1, path_description.size())) + { + entire_length += path_description[i].length; + segment_length += path_description[i].length; + segment_duration += path_description[i].duration; + path_description[segment_start_index].length = segment_length; + path_description[segment_start_index].duration = segment_duration; + + if (TurnInstruction::NoTurn != path_description[i].turn_instruction) + { + BOOST_ASSERT(path_description[i].necessary); + segment_length = 0; + segment_duration = 0; + segment_start_index = i; + } + } + + // Post-processing to remove empty or nearly empty path segments + if (path_description.size() > 2 && + std::numeric_limits::epsilon() > path_description.back().length) + { + path_description.pop_back(); + path_description.back().necessary = true; + path_description.back().turn_instruction = TurnInstruction::NoTurn; + target_phantom.name_id = (path_description.end() - 2)->name_id; + } + + if (path_description.size() > 2 && + std::numeric_limits::epsilon() > path_description.front().length) + { + path_description.erase(path_description.begin()); + path_description.front().turn_instruction = TurnInstruction::HeadOn; + path_description.front().necessary = true; + start_phantom.name_id = path_description.front().name_id; + } + + // Generalize poly line + polyline_generalizer.Run(path_description.begin(), path_description.end(), zoom_level); + + // fix what needs to be fixed else + unsigned necessary_segments = 0; // a running index that counts the necessary pieces + osrm::for_each_pair( + path_description, [&](SegmentInformation &first, const SegmentInformation &second) + { + if (!first.necessary) + { + return; + } + + ++necessary_segments; + + if (first.is_via_location) + { // mark the end of a leg (of several segments) + via_indices.push_back(necessary_segments); + } + + const double angle = coordinate_calculation::bearing(first.location, second.location); + first.bearing = static_cast(angle * 10); + }); + + via_indices.push_back(necessary_segments + 1); + BOOST_ASSERT(via_indices.size() >= 2); + return; +} diff --git a/3party/osrm/osrm-backend/descriptors/description_factory.hpp b/3party/osrm/osrm-backend/descriptors/description_factory.hpp new file mode 100755 index 0000000000..985f9c1c5d --- /dev/null +++ b/3party/osrm/osrm-backend/descriptors/description_factory.hpp @@ -0,0 +1,96 @@ +/* + +Copyright (c) 2015, 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 DESCRIPTION_FACTORY_HPP +#define DESCRIPTION_FACTORY_HPP + +#include "../algorithms/douglas_peucker.hpp" +#include "../data_structures/phantom_node.hpp" +#include "../data_structures/segment_information.hpp" +#include "../data_structures/turn_instructions.hpp" + +#include + +#include +#include + +#include + +#include +#include + +struct PathData; +/* This class is fed with all way segments in consecutive order + * and produces the description plus the encoded polyline */ + +class DescriptionFactory +{ + DouglasPeucker polyline_generalizer; + PhantomNode start_phantom, target_phantom; + + double DegreeToRadian(const double degree) const; + double RadianToDegree(const double degree) const; + + std::vector via_indices; + + double entire_length; + + public: + struct RouteSummary + { + unsigned distance; + EdgeWeight duration; + unsigned source_name_id; + unsigned target_name_id; + RouteSummary() : distance(0), duration(0), source_name_id(0), target_name_id(0) {} + + void BuildDurationAndLengthStrings(const double raw_distance, const unsigned raw_duration) + { + // compute distance/duration for route summary + distance = static_cast(std::round(raw_distance)); + duration = static_cast(std::round(raw_duration / 10.)); + } + } summary; + + // I know, declaring this public is considered bad. I'm lazy + std::vector path_description; + DescriptionFactory(); + void AppendSegment(const FixedPointCoordinate &coordinate, const PathData &data); + void BuildRouteSummary(const double distance, const unsigned time); + void SetStartSegment(const PhantomNode &start_phantom, const bool traversed_in_reverse); + void SetEndSegment(const PhantomNode &start_phantom, + const bool traversed_in_reverse, + const bool is_via_location = false); + osrm::json::Value AppendGeometryString(const bool return_encoded); + std::vector const &GetViaIndices() const; + + double get_entire_length() const { return entire_length; } + + void Run(const unsigned zoom_level); +}; + +#endif /* DESCRIPTION_FACTORY_HPP */ diff --git a/3party/osrm/osrm-backend/Descriptors/BaseDescriptor.h b/3party/osrm/osrm-backend/descriptors/descriptor_base.hpp old mode 100644 new mode 100755 similarity index 61% rename from 3party/osrm/osrm-backend/Descriptors/BaseDescriptor.h rename to 3party/osrm/osrm-backend/descriptors/descriptor_base.hpp index d06b9b6cb6..497c2161d5 --- a/3party/osrm/osrm-backend/Descriptors/BaseDescriptor.h +++ b/3party/osrm/osrm-backend/descriptors/descriptor_base.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,27 +25,53 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef BASE_DESCRIPTOR_H -#define BASE_DESCRIPTOR_H +#ifndef DESCRIPTOR_BASE_HPP +#define DESCRIPTOR_BASE_HPP -#include "../DataStructures/PhantomNodes.h" -#include "../DataStructures/RawRouteData.h" +#include "../data_structures/coordinate_calculation.hpp" +#include "../data_structures/internal_route_result.hpp" +#include "../data_structures/phantom_node.hpp" #include "../typedefs.h" -#include +#include + +#include #include +#include #include +struct DescriptorTable : public std::unordered_map +{ + unsigned get_id(const std::string &key) + { + auto iter = find(key); + if (iter != end()) + { + return iter->second; + } + return 0; + } +}; + struct DescriptorConfig { DescriptorConfig() : instructions(true), geometry(true), encode_geometry(true), zoom_level(18) { } + + template + DescriptorConfig(const OtherT &other) + : instructions(other.print_instructions), geometry(other.geometry), + encode_geometry(other.compression), zoom_level(other.zoom_level) + { + BOOST_ASSERT(zoom_level >= 0); + } + bool instructions; bool geometry; bool encode_geometry; - unsigned short zoom_level; + short zoom_level; }; template class BaseDescriptor @@ -54,8 +80,8 @@ template class BaseDescriptor BaseDescriptor() {} // Maybe someone can explain the pure virtual destructor thing to me (dennis) virtual ~BaseDescriptor() {} - virtual void Run(const RawRouteData &raw_route, http::Reply &reply) = 0; - virtual void SetConfig(const DescriptorConfig &config) = 0; + virtual void Run(const InternalRouteResult &raw_route, osrm::json::Object &json_result) = 0; + virtual void SetConfig(const DescriptorConfig &c) = 0; }; -#endif // BASE_DESCRIPTOR_H +#endif // DESCRIPTOR_BASE_HPP diff --git a/3party/osrm/osrm-backend/descriptors/gpx_descriptor.hpp b/3party/osrm/osrm-backend/descriptors/gpx_descriptor.hpp new file mode 100755 index 0000000000..fb4c5b9de9 --- /dev/null +++ b/3party/osrm/osrm-backend/descriptors/gpx_descriptor.hpp @@ -0,0 +1,94 @@ +/* + +Copyright (c) 2015, 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 GPX_DESCRIPTOR_HPP +#define GPX_DESCRIPTOR_HPP + +#include "descriptor_base.hpp" +#include "../util/xml_renderer.hpp" + +#include + +#include + +template class GPXDescriptor final : public BaseDescriptor +{ + private: + DescriptorConfig config; + DataFacadeT *facade; + + void AddRoutePoint(const FixedPointCoordinate &coordinate, osrm::json::Array &json_route) + { + osrm::json::Object json_lat; + osrm::json::Object json_lon; + osrm::json::Array json_row; + + std::string tmp; + + coordinate_calculation::lat_or_lon_to_string(coordinate.lat, tmp); + json_lat.values["_lat"] = tmp; + + coordinate_calculation::lat_or_lon_to_string(coordinate.lon, tmp); + json_lon.values["_lon"] = tmp; + + json_row.values.push_back(json_lat); + json_row.values.push_back(json_lon); + osrm::json::Object entry; + entry.values["rtept"] = json_row; + json_route.values.push_back(entry); + } + + public: + explicit GPXDescriptor(DataFacadeT *facade) : facade(facade) {} + + virtual void SetConfig(const DescriptorConfig &c) final { config = c; } + + virtual void Run(const InternalRouteResult &raw_route, osrm::json::Object &json_result) final + { + osrm::json::Array json_route; + if (raw_route.shortest_path_length != INVALID_EDGE_WEIGHT) + { + AddRoutePoint(raw_route.segment_end_coordinates.front().source_phantom.location, + json_route); + + for (const std::vector &path_data_vector : raw_route.unpacked_path_segments) + { + for (const PathData &path_data : path_data_vector) + { + const FixedPointCoordinate current_coordinate = + facade->GetCoordinateOfNode(path_data.node); + AddRoutePoint(current_coordinate, json_route); + } + } + AddRoutePoint(raw_route.segment_end_coordinates.back().target_phantom.location, + json_route); + } + // osrm::json::gpx_render(reply.content, json_route); + json_result.values["route"] = json_route; + } +}; +#endif // GPX_DESCRIPTOR_HPP diff --git a/3party/osrm/osrm-backend/Descriptors/JSONDescriptor.h b/3party/osrm/osrm-backend/descriptors/json_descriptor.hpp old mode 100644 new mode 100755 similarity index 75% rename from 3party/osrm/osrm-backend/Descriptors/JSONDescriptor.h rename to 3party/osrm/osrm-backend/descriptors/json_descriptor.hpp index 9e095c151e..13b68c6ecd --- a/3party/osrm/osrm-backend/Descriptors/JSONDescriptor.h +++ b/3party/osrm/osrm-backend/descriptors/json_descriptor.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,20 +25,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JSON_DESCRIPTOR_H_ -#define JSON_DESCRIPTOR_H_ +#ifndef JSON_DESCRIPTOR_HPP +#define JSON_DESCRIPTOR_HPP -#include "BaseDescriptor.h" -#include "DescriptionFactory.h" -#include "../Algorithms/ObjectToBase64.h" -#include "../Algorithms/ExtractRouteNames.h" -#include "../DataStructures/JSONContainer.h" -#include "../DataStructures/Range.h" -#include "../DataStructures/SegmentInformation.h" -#include "../DataStructures/TurnInstructions.h" -#include "../Util/Azimuth.h" -#include "../Util/StringUtil.h" -#include "../Util/TimingUtil.h" +#include "descriptor_base.hpp" +#include "description_factory.hpp" +#include "../algorithms/object_encoder.hpp" +#include "../algorithms/route_name_extraction.hpp" +#include "../data_structures/segment_information.hpp" +#include "../data_structures/turn_instructions.hpp" +#include "../util/bearing.hpp" +#include "../util/integer_range.hpp" +#include "../util/json_renderer.hpp" +#include "../util/simple_logger.hpp" +#include "../util/string_util.hpp" +#include "../util/timing_util.hpp" + +#include #include @@ -70,11 +73,13 @@ template class JSONDescriptor final : public BaseDescriptor< ExtractRouteNames GenerateRouteNames; public: - explicit JSONDescriptor(DataFacadeT *facade) : facade(facade), entered_restricted_area_count(0) {} + explicit JSONDescriptor(DataFacadeT *facade) : facade(facade), entered_restricted_area_count(0) + { + } - void SetConfig(const DescriptorConfig &c) final { config = c; } + virtual void SetConfig(const DescriptorConfig &c) override final { config = c; } - unsigned DescribeLeg(const std::vector route_leg, + unsigned DescribeLeg(const std::vector &route_leg, const PhantomNodes &leg_phantoms, const bool target_traversed_in_reverse, const bool is_via_leg) @@ -88,29 +93,26 @@ template class JSONDescriptor final : public BaseDescriptor< description_factory.AppendSegment(current_coordinate, path_data); ++added_element_count; } - description_factory.SetEndSegment( - leg_phantoms.target_phantom, target_traversed_in_reverse, is_via_leg); + description_factory.SetEndSegment(leg_phantoms.target_phantom, target_traversed_in_reverse, + is_via_leg); ++added_element_count; BOOST_ASSERT((route_leg.size() + 1) == added_element_count); return added_element_count; } - void Run(const RawRouteData &raw_route, http::Reply &reply) final + virtual void Run(const InternalRouteResult &raw_route, + osrm::json::Object &json_result) override final { - JSON::Object json_result; if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length) { // We do not need to do much, if there is no route ;-) json_result.values["status"] = 207; json_result.values["status_message"] = "Cannot find route between points"; - JSON::render(reply.content, json_result); + // osrm::json::render(reply.content, json_result); return; } // check if first segment is non-zero - std::string road_name = facade->GetEscapedNameForNameID( - raw_route.segment_end_coordinates.front().source_phantom.name_id); - BOOST_ASSERT(raw_route.unpacked_path_segments.size() == raw_route.segment_end_coordinates.size()); @@ -128,42 +130,39 @@ template class JSONDescriptor final : public BaseDescriptor< #endif DescribeLeg(raw_route.unpacked_path_segments[i], raw_route.segment_end_coordinates[i], - raw_route.target_traversed_in_reverse[i], - raw_route.is_via_leg(i)); + raw_route.target_traversed_in_reverse[i], raw_route.is_via_leg(i)); BOOST_ASSERT(0 < added_segments); } - description_factory.Run(facade, config.zoom_level); + description_factory.Run(config.zoom_level); if (config.geometry) { - JSON::Value route_geometry = + osrm::json::Value route_geometry = description_factory.AppendGeometryString(config.encode_geometry); json_result.values["route_geometry"] = route_geometry; } if (config.instructions) { - JSON::Array json_route_instructions; - BuildTextualDescription(description_factory, - json_route_instructions, - raw_route.shortest_path_length, - shortest_path_segments); + osrm::json::Array json_route_instructions; + BuildTextualDescription(description_factory, json_route_instructions, + raw_route.shortest_path_length, shortest_path_segments); json_result.values["route_instructions"] = json_route_instructions; } - description_factory.BuildRouteSummary(description_factory.entireLength, + description_factory.BuildRouteSummary(description_factory.get_entire_length(), raw_route.shortest_path_length); - JSON::Object json_route_summary; + osrm::json::Object json_route_summary; json_route_summary.values["total_distance"] = description_factory.summary.distance; json_route_summary.values["total_time"] = description_factory.summary.duration; json_route_summary.values["start_point"] = - facade->GetEscapedNameForNameID(description_factory.summary.source_name_id); + facade->get_name_for_id(description_factory.summary.source_name_id); json_route_summary.values["end_point"] = - facade->GetEscapedNameForNameID(description_factory.summary.target_name_id); + facade->get_name_for_id(description_factory.summary.target_name_id); json_result.values["route_summary"] = json_route_summary; BOOST_ASSERT(!raw_route.segment_end_coordinates.empty()); - JSON::Array json_via_points_array; - JSON::Array json_first_coordinate; + osrm::json::Array json_via_points_array; + osrm::json::Array json_first_coordinate; json_first_coordinate.values.push_back( raw_route.segment_end_coordinates.front().source_phantom.location.lat / COORDINATE_PRECISION); @@ -174,7 +173,7 @@ template class JSONDescriptor final : public BaseDescriptor< for (const PhantomNodes &nodes : raw_route.segment_end_coordinates) { std::string tmp; - JSON::Array json_coordinate; + osrm::json::Array json_coordinate; json_coordinate.values.push_back(nodes.target_phantom.location.lat / COORDINATE_PRECISION); json_coordinate.values.push_back(nodes.target_phantom.location.lon / @@ -183,7 +182,7 @@ template class JSONDescriptor final : public BaseDescriptor< } json_result.values["via_points"] = json_via_points_array; - JSON::Array json_via_indices_array; + osrm::json::Array json_via_indices_array; std::vector const &shortest_leg_end_indices = description_factory.GetViaIndices(); json_via_indices_array.values.insert(json_via_indices_array.values.end(), @@ -194,7 +193,7 @@ template class JSONDescriptor final : public BaseDescriptor< // only one alternative route is computed at this time, so this is hardcoded if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length) { - json_result.values["found_alternative"] = JSON::True(); + json_result.values["found_alternative"] = osrm::json::True(); BOOST_ASSERT(!raw_route.alt_source_traversed_in_reverse.empty()); alternate_description_factory.SetStartSegment( raw_route.segment_end_coordinates.front().source_phantom, @@ -208,47 +207,47 @@ template class JSONDescriptor final : public BaseDescriptor< alternate_description_factory.SetEndSegment( raw_route.segment_end_coordinates.back().target_phantom, raw_route.alt_source_traversed_in_reverse.back()); - alternate_description_factory.Run(facade, config.zoom_level); + alternate_description_factory.Run(config.zoom_level); if (config.geometry) { - JSON::Value alternate_geometry_string = + osrm::json::Value alternate_geometry_string = alternate_description_factory.AppendGeometryString(config.encode_geometry); - JSON::Array json_alternate_geometries_array; + osrm::json::Array json_alternate_geometries_array; json_alternate_geometries_array.values.push_back(alternate_geometry_string); json_result.values["alternative_geometries"] = json_alternate_geometries_array; } // Generate instructions for each alternative (simulated here) - JSON::Array json_alt_instructions; - JSON::Array json_current_alt_instructions; + osrm::json::Array json_alt_instructions; + osrm::json::Array json_current_alt_instructions; if (config.instructions) { - BuildTextualDescription(alternate_description_factory, - json_current_alt_instructions, - raw_route.alternative_path_length, - alternative_path_segments); + BuildTextualDescription( + alternate_description_factory, json_current_alt_instructions, + raw_route.alternative_path_length, alternative_path_segments); json_alt_instructions.values.push_back(json_current_alt_instructions); json_result.values["alternative_instructions"] = json_alt_instructions; } alternate_description_factory.BuildRouteSummary( - alternate_description_factory.entireLength, raw_route.alternative_path_length); + alternate_description_factory.get_entire_length(), + raw_route.alternative_path_length); - JSON::Object json_alternate_route_summary; - JSON::Array json_alternate_route_summary_array; + osrm::json::Object json_alternate_route_summary; + osrm::json::Array json_alternate_route_summary_array; json_alternate_route_summary.values["total_distance"] = alternate_description_factory.summary.distance; json_alternate_route_summary.values["total_time"] = alternate_description_factory.summary.duration; - json_alternate_route_summary.values["start_point"] = facade->GetEscapedNameForNameID( - alternate_description_factory.summary.source_name_id); - json_alternate_route_summary.values["end_point"] = facade->GetEscapedNameForNameID( - alternate_description_factory.summary.target_name_id); + json_alternate_route_summary.values["start_point"] = + facade->get_name_for_id(alternate_description_factory.summary.source_name_id); + json_alternate_route_summary.values["end_point"] = + facade->get_name_for_id(alternate_description_factory.summary.target_name_id); json_alternate_route_summary_array.values.push_back(json_alternate_route_summary); json_result.values["alternative_summaries"] = json_alternate_route_summary_array; std::vector const &alternate_leg_end_indices = alternate_description_factory.GetViaIndices(); - JSON::Array json_altenative_indices_array; + osrm::json::Array json_altenative_indices_array; json_altenative_indices_array.values.insert(json_altenative_indices_array.values.end(), alternate_leg_end_indices.begin(), alternate_leg_end_indices.end()); @@ -256,51 +255,53 @@ template class JSONDescriptor final : public BaseDescriptor< } else { - json_result.values["found_alternative"] = JSON::False(); + json_result.values["found_alternative"] = osrm::json::False(); } // Get Names for both routes RouteNames route_names = GenerateRouteNames(shortest_path_segments, alternative_path_segments, facade); - JSON::Array json_route_names; + osrm::json::Array json_route_names; json_route_names.values.push_back(route_names.shortest_path_name_1); json_route_names.values.push_back(route_names.shortest_path_name_2); json_result.values["route_name"] = json_route_names; if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length) { - JSON::Array json_alternate_names_array; - JSON::Array json_alternate_names; + osrm::json::Array json_alternate_names_array; + osrm::json::Array json_alternate_names; json_alternate_names.values.push_back(route_names.alternative_path_name_1); json_alternate_names.values.push_back(route_names.alternative_path_name_2); json_alternate_names_array.values.push_back(json_alternate_names); json_result.values["alternative_names"] = json_alternate_names_array; } - JSON::Object json_hint_object; - json_hint_object.values["checksum"] = raw_route.check_sum; - JSON::Array json_location_hint_array; + osrm::json::Object json_hint_object; + json_hint_object.values["checksum"] = facade->GetCheckSum(); + osrm::json::Array json_location_hint_array; std::string hint; for (const auto i : osrm::irange(0, raw_route.segment_end_coordinates.size())) { - ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates[i].source_phantom, hint); + ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates[i].source_phantom, + hint); json_location_hint_array.values.push_back(hint); } - ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates.back().target_phantom, hint); + ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates.back().target_phantom, + hint); json_location_hint_array.values.push_back(hint); json_hint_object.values["locations"] = json_location_hint_array; json_result.values["hint_data"] = json_hint_object; // render the content to the output array - TIMER_START(route_render); - JSON::render(reply.content, json_result); - TIMER_STOP(route_render); - SimpleLogger().Write(logDEBUG) << "rendering took: " << TIMER_MSEC(route_render); + // TIMER_START(route_render); + // osrm::json::render(reply.content, json_result); + // TIMER_STOP(route_render); + // SimpleLogger().Write(logDEBUG) << "rendering took: " << TIMER_MSEC(route_render); } // TODO: reorder parameters inline void BuildTextualDescription(DescriptionFactory &description_factory, - JSON::Array &json_instruction_array, + osrm::json::Array &json_instruction_array, const int route_length, std::vector &route_segments_list) { @@ -314,7 +315,7 @@ template class JSONDescriptor final : public BaseDescriptor< // Fetch data from Factory and generate a string from it. for (const SegmentInformation &segment : description_factory.path_description) { - JSON::Array json_instruction_row; + osrm::json::Array json_instruction_row; TurnInstruction current_instruction = segment.turn_instruction; entered_restricted_area_count += (current_instruction != segment.turn_instruction); if (TurnInstructionsClass::TurnIsNecessary(current_instruction)) @@ -329,8 +330,8 @@ template class JSONDescriptor final : public BaseDescriptor< std::string current_turn_instruction; if (TurnInstruction::LeaveRoundAbout == current_instruction) { - temp_instruction = - cast::integral_to_string(cast::enum_to_underlying(TurnInstruction::EnterRoundAbout)); + temp_instruction = cast::integral_to_string( + cast::enum_to_underlying(TurnInstruction::EnterRoundAbout)); current_turn_instruction += temp_instruction; current_turn_instruction += "-"; temp_instruction = cast::integral_to_string(round_about.leave_at_exit + 1); @@ -339,27 +340,26 @@ template class JSONDescriptor final : public BaseDescriptor< } else { - temp_instruction = cast::integral_to_string(cast::enum_to_underlying(current_instruction)); + temp_instruction = + cast::integral_to_string(cast::enum_to_underlying(current_instruction)); current_turn_instruction += temp_instruction; } json_instruction_row.values.push_back(current_turn_instruction); - json_instruction_row.values.push_back( - facade->GetEscapedNameForNameID(segment.name_id)); + json_instruction_row.values.push_back(facade->get_name_for_id(segment.name_id)); json_instruction_row.values.push_back(std::round(segment.length)); json_instruction_row.values.push_back(necessary_segments_running_index); - json_instruction_row.values.push_back(round(segment.duration / 10)); + json_instruction_row.values.push_back(std::round(segment.duration / 10.)); json_instruction_row.values.push_back( cast::integral_to_string(static_cast(segment.length)) + "m"); const double bearing_value = (segment.bearing / 10.); - json_instruction_row.values.push_back(Azimuth::Get(bearing_value)); + json_instruction_row.values.push_back(bearing::get(bearing_value)); json_instruction_row.values.push_back( static_cast(round(bearing_value))); json_instruction_row.values.push_back(segment.travel_mode); route_segments_list.emplace_back( - segment.name_id, - static_cast(segment.length), + segment.name_id, static_cast(segment.length), static_cast(route_segments_list.size())); json_instruction_array.values.push_back(json_instruction_row); } @@ -374,15 +374,16 @@ template class JSONDescriptor final : public BaseDescriptor< } } - JSON::Array json_last_instruction_row; - temp_instruction = cast::integral_to_string(cast::enum_to_underlying(TurnInstruction::ReachedYourDestination)); + osrm::json::Array json_last_instruction_row; + temp_instruction = cast::integral_to_string( + cast::enum_to_underlying(TurnInstruction::ReachedYourDestination)); json_last_instruction_row.values.push_back(temp_instruction); json_last_instruction_row.values.push_back(""); json_last_instruction_row.values.push_back(0); json_last_instruction_row.values.push_back(necessary_segments_running_index - 1); json_last_instruction_row.values.push_back(0); json_last_instruction_row.values.push_back("0m"); - json_last_instruction_row.values.push_back(Azimuth::Get(0.0)); + json_last_instruction_row.values.push_back(bearing::get(0.0)); json_last_instruction_row.values.push_back(0.); json_instruction_array.values.push_back(json_last_instruction_row); } diff --git a/3party/osrm/osrm-backend/extract.cpp b/3party/osrm/osrm-backend/extract.cpp new file mode 100755 index 0000000000..a147629834 --- /dev/null +++ b/3party/osrm/osrm-backend/extract.cpp @@ -0,0 +1,83 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "extractor/extractor.hpp" +#include "extractor/extractor_options.hpp" +#include "util/simple_logger.hpp" + +#include + +#include + +int main(int argc, char *argv[]) +{ + try + { + LogPolicy::GetInstance().Unmute(); + ExtractorConfig extractor_config; + + const return_code result = ExtractorOptions::ParseArguments(argc, argv, extractor_config); + + if (return_code::fail == result) + { + return 1; + } + + if (return_code::exit == result) + { + return 0; + } + + ExtractorOptions::GenerateOutputFilesNames(extractor_config); + + if (1 > extractor_config.requested_num_threads) + { + SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger"; + return 1; + } + + if (!boost::filesystem::is_regular_file(extractor_config.input_path)) + { + SimpleLogger().Write(logWARNING) + << "Input file " << extractor_config.input_path.string() << " not found!"; + return 1; + } + + if (!boost::filesystem::is_regular_file(extractor_config.profile_path)) + { + SimpleLogger().Write(logWARNING) << "Profile " << extractor_config.profile_path.string() + << " not found!"; + return 1; + } + return extractor().run(extractor_config); + } + catch (const std::exception &e) + { + SimpleLogger().Write(logWARNING) << "[exception] " << e.what(); + return 1; + } +} diff --git a/3party/osrm/osrm-backend/Extractor/ExtractionContainers.cpp b/3party/osrm/osrm-backend/extractor/extraction_containers.cpp old mode 100644 new mode 100755 similarity index 70% rename from 3party/osrm/osrm-backend/Extractor/ExtractionContainers.cpp rename to 3party/osrm/osrm-backend/extractor/extraction_containers.cpp index eb45efee3f..8c484eb814 --- a/3party/osrm/osrm-backend/Extractor/ExtractionContainers.cpp +++ b/3party/osrm/osrm-backend/extractor/extraction_containers.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,12 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "ExtractionContainers.h" -#include "ExtractionWay.h" -#include "../Util/OSRMException.h" -#include "../Util/simple_logger.hpp" -#include "../Util/TimingUtil.h" -#include "../DataStructures/RangeTable.h" +#include "extraction_containers.hpp" +#include "extraction_way.hpp" + +#include "../data_structures/coordinate_calculation.hpp" +#include "../data_structures/node_id.hpp" +#include "../data_structures/range_table.hpp" + +#include "../util/osrm_exception.hpp" +#include "../util/simple_logger.hpp" +#include "../util/timing_util.hpp" #include #include @@ -79,71 +83,61 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name, TIMER_STOP(erasing_dups); std::cout << "ok, after " << TIMER_SEC(erasing_dups) << "s" << std::endl; - std::cout << "[extractor] Sorting all nodes ... " << std::flush; TIMER_START(sorting_nodes); - stxxl::sort(all_nodes_list.begin(), all_nodes_list.end(), CmpNodeByID(), stxxl_memory); + stxxl::sort(all_nodes_list.begin(), all_nodes_list.end(), ExternalMemoryNodeSTXXLCompare(), + stxxl_memory); TIMER_STOP(sorting_nodes); std::cout << "ok, after " << TIMER_SEC(sorting_nodes) << "s" << std::endl; - std::cout << "[extractor] Sorting used ways ... " << std::flush; TIMER_START(sort_ways); - stxxl::sort( - way_start_end_id_list.begin(), way_start_end_id_list.end(), CmpWayByID(), stxxl_memory); + stxxl::sort(way_start_end_id_list.begin(), way_start_end_id_list.end(), + FirstAndLastSegmentOfWayStxxlCompare(), stxxl_memory); TIMER_STOP(sort_ways); std::cout << "ok, after " << TIMER_SEC(sort_ways) << "s" << std::endl; - std::cout << "[extractor] Sorting restrictions. by from... " << std::flush; + std::cout << "[extractor] Sorting " << restrictions_list.size() + << " restrictions. by from... " << std::flush; TIMER_START(sort_restrictions); - stxxl::sort(restrictions_list.begin(), - restrictions_list.end(), - CmpRestrictionContainerByFrom(), - stxxl_memory); + stxxl::sort(restrictions_list.begin(), restrictions_list.end(), + CmpRestrictionContainerByFrom(), stxxl_memory); TIMER_STOP(sort_restrictions); std::cout << "ok, after " << TIMER_SEC(sort_restrictions) << "s" << std::endl; std::cout << "[extractor] Fixing restriction starts ... " << std::flush; TIMER_START(fix_restriction_starts); auto restrictions_iterator = restrictions_list.begin(); - auto way_start_and_end_iterator = way_start_end_id_list.begin(); + auto way_start_and_end_iterator = way_start_end_id_list.cbegin(); - while (way_start_and_end_iterator != way_start_end_id_list.end() && + while (way_start_and_end_iterator != way_start_end_id_list.cend() && restrictions_iterator != restrictions_list.end()) { - if (way_start_and_end_iterator->wayID < restrictions_iterator->fromWay) + if (way_start_and_end_iterator->way_id < restrictions_iterator->restriction.from.way) { ++way_start_and_end_iterator; continue; } - if (way_start_and_end_iterator->wayID > restrictions_iterator->fromWay) + if (way_start_and_end_iterator->way_id > restrictions_iterator->restriction.from.way) { ++restrictions_iterator; continue; } - BOOST_ASSERT(way_start_and_end_iterator->wayID == restrictions_iterator->fromWay); - const NodeID via_node_id = restrictions_iterator->restriction.viaNode; + BOOST_ASSERT(way_start_and_end_iterator->way_id == + restrictions_iterator->restriction.from.way); + const NodeID via_node_id = restrictions_iterator->restriction.via.node; - if (way_start_and_end_iterator->firstStart == via_node_id) + if (way_start_and_end_iterator->first_segment_source_id == via_node_id) { - restrictions_iterator->restriction.fromNode = - way_start_and_end_iterator->firstTarget; + restrictions_iterator->restriction.from.node = + way_start_and_end_iterator->first_segment_target_id; } - else if (way_start_and_end_iterator->firstTarget == via_node_id) + else if (way_start_and_end_iterator->last_segment_target_id == via_node_id) { - restrictions_iterator->restriction.fromNode = - way_start_and_end_iterator->firstStart; - } - else if (way_start_and_end_iterator->lastStart == via_node_id) - { - restrictions_iterator->restriction.fromNode = - way_start_and_end_iterator->lastTarget; - } - else if (way_start_and_end_iterator->lastTarget == via_node_id) - { - restrictions_iterator->restriction.fromNode = way_start_and_end_iterator->lastStart; + restrictions_iterator->restriction.from.node = + way_start_and_end_iterator->last_segment_source_id; } ++restrictions_iterator; } @@ -153,76 +147,70 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name, std::cout << "[extractor] Sorting restrictions. by to ... " << std::flush; TIMER_START(sort_restrictions_to); - stxxl::sort(restrictions_list.begin(), - restrictions_list.end(), - CmpRestrictionContainerByTo(), - stxxl_memory); + stxxl::sort(restrictions_list.begin(), restrictions_list.end(), + CmpRestrictionContainerByTo(), stxxl_memory); TIMER_STOP(sort_restrictions_to); std::cout << "ok, after " << TIMER_SEC(sort_restrictions_to) << "s" << std::endl; - unsigned number_of_useable_restrictions = 0; std::cout << "[extractor] Fixing restriction ends ... " << std::flush; TIMER_START(fix_restriction_ends); restrictions_iterator = restrictions_list.begin(); - way_start_and_end_iterator = way_start_end_id_list.begin(); - while (way_start_and_end_iterator != way_start_end_id_list.end() && + way_start_and_end_iterator = way_start_end_id_list.cbegin(); + while (way_start_and_end_iterator != way_start_end_id_list.cend() && restrictions_iterator != restrictions_list.end()) { - if (way_start_and_end_iterator->wayID < restrictions_iterator->toWay) + if (way_start_and_end_iterator->way_id < restrictions_iterator->restriction.to.way) { ++way_start_and_end_iterator; continue; } - if (way_start_and_end_iterator->wayID > restrictions_iterator->toWay) + if (way_start_and_end_iterator->way_id > restrictions_iterator->restriction.to.way) { ++restrictions_iterator; continue; } - NodeID via_node_id = restrictions_iterator->restriction.viaNode; - if (way_start_and_end_iterator->lastStart == via_node_id) - { - restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastTarget; - } - else if (way_start_and_end_iterator->lastTarget == via_node_id) - { - restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastStart; - } - else if (way_start_and_end_iterator->firstStart == via_node_id) - { - restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstTarget; - } - else if (way_start_and_end_iterator->firstTarget == via_node_id) - { - restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstStart; - } + BOOST_ASSERT(way_start_and_end_iterator->way_id == + restrictions_iterator->restriction.to.way); + const NodeID via_node_id = restrictions_iterator->restriction.via.node; - if (std::numeric_limits::max() != restrictions_iterator->restriction.fromNode && - std::numeric_limits::max() != restrictions_iterator->restriction.toNode) + if (way_start_and_end_iterator->first_segment_source_id == via_node_id) { - ++number_of_useable_restrictions; + restrictions_iterator->restriction.to.node = + way_start_and_end_iterator->first_segment_target_id; + } + else if (way_start_and_end_iterator->last_segment_target_id == via_node_id) + { + restrictions_iterator->restriction.to.node = + way_start_and_end_iterator->last_segment_source_id; } ++restrictions_iterator; } TIMER_STOP(fix_restriction_ends); std::cout << "ok, after " << TIMER_SEC(fix_restriction_ends) << "s" << std::endl; - SimpleLogger().Write() << "usable restrictions: " << number_of_useable_restrictions; // serialize restrictions std::ofstream restrictions_out_stream; + unsigned written_restriction_count = 0; restrictions_out_stream.open(restrictions_file_name.c_str(), std::ios::binary); restrictions_out_stream.write((char *)&fingerprint, sizeof(FingerPrint)); - restrictions_out_stream.write((char *)&number_of_useable_restrictions, sizeof(unsigned)); + const auto count_position = restrictions_out_stream.tellp(); + restrictions_out_stream.write((char *)&written_restriction_count, sizeof(unsigned)); - for(const auto & restriction_container : restrictions_list) + for (const auto &restriction_container : restrictions_list) { - if (std::numeric_limits::max() != restriction_container.restriction.fromNode && - std::numeric_limits::max() != restriction_container.restriction.toNode) + if (SPECIAL_NODEID != restriction_container.restriction.from.node && + SPECIAL_NODEID != restriction_container.restriction.to.node) { restrictions_out_stream.write((char *)&(restriction_container.restriction), sizeof(TurnRestriction)); + ++written_restriction_count; } } + restrictions_out_stream.seekp(count_position); + restrictions_out_stream.write((char *)&written_restriction_count, sizeof(unsigned)); + restrictions_out_stream.close(); + SimpleLogger().Write() << "usable restrictions: " << written_restriction_count; std::ofstream file_out_stream; file_out_stream.open(output_file_name.c_str(), std::ios::binary); @@ -272,7 +260,6 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name, TIMER_STOP(sort_edges_by_start); std::cout << "ok, after " << TIMER_SEC(sort_edges_by_start) << "s" << std::endl; - std::cout << "[extractor] Setting start coords ... " << std::flush; TIMER_START(set_start_coords); file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned)); @@ -303,7 +290,8 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name, // Sort Edges by target std::cout << "[extractor] Sorting edges by target ... " << std::flush; TIMER_START(sort_edges_by_target); - stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByTargetID(), stxxl_memory); + stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByTargetID(), + stxxl_memory); TIMER_STOP(sort_edges_by_target); std::cout << "ok, after " << TIMER_SEC(sort_edges_by_target) << "s" << std::endl; @@ -333,22 +321,20 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name, edge_iterator->target_coordinate.lat = node_iterator->lat; edge_iterator->target_coordinate.lon = node_iterator->lon; - const double distance = FixedPointCoordinate::ApproximateEuclideanDistance( - edge_iterator->source_coordinate.lat, - edge_iterator->source_coordinate.lon, - node_iterator->lat, - node_iterator->lon); + const double distance = coordinate_calculation::euclidean_distance( + edge_iterator->source_coordinate.lat, edge_iterator->source_coordinate.lon, + node_iterator->lat, node_iterator->lon); const double weight = (distance * 10.) / (edge_iterator->speed / 3.6); int integer_weight = std::max( - 1, - (int)std::floor( - (edge_iterator->is_duration_set ? edge_iterator->speed : weight) + .5)); - int integer_distance = std::max(1, (int)distance); - short zero = 0; - short one = 1; + 1, (int)std::floor( + (edge_iterator->is_duration_set ? edge_iterator->speed : weight) + .5)); + const int integer_distance = std::max(1, (int)distance); + const short zero = 0; + const short one = 1; + const bool yes = true; + const bool no = false; - 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)); @@ -367,20 +353,48 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name, file_out_stream.write((char *)&one, sizeof(short)); break; default: - throw OSRMException("edge has broken direction"); + throw osrm::exception("edge has broken direction"); } file_out_stream.write((char *)&integer_weight, sizeof(int)); file_out_stream.write((char *)&edge_iterator->name_id, sizeof(unsigned)); - file_out_stream.write((char *)&edge_iterator->is_roundabout, sizeof(bool)); - file_out_stream.write((char *)&edge_iterator->is_in_tiny_cc, sizeof(bool)); - file_out_stream.write((char *)&edge_iterator->is_access_restricted, sizeof(bool)); + if (edge_iterator->is_roundabout) + { + file_out_stream.write((char *)&yes, sizeof(bool)); + } + else + { + file_out_stream.write((char *)&no, sizeof(bool)); + } + if (edge_iterator->is_in_tiny_cc) + { + file_out_stream.write((char *)&yes, sizeof(bool)); + } + else + { + file_out_stream.write((char *)&no, sizeof(bool)); + } + if (edge_iterator->is_access_restricted) + { + file_out_stream.write((char *)&yes, sizeof(bool)); + } + else + { + file_out_stream.write((char *)&no, sizeof(bool)); + } // cannot take adress of bit field, so use local - const TravelMode travel_mode = edge_iterator->travel_mode; + const TravelMode travel_mode = edge_iterator->travel_mode; file_out_stream.write((char *)&travel_mode, sizeof(TravelMode)); - file_out_stream.write((char *)&edge_iterator->is_split, sizeof(bool)); + if (edge_iterator->is_split) + { + file_out_stream.write((char *)&yes, sizeof(bool)); + } + else + { + file_out_stream.write((char *)&no, sizeof(bool)); + } ++number_of_used_edges; } ++edge_iterator; @@ -404,7 +418,8 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name, std::vector name_lengths; for (const std::string &temp_string : name_list) { - const unsigned string_length = std::min(static_cast(temp_string.length()), 255u); + const unsigned string_length = + std::min(static_cast(temp_string.length()), 255u); name_lengths.push_back(string_length); total_length += string_length; } @@ -412,11 +427,12 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name, RangeTable<> table(name_lengths); name_file_stream << table; - name_file_stream.write((char*) &total_length, sizeof(unsigned)); + name_file_stream.write((char *)&total_length, sizeof(unsigned)); // write all chars consecutively for (const std::string &temp_string : name_list) { - const unsigned string_length = std::min(static_cast(temp_string.length()), 255u); + const unsigned string_length = + std::min(static_cast(temp_string.length()), 255u); name_file_stream.write(temp_string.c_str(), string_length); } @@ -427,5 +443,8 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name, SimpleLogger().Write() << "Processed " << number_of_used_nodes << " nodes and " << number_of_used_edges << " edges"; } - catch (const std::exception &e) { std::cerr << "Caught Execption:" << e.what() << std::endl; } + catch (const std::exception &e) + { + std::cerr << "Caught Execption:" << e.what() << std::endl; + } } diff --git a/3party/osrm/osrm-backend/Extractor/ExtractionContainers.h b/3party/osrm/osrm-backend/extractor/extraction_containers.hpp old mode 100644 new mode 100755 similarity index 66% rename from 3party/osrm/osrm-backend/Extractor/ExtractionContainers.h rename to 3party/osrm/osrm-backend/extractor/extraction_containers.hpp index bfb318ba7a..12d88a26c8 --- a/3party/osrm/osrm-backend/Extractor/ExtractionContainers.h +++ b/3party/osrm/osrm-backend/extractor/extraction_containers.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,30 +25,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef EXTRACTIONCONTAINERS_H_ -#define EXTRACTIONCONTAINERS_H_ +#ifndef EXTRACTION_CONTAINERS_HPP +#define EXTRACTION_CONTAINERS_HPP -#include "InternalExtractorEdge.h" -#include "ExtractorStructs.h" -#include "../DataStructures/Restriction.h" -#include "../Util/FingerPrint.h" +#include "internal_extractor_edge.hpp" +#include "first_and_last_segment_of_way.hpp" +#include "../data_structures/external_memory_node.hpp" +#include "../data_structures/restriction.hpp" +#include "../util/fingerprint.hpp" #include class ExtractionContainers { #ifndef _MSC_VER - constexpr static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? std::numeric_limits::max() : std::numeric_limits::max()); + constexpr static unsigned stxxl_memory = + ((sizeof(std::size_t) == 4) ? std::numeric_limits::max() + : std::numeric_limits::max()); #else const static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? INT_MAX : UINT_MAX); #endif public: - using STXXLNodeIDVector = stxxl::vector; - using STXXLNodeVector = stxxl::vector; - using STXXLEdgeVector = stxxl::vector; - using STXXLStringVector = stxxl::vector; - using STXXLRestrictionsVector = stxxl::vector; - using STXXLWayIDStartEndVector = stxxl::vector; + using STXXLNodeIDVector = stxxl::vector; + using STXXLNodeVector = stxxl::vector; + using STXXLEdgeVector = stxxl::vector; + using STXXLStringVector = stxxl::vector; + using STXXLRestrictionsVector = stxxl::vector; + using STXXLWayIDStartEndVector = stxxl::vector; STXXLNodeIDVector used_node_id_list; STXXLNodeVector all_nodes_list; @@ -66,4 +69,4 @@ class ExtractionContainers const std::string &restrictions_file_name); }; -#endif /* EXTRACTIONCONTAINERS_H_ */ +#endif /* EXTRACTION_CONTAINERS_HPP */ diff --git a/3party/osrm/osrm-backend/extractor/extraction_helper_functions.hpp b/3party/osrm/osrm-backend/extractor/extraction_helper_functions.hpp new file mode 100755 index 0000000000..d10200abbe --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/extraction_helper_functions.hpp @@ -0,0 +1,119 @@ +/* + +Copyright (c) 2015, 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 EXTRACTION_HELPER_FUNCTIONS_HPP +#define EXTRACTION_HELPER_FUNCTIONS_HPP + +#include "../util/cast.hpp" +#include "../util/iso_8601_duration_parser.hpp" + +#include +#include +#include +#include + +#include + +bool simple_duration_is_valid(const std::string &s) +{ + boost::regex simple_format( + "((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)", + boost::regex_constants::icase | boost::regex_constants::perl); + + const bool simple_matched = regex_match(s, simple_format); + + if (simple_matched) + { + return true; + } + return false; +} + +bool iso_8601_duration_is_valid(const std::string &s) +{ + iso_8601_grammar iso_parser; + const bool result = qi::parse(s.begin(), s.end(), iso_parser); + + // check if the was an error with the request + if (result && (0 != iso_parser.get_duration())) + { + return true; + } + return false; +} + +bool durationIsValid(const std::string &s) +{ + return simple_duration_is_valid(s) || iso_8601_duration_is_valid(s); +} + +unsigned parseDuration(const std::string &s) +{ + if (simple_duration_is_valid(s)) + { + unsigned hours = 0; + unsigned minutes = 0; + unsigned seconds = 0; + boost::regex e( + "((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)", + boost::regex_constants::icase | boost::regex_constants::perl); + + std::vector result; + boost::algorithm::split_regex(result, s, boost::regex(":")); + const bool matched = regex_match(s, e); + if (matched) + { + if (1 == result.size()) + { + minutes = cast::string_to_int(result[0]); + } + if (2 == result.size()) + { + minutes = cast::string_to_int(result[1]); + hours = cast::string_to_int(result[0]); + } + if (3 == result.size()) + { + seconds = cast::string_to_int(result[2]); + minutes = cast::string_to_int(result[1]); + hours = cast::string_to_int(result[0]); + } + return 10 * (3600 * hours + 60 * minutes + seconds); + } + } + else if (iso_8601_duration_is_valid(s)) + { + iso_8601_grammar iso_parser; + qi::parse(s.begin(), s.end(), iso_parser); + + return iso_parser.get_duration(); + } + + return std::numeric_limits::max(); +} + +#endif // EXTRACTION_HELPER_FUNCTIONS_HPP diff --git a/3party/osrm/osrm-backend/extractor/extraction_node.hpp b/3party/osrm/osrm-backend/extractor/extraction_node.hpp new file mode 100755 index 0000000000..e821d6ffa1 --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/extraction_node.hpp @@ -0,0 +1,38 @@ +/* + +Copyright (c) 2014, 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 EXTRACTION_NODE_HPP +#define EXTRACTION_NODE_HPP + +struct ExtractionNode +{ + ExtractionNode() : traffic_lights(false), barrier(false) {} + void clear() { traffic_lights = barrier = false; } + bool traffic_lights; + bool barrier; +}; +#endif // EXTRACTION_NODE_HPP diff --git a/3party/osrm/osrm-backend/Extractor/ExtractionWay.h b/3party/osrm/osrm-backend/extractor/extraction_way.hpp old mode 100644 new mode 100755 similarity index 66% rename from 3party/osrm/osrm-backend/Extractor/ExtractionWay.h rename to 3party/osrm/osrm-backend/extractor/extraction_way.hpp index 1a197b6599..d47de20b08 --- a/3party/osrm/osrm-backend/Extractor/ExtractionWay.h +++ b/3party/osrm/osrm-backend/extractor/extraction_way.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,11 +25,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef EXTRACTION_WAY_H -#define EXTRACTION_WAY_H +#ifndef EXTRACTION_WAY_HPP +#define EXTRACTION_WAY_HPP -#include "../DataStructures/HashTable.h" -#include "../DataStructures/TravelMode.h" +#include "../data_structures/travel_mode.hpp" #include "../typedefs.h" #include @@ -37,35 +36,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct ExtractionWay { - ExtractionWay() { Clear(); } + ExtractionWay() { clear(); } - inline void Clear() + void clear() { - id = SPECIAL_NODEID; - nameID = INVALID_NAMEID; - path.clear(); - keyVals.Clear(); forward_speed = -1; backward_speed = -1; duration = -1; - access = true; roundabout = false; - isAccessRestricted = false; - ignoreInGrid = false; + is_access_restricted = false; + ignore_in_grid = false; + name.clear(); forward_travel_mode = TRAVEL_MODE_DEFAULT; backward_travel_mode = TRAVEL_MODE_DEFAULT; } enum Directions - { notSure = 0, - oneway, - bidirectional, - opposite }; + { + notSure = 0, + oneway, + bidirectional, + opposite + }; // These accessor methods exists to support the depreciated "way.direction" access // in LUA. Since the direction attribute was removed from ExtractionWay, the // accessors translate to/from the mode attributes. - inline void set_direction(const Directions m) + void set_direction(const Directions m) { if (Directions::oneway == m) { @@ -74,19 +71,20 @@ struct ExtractionWay } else if (Directions::opposite == m) { - forward_travel_mode = TRAVEL_MODE_INACCESSIBLE; - backward_travel_mode = TRAVEL_MODE_DEFAULT; + forward_travel_mode = TRAVEL_MODE_INACCESSIBLE; + backward_travel_mode = TRAVEL_MODE_DEFAULT; } else if (Directions::bidirectional == m) { - forward_travel_mode = TRAVEL_MODE_DEFAULT; - backward_travel_mode = TRAVEL_MODE_DEFAULT; + forward_travel_mode = TRAVEL_MODE_DEFAULT; + backward_travel_mode = TRAVEL_MODE_DEFAULT; } } - inline const Directions get_direction() const + Directions get_direction() const { - if (TRAVEL_MODE_INACCESSIBLE != forward_travel_mode && TRAVEL_MODE_INACCESSIBLE != backward_travel_mode) + if (TRAVEL_MODE_INACCESSIBLE != forward_travel_mode && + TRAVEL_MODE_INACCESSIBLE != backward_travel_mode) { return Directions::bidirectional; } @@ -106,25 +104,20 @@ struct ExtractionWay // These accessors exists because it's not possible to take the address of a bitfield, // and LUA therefore cannot read/write the mode attributes directly. - inline void set_forward_mode(const TravelMode m) { forward_travel_mode = m; } - inline const TravelMode get_forward_mode() const { return forward_travel_mode; } - inline void set_backward_mode(const TravelMode m) { backward_travel_mode = m; } - inline const TravelMode get_backward_mode() const { return backward_travel_mode; } + void set_forward_mode(const TravelMode m) { forward_travel_mode = m; } + TravelMode get_forward_mode() const { return forward_travel_mode; } + void set_backward_mode(const TravelMode m) { backward_travel_mode = m; } + TravelMode get_backward_mode() const { return backward_travel_mode; } - unsigned id; - unsigned nameID; double forward_speed; double backward_speed; double duration; std::string name; - bool access; bool roundabout; - bool isAccessRestricted; - bool ignoreInGrid; - std::vector path; - HashTable keyVals; + bool is_access_restricted; + bool ignore_in_grid; TravelMode forward_travel_mode : 4; TravelMode backward_travel_mode : 4; }; -#endif // EXTRACTION_WAY_H +#endif // EXTRACTION_WAY_HPP diff --git a/3party/osrm/osrm-backend/extractor/extractor.cpp b/3party/osrm/osrm-backend/extractor/extractor.cpp new file mode 100755 index 0000000000..0581e4e5cd --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/extractor.cpp @@ -0,0 +1,239 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "extractor.hpp" + +#include "extraction_containers.hpp" +#include "extraction_node.hpp" +#include "extraction_way.hpp" +#include "extractor_callbacks.hpp" +#include "restriction_parser.hpp" +#include "scripting_environment.hpp" + +#include "../util/git_sha.hpp" +#include "../util/make_unique.hpp" +#include "../util/simple_logger.hpp" +#include "../util/timing_util.hpp" + +#include "../typedefs.h" + +#include +#include + +#include + +#include + +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +int extractor::run(const ExtractorConfig &extractor_config) +{ + try + { + LogPolicy::GetInstance().Unmute(); + TIMER_START(extracting); + + const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads(); + const auto number_of_threads = + std::min(recommended_num_threads, extractor_config.requested_num_threads); + tbb::task_scheduler_init init(number_of_threads); + + SimpleLogger().Write() << "Input file: " << extractor_config.input_path.filename().string(); + SimpleLogger().Write() << "Profile: " << extractor_config.profile_path.filename().string(); + SimpleLogger().Write() << "Threads: " << number_of_threads; + + // setup scripting environment + ScriptingEnvironment scripting_environment(extractor_config.profile_path.string().c_str()); + + std::unordered_map string_map; + string_map[""] = 0; + + ExtractionContainers extraction_containers; + auto extractor_callbacks = + osrm::make_unique(extraction_containers, string_map); + + const osmium::io::File input_file(extractor_config.input_path.string()); + osmium::io::Reader reader(input_file); + const osmium::io::Header header = reader.header(); + + std::atomic number_of_nodes{0}; + std::atomic number_of_ways{0}; + std::atomic number_of_relations{0}; + std::atomic number_of_others{0}; + + SimpleLogger().Write() << "Parsing in progress.."; + TIMER_START(parsing); + + std::string generator = header.get("generator"); + if (generator.empty()) + { + generator = "unknown tool"; + } + SimpleLogger().Write() << "input file generated by " << generator; + + // write .timestamp data file + std::string timestamp = header.get("osmosis_replication_timestamp"); + if (timestamp.empty()) + { + timestamp = "n/a"; + } + SimpleLogger().Write() << "timestamp: " << timestamp; + + boost::filesystem::ofstream timestamp_out(extractor_config.timestamp_file_name); + timestamp_out.write(timestamp.c_str(), timestamp.length()); + timestamp_out.close(); + + // initialize vectors holding parsed objects + tbb::concurrent_vector> resulting_nodes; + tbb::concurrent_vector> resulting_ways; + tbb::concurrent_vector> + resulting_restrictions; + + // setup restriction parser + const RestrictionParser restriction_parser(scripting_environment.get_lua_state()); + + while (const osmium::memory::Buffer buffer = reader.read()) + { + // create a vector of iterators into the buffer + std::vector osm_elements; + for (auto iter = std::begin(buffer); iter != std::end(buffer); ++iter) + { + osm_elements.push_back(iter); + } + + // clear resulting vectors + resulting_nodes.clear(); + resulting_ways.clear(); + resulting_restrictions.clear(); + + // parse OSM entities in parallel, store in resulting vectors + tbb::parallel_for( + tbb::blocked_range(0, osm_elements.size()), + [&](const tbb::blocked_range &range) + { + ExtractionNode result_node; + ExtractionWay result_way; + lua_State *local_state = scripting_environment.get_lua_state(); + + for (auto x = range.begin(); x != range.end(); ++x) + { + const auto entity = osm_elements[x]; + + switch (entity->type()) + { + case osmium::item_type::node: + result_node.clear(); + ++number_of_nodes; + luabind::call_function( + local_state, "node_function", + boost::cref(static_cast(*entity)), + boost::ref(result_node)); + resulting_nodes.push_back(std::make_pair(x, result_node)); + break; + case osmium::item_type::way: + result_way.clear(); + ++number_of_ways; + luabind::call_function( + local_state, "way_function", + boost::cref(static_cast(*entity)), + boost::ref(result_way)); + resulting_ways.push_back(std::make_pair(x, result_way)); + break; + case osmium::item_type::relation: + ++number_of_relations; + resulting_restrictions.push_back(restriction_parser.TryParse( + static_cast(*entity))); + break; + default: + ++number_of_others; + break; + } + } + }); + + // put parsed objects thru extractor callbacks + for (const auto &result : resulting_nodes) + { + extractor_callbacks->ProcessNode( + static_cast(*(osm_elements[result.first])), + result.second); + } + for (const auto &result : resulting_ways) + { + extractor_callbacks->ProcessWay( + static_cast(*(osm_elements[result.first])), result.second); + } + for (const auto &result : resulting_restrictions) + { + extractor_callbacks->ProcessRestriction(result); + } + } + TIMER_STOP(parsing); + SimpleLogger().Write() << "Parsing finished after " << TIMER_SEC(parsing) << " seconds"; + + SimpleLogger().Write() << "Raw input contains " << number_of_nodes.load() << " nodes, " + << number_of_ways.load() << " ways, and " + << number_of_relations.load() << " relations, and " + << number_of_others.load() << " unknown entities"; + + extractor_callbacks.reset(); + + if (extraction_containers.all_edges_list.empty()) + { + SimpleLogger().Write(logWARNING) << "The input data is empty, exiting."; + return 1; + } + + extraction_containers.PrepareData(extractor_config.output_file_name, + extractor_config.restriction_file_name); + TIMER_STOP(extracting); + SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting) << "s"; + SimpleLogger().Write() << "To prepare the data for routing, run: " + << "./osrm-prepare " << extractor_config.output_file_name + << std::endl; + } + catch (std::exception &e) + { + SimpleLogger().Write(logWARNING) << e.what(); + return 1; + } + return 0; +} diff --git a/3party/osrm/osrm-backend/extractor/extractor.hpp b/3party/osrm/osrm-backend/extractor/extractor.hpp new file mode 100755 index 0000000000..8ea56c3cb0 --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/extractor.hpp @@ -0,0 +1,37 @@ +/* + +Copyright (c) 2015, 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 EXTRACTOR_HPP +#define EXTRACTOR_HPP + +#include "extractor_options.hpp" + +struct extractor +{ + int run(const ExtractorConfig &extractor_config); +}; +#endif /* EXTRACTOR_HPP */ diff --git a/3party/osrm/osrm-backend/extractor/extractor_callbacks.cpp b/3party/osrm/osrm-backend/extractor/extractor_callbacks.cpp new file mode 100755 index 0000000000..224468b060 --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/extractor_callbacks.cpp @@ -0,0 +1,211 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "extractor_callbacks.hpp" +#include "extraction_containers.hpp" +#include "extraction_node.hpp" +#include "extraction_way.hpp" + +#include "../data_structures/external_memory_node.hpp" +#include "../data_structures/restriction.hpp" +#include "../util/container.hpp" +#include "../util/simple_logger.hpp" + +#include + +#include +#include +#include + +ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers, + std::unordered_map &string_map) + : string_map(string_map), external_memory(extraction_containers) +{ +} + +/** warning: caller needs to take care of synchronization! */ +void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node, + const ExtractionNode &result_node) +{ + external_memory.all_nodes_list.push_back( + {static_cast(input_node.location().lat() * COORDINATE_PRECISION), + static_cast(input_node.location().lon() * COORDINATE_PRECISION), + static_cast(input_node.id()), + result_node.barrier, + result_node.traffic_lights}); +} + +void ExtractorCallbacks::ProcessRestriction( + const mapbox::util::optional &restriction) +{ + if (restriction) + { + external_memory.restrictions_list.push_back(restriction.get()); + // SimpleLogger().Write() << "from: " << restriction.get().restriction.from.node << + // ",via: " << restriction.get().restriction.via.node << + // ", to: " << restriction.get().restriction.to.node << + // ", only: " << (restriction.get().restriction.flags.is_only ? + // "y" : "n"); + } +} +/** warning: caller needs to take care of synchronization! */ +void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const ExtractionWay &parsed_way) +{ + if (((0 >= parsed_way.forward_speed) || + (TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)) && + ((0 >= parsed_way.backward_speed) || + (TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode)) && + (0 >= parsed_way.duration)) + { // Only true if the way is specified by the speed profile + return; + } + + if (input_way.nodes().size() <= 1) + { // safe-guard against broken data + return; + } + + if (std::numeric_limits::max() == input_way.id()) + { + SimpleLogger().Write(logDEBUG) << "found bogus way with id: " << input_way.id() + << " of size " << input_way.nodes().size(); + return; + } + if (0 < parsed_way.duration) + { + // TODO: iterate all way segments and set duration corresponding to the length of each + // segment + const_cast(parsed_way).forward_speed = + parsed_way.duration / (input_way.nodes().size() - 1); + const_cast(parsed_way).backward_speed = + parsed_way.duration / (input_way.nodes().size() - 1); + } + + if (std::numeric_limits::epsilon() >= std::abs(-1. - parsed_way.forward_speed)) + { + SimpleLogger().Write(logDEBUG) << "found way with bogus speed, id: " << input_way.id(); + return; + } + + // Get the unique identifier for the street name + const auto &string_map_iterator = string_map.find(parsed_way.name); + unsigned name_id = external_memory.name_list.size(); + if (string_map.end() == string_map_iterator) + { + external_memory.name_list.push_back(parsed_way.name); + string_map.insert(std::make_pair(parsed_way.name, name_id)); + } + else + { + name_id = string_map_iterator->second; + } + + const bool split_edge = (parsed_way.forward_speed > 0) && + (TRAVEL_MODE_INACCESSIBLE != parsed_way.forward_travel_mode) && + (parsed_way.backward_speed > 0) && + (TRAVEL_MODE_INACCESSIBLE != parsed_way.backward_travel_mode) && + ((parsed_way.forward_speed != parsed_way.backward_speed) || + (parsed_way.forward_travel_mode != parsed_way.backward_travel_mode)); + + auto pair_wise_segment_split = + [&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node) + { + // SimpleLogger().Write() << "adding edge (" << first_node.ref() << "," << + // last_node.ref() << "), fwd speed: " << parsed_way.forward_speed; + external_memory.all_edges_list.push_back(InternalExtractorEdge( + first_node.ref(), last_node.ref(), + ((split_edge || TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode) + ? ExtractionWay::oneway + : ExtractionWay::bidirectional), + parsed_way.forward_speed, name_id, parsed_way.roundabout, parsed_way.ignore_in_grid, + (0 < parsed_way.duration), parsed_way.is_access_restricted, + parsed_way.forward_travel_mode, split_edge)); + external_memory.used_node_id_list.push_back(first_node.ref()); + }; + + const bool is_opposite_way = TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode; + if (is_opposite_way) + { + const_cast(parsed_way).forward_travel_mode = + parsed_way.backward_travel_mode; + const_cast(parsed_way).backward_travel_mode = TRAVEL_MODE_INACCESSIBLE; + osrm::for_each_pair(input_way.nodes().crbegin(), input_way.nodes().crend(), + pair_wise_segment_split); + external_memory.used_node_id_list.push_back(input_way.nodes().front().ref()); + } + else + { + osrm::for_each_pair(input_way.nodes().cbegin(), input_way.nodes().cend(), + pair_wise_segment_split); + external_memory.used_node_id_list.push_back(input_way.nodes().back().ref()); + } + + // The following information is needed to identify start and end segments of restrictions + external_memory.way_start_end_id_list.push_back( + {(EdgeID)input_way.id(), + (NodeID)input_way.nodes()[0].ref(), + (NodeID)input_way.nodes()[1].ref(), + (NodeID)input_way.nodes()[input_way.nodes().size() - 2].ref(), + (NodeID)input_way.nodes().back().ref()}); + + if (split_edge) + { // Only true if the way should be split + BOOST_ASSERT(parsed_way.backward_travel_mode > 0); + auto pair_wise_segment_split_2 = + [&](const osmium::NodeRef &first_node, const osmium::NodeRef &last_node) + { + // SimpleLogger().Write() << "adding edge (" << last_node.ref() << "," << + // first_node.ref() << "), bwd speed: " << parsed_way.backward_speed; + external_memory.all_edges_list.push_back(InternalExtractorEdge( + last_node.ref(), first_node.ref(), ExtractionWay::oneway, parsed_way.backward_speed, + name_id, parsed_way.roundabout, parsed_way.ignore_in_grid, + (0 < parsed_way.duration), parsed_way.is_access_restricted, + parsed_way.backward_travel_mode, split_edge)); + }; + + if (is_opposite_way) + { + // SimpleLogger().Write() << "opposite2"; + osrm::for_each_pair(input_way.nodes().crbegin(), input_way.nodes().crend(), + pair_wise_segment_split_2); + external_memory.used_node_id_list.push_back(input_way.nodes().front().ref()); + } + else + { + osrm::for_each_pair(input_way.nodes().cbegin(), input_way.nodes().cend(), + pair_wise_segment_split_2); + external_memory.used_node_id_list.push_back(input_way.nodes().back().ref()); + } + + external_memory.way_start_end_id_list.push_back( + {(EdgeID)input_way.id(), + (NodeID)input_way.nodes()[1].ref(), + (NodeID)input_way.nodes()[0].ref(), + (NodeID)input_way.nodes().back().ref(), + (NodeID)input_way.nodes()[input_way.nodes().size() - 2].ref()}); + } +} diff --git a/3party/osrm/osrm-backend/Extractor/ExtractorCallbacks.h b/3party/osrm/osrm-backend/extractor/extractor_callbacks.hpp old mode 100644 new mode 100755 similarity index 79% rename from 3party/osrm/osrm-backend/Extractor/ExtractorCallbacks.h rename to 3party/osrm/osrm-backend/extractor/extractor_callbacks.hpp index fcdb272da8..8eab0182b1 --- a/3party/osrm/osrm-backend/Extractor/ExtractorCallbacks.h +++ b/3party/osrm/osrm-backend/extractor/extractor_callbacks.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,18 +25,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef EXTRACTOR_CALLBACKS_H -#define EXTRACTOR_CALLBACKS_H +#ifndef EXTRACTOR_CALLBACKS_HPP +#define EXTRACTOR_CALLBACKS_HPP +#include "extraction_way.hpp" #include "../typedefs.h" -#include +#include + +#include + #include +#include struct ExternalMemoryNode; class ExtractionContainers; -struct ExtractionWay; struct InputRestrictionContainer; +struct ExtractionNode; class ExtractorCallbacks { @@ -51,13 +56,13 @@ class ExtractorCallbacks std::unordered_map &string_map); // warning: caller needs to take care of synchronization! - void ProcessNode(const ExternalMemoryNode &node); + void ProcessNode(const osmium::Node ¤t_node, const ExtractionNode &result_node); // warning: caller needs to take care of synchronization! - bool ProcessRestriction(const InputRestrictionContainer &restriction); + void ProcessRestriction(const mapbox::util::optional &restriction); // warning: caller needs to take care of synchronization! - void ProcessWay(ExtractionWay &way); + void ProcessWay(const osmium::Way ¤t_way, const ExtractionWay &result_way); }; -#endif /* EXTRACTOR_CALLBACKS_H */ +#endif /* EXTRACTOR_CALLBACKS_HPP */ diff --git a/3party/osrm/osrm-backend/extractor/extractor_options.cpp b/3party/osrm/osrm-backend/extractor/extractor_options.cpp new file mode 100755 index 0000000000..9ae5cd4c10 --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/extractor_options.cpp @@ -0,0 +1,174 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "extractor_options.hpp" + +#include "../util/git_sha.hpp" +#include "../util/ini_file.hpp" +#include "../util/simple_logger.hpp" + +#include +#include + +#include + +return_code +ExtractorOptions::ParseArguments(int argc, char *argv[], ExtractorConfig &extractor_config) +{ + // 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", boost::program_options::value( + &extractor_config.config_file_path)->default_value("extractor.ini"), + "Path to a configuration file."); + + // declare a group of options that will be allowed both on command line and in config file + boost::program_options::options_description config_options("Configuration"); + config_options.add_options()("profile,p", + boost::program_options::value( + &extractor_config.profile_path)->default_value("profile.lua"), + "Path to LUA routing profile")( + "threads,t", + boost::program_options::value(&extractor_config.requested_num_threads) + ->default_value(tbb::task_scheduler_init::default_num_threads()), + "Number of threads to use"); + + // hidden options, will be allowed both on command line and in config file, but will not be + // shown to the user + boost::program_options::options_description hidden_options("Hidden options"); + hidden_options.add_options()("input,i", boost::program_options::value( + &extractor_config.input_path), + "Input file in .osm, .osm.bz2 or .osm.pbf format"); + + // positional option + boost::program_options::positional_options_description positional_options; + positional_options.add("input", 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 config_file_options; + config_file_options.add(config_options).add(hidden_options); + + boost::program_options::options_description visible_options( + boost::filesystem::basename(argv[0]) + " [options]"); + visible_options.add(generic_options).add(config_options); + + // parse command line options + try + { + 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() << g_GIT_DESCRIPTION; + return return_code::exit; + } + + if (option_variables.count("help")) + { + SimpleLogger().Write() << visible_options; + return return_code::exit; + } + + boost::program_options::notify(option_variables); + + // parse config file + if (boost::filesystem::is_regular_file(extractor_config.config_file_path)) + { + SimpleLogger().Write() + << "Reading options from: " << extractor_config.config_file_path.string(); + std::string ini_file_contents = + read_file_lower_content(extractor_config.config_file_path); + std::stringstream config_stream(ini_file_contents); + boost::program_options::store(parse_config_file(config_stream, config_file_options), + option_variables); + boost::program_options::notify(option_variables); + } + + if (!option_variables.count("input")) + { + SimpleLogger().Write() << visible_options; + return return_code::exit; + } + } + catch (std::exception &e) + { + SimpleLogger().Write(logWARNING) << e.what(); + return return_code::fail; + } + + return return_code::ok; +} + +void ExtractorOptions::GenerateOutputFilesNames(ExtractorConfig &extractor_config) +{ + boost::filesystem::path &input_path = extractor_config.input_path; + extractor_config.output_file_name = input_path.string(); + extractor_config.restriction_file_name = input_path.string(); + extractor_config.timestamp_file_name = input_path.string(); + std::string::size_type pos = extractor_config.output_file_name.find(".osm.bz2"); + if (pos == std::string::npos) + { + pos = extractor_config.output_file_name.find(".osm.pbf"); + if (pos == std::string::npos) + { + pos = extractor_config.output_file_name.find(".osm.xml"); + } + } + if (pos == std::string::npos) + { + pos = extractor_config.output_file_name.find(".pbf"); + } + if (pos == std::string::npos) + { + pos = extractor_config.output_file_name.find(".osm"); + if (pos == std::string::npos) + { + extractor_config.output_file_name.append(".osrm"); + extractor_config.restriction_file_name.append(".osrm.restrictions"); + extractor_config.timestamp_file_name.append(".osrm.timestamp"); + } + else + { + extractor_config.output_file_name.replace(pos, 5, ".osrm"); + extractor_config.restriction_file_name.replace(pos, 5, ".osrm.restrictions"); + extractor_config.timestamp_file_name.replace(pos, 5, ".osrm.timestamp"); + } + } + else + { + extractor_config.output_file_name.replace(pos, 8, ".osrm"); + extractor_config.restriction_file_name.replace(pos, 8, ".osrm.restrictions"); + extractor_config.timestamp_file_name.replace(pos, 8, ".osrm.timestamp"); + } +} diff --git a/3party/osrm/osrm-backend/extractor/extractor_options.hpp b/3party/osrm/osrm-backend/extractor/extractor_options.hpp new file mode 100755 index 0000000000..5712ea01a3 --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/extractor_options.hpp @@ -0,0 +1,63 @@ +/* + +Copyright (c) 2015, 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 EXTRACTOR_OPTIONS_HPP +#define EXTRACTOR_OPTIONS_HPP + +#include + +#include + +enum class return_code : unsigned +{ + ok, + fail, + exit +}; + +struct ExtractorConfig +{ + ExtractorConfig() noexcept : requested_num_threads(0) {} + boost::filesystem::path config_file_path; + boost::filesystem::path input_path; + boost::filesystem::path profile_path; + + std::string output_file_name; + std::string restriction_file_name; + std::string timestamp_file_name; + + unsigned requested_num_threads; +}; + +struct ExtractorOptions +{ + static return_code ParseArguments(int argc, char *argv[], ExtractorConfig &extractor_config); + + static void GenerateOutputFilesNames(ExtractorConfig &extractor_config); +}; + +#endif // EXTRACTOR_OPTIONS_HPP diff --git a/3party/osrm/osrm-backend/extractor/first_and_last_segment_of_way.hpp b/3party/osrm/osrm-backend/extractor/first_and_last_segment_of_way.hpp new file mode 100755 index 0000000000..3a26be7ced --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/first_and_last_segment_of_way.hpp @@ -0,0 +1,88 @@ +/* + +Copyright (c) 2014, 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 FIRST_AND_LAST_SEGMENT_OF_WAY_HPP +#define FIRST_AND_LAST_SEGMENT_OF_WAY_HPP + +#include "../data_structures/external_memory_node.hpp" +#include "../typedefs.h" + +#include +#include + +struct FirstAndLastSegmentOfWay +{ + EdgeID way_id; + NodeID first_segment_source_id; + NodeID first_segment_target_id; + NodeID last_segment_source_id; + NodeID last_segment_target_id; + FirstAndLastSegmentOfWay() + : way_id(std::numeric_limits::max()), + first_segment_source_id(std::numeric_limits::max()), + first_segment_target_id(std::numeric_limits::max()), + last_segment_source_id(std::numeric_limits::max()), + last_segment_target_id(std::numeric_limits::max()) + { + } + + FirstAndLastSegmentOfWay(EdgeID w, NodeID fs, NodeID ft, NodeID ls, NodeID lt) + : way_id(w), first_segment_source_id(fs), first_segment_target_id(ft), + last_segment_source_id(ls), last_segment_target_id(lt) + { + } + + static FirstAndLastSegmentOfWay min_value() + { + return {std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::min()}; + } + static FirstAndLastSegmentOfWay max_value() + { + return {std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max()}; + } +}; + +struct FirstAndLastSegmentOfWayStxxlCompare +{ + using value_type = FirstAndLastSegmentOfWay; + bool operator()(const FirstAndLastSegmentOfWay &a, const FirstAndLastSegmentOfWay &b) const + { + return a.way_id < b.way_id; + } + value_type max_value() { return FirstAndLastSegmentOfWay::max_value(); } + value_type min_value() { return FirstAndLastSegmentOfWay::min_value(); } +}; + +#endif /* FIRST_AND_LAST_SEGMENT_OF_WAY_HPP */ diff --git a/3party/osrm/osrm-backend/Extractor/InternalExtractorEdge.h b/3party/osrm/osrm-backend/extractor/internal_extractor_edge.hpp old mode 100644 new mode 100755 similarity index 73% rename from 3party/osrm/osrm-backend/Extractor/InternalExtractorEdge.h rename to 3party/osrm/osrm-backend/extractor/internal_extractor_edge.hpp index 30809bddc2..27e1af146f --- a/3party/osrm/osrm-backend/Extractor/InternalExtractorEdge.h +++ b/3party/osrm/osrm-backend/extractor/internal_extractor_edge.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,26 +25,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef INTERNAL_EXTRACTOR_EDGE_H -#define INTERNAL_EXTRACTOR_EDGE_H +#ifndef INTERNAL_EXTRACTOR_EDGE_HPP +#define INTERNAL_EXTRACTOR_EDGE_HPP #include "../typedefs.h" -#include "../DataStructures/TravelMode.h" -#include +#include "../data_structures/travel_mode.hpp" #include +#include + struct InternalExtractorEdge { InternalExtractorEdge() - : way_id(0), start(0), target(0), direction(0), speed(0), name_id(0), is_roundabout(false), + : start(0), target(0), speed(0), name_id(0), direction(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) + is_split(false), travel_mode(TRAVEL_MODE_INACCESSIBLE) { } - explicit InternalExtractorEdge(unsigned id, - NodeID start, + explicit InternalExtractorEdge(NodeID start, NodeID target, short direction, double speed, @@ -55,36 +55,36 @@ struct InternalExtractorEdge bool is_access_restricted, TravelMode travel_mode, bool is_split) - : 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), + : start(start), target(target), speed(speed), name_id(name_id), direction(direction), + 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) + is_split(is_split), travel_mode(travel_mode) { } // necessary static util functions for stxxl's sorting static InternalExtractorEdge min_value() { - return InternalExtractorEdge(0, 0, 0, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false); + return InternalExtractorEdge(0, 0, 0, 0, 0, false, false, false, false, + TRAVEL_MODE_INACCESSIBLE, false); } static InternalExtractorEdge max_value() { - return InternalExtractorEdge( - SPECIAL_NODEID, SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false); + return InternalExtractorEdge(SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, false, false, false, + false, TRAVEL_MODE_INACCESSIBLE, false); } - unsigned way_id; NodeID start; NodeID target; - short direction; double speed; unsigned name_id; - bool is_roundabout; - bool is_in_tiny_cc; - bool is_duration_set; - bool is_access_restricted; + short direction; + bool is_roundabout : 1; + bool is_in_tiny_cc : 1; + bool is_duration_set : 1; + bool is_access_restricted : 1; + bool is_split : 1; TravelMode travel_mode : 4; - bool is_split; FixedPointCoordinate source_coordinate; FixedPointCoordinate target_coordinate; @@ -117,4 +117,4 @@ struct CmpEdgeByTargetID value_type min_value() { return InternalExtractorEdge::min_value(); } }; -#endif // INTERNAL_EXTRACTOR_EDGE_H +#endif // INTERNAL_EXTRACTOR_EDGE_HPP diff --git a/3party/osrm/osrm-backend/extractor/restriction_parser.cpp b/3party/osrm/osrm-backend/extractor/restriction_parser.cpp new file mode 100755 index 0000000000..6781040d4a --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/restriction_parser.cpp @@ -0,0 +1,233 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "restriction_parser.hpp" +#include "extraction_way.hpp" +#include "scripting_environment.hpp" + +#include "../data_structures/external_memory_node.hpp" +#include "../util/lua_util.hpp" +#include "../util/osrm_exception.hpp" +#include "../util/simple_logger.hpp" + +#include +#include +#include +#include + +#include + +namespace +{ +int lua_error_callback(lua_State *lua_state) +{ + luabind::object error_msg(luabind::from_stack(lua_state, -1)); + std::ostringstream error_stream; + error_stream << error_msg; + throw osrm::exception("ERROR occured in profile script:\n" + error_stream.str()); +} +} + +RestrictionParser::RestrictionParser(lua_State *lua_state) + : /*lua_state(scripting_environment.getLuaState()),*/ 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) + { + SimpleLogger().Write() << "Using turn restrictions"; + } + else + { + SimpleLogger().Write() << "Ignoring turn restrictions"; + } +} + +void RestrictionParser::ReadRestrictionExceptions(lua_State *lua_state) +{ + if (lua_function_exists(lua_state, "get_exceptions")) + { + luabind::set_pcall_callback(&lua_error_callback); + // get list of turn restriction exceptions + luabind::call_function(lua_state, "get_exceptions", + boost::ref(restriction_exceptions)); + const unsigned exception_count = restriction_exceptions.size(); + SimpleLogger().Write() << "Found " << exception_count + << " exceptions to turn restrictions:"; + for (const std::string &str : restriction_exceptions) + { + SimpleLogger().Write() << " " << str; + } + } + else + { + SimpleLogger().Write() << "Found no exceptions to turn restrictions"; + } +} + +mapbox::util::optional +RestrictionParser::TryParse(const osmium::Relation &relation) const +{ + // return if turn restrictions should be ignored + if (!use_turn_restrictions) + { + return mapbox::util::optional(); + } + + osmium::tags::KeyPrefixFilter filter(false); + filter.add(true, "restriction"); + + const osmium::TagList &tag_list = relation.tags(); + + osmium::tags::KeyPrefixFilter::iterator fi_begin(filter, tag_list.begin(), tag_list.end()); + osmium::tags::KeyPrefixFilter::iterator fi_end(filter, tag_list.end(), tag_list.end()); + + // if it's a restriction, continue; + if (std::distance(fi_begin, fi_end) == 0) + { + return mapbox::util::optional(); + } + + // check if the restriction should be ignored + const char *except = relation.get_value_by_key("except"); + if (except != nullptr && ShouldIgnoreRestriction(except)) + { + return mapbox::util::optional(); + } + + bool is_only_restriction = false; + + for (auto iter = fi_begin; iter != fi_end; ++iter) + { + if (std::string("restriction") == iter->key() || + std::string("restriction::hgv") == iter->key()) + { + const std::string restriction_value(iter->value()); + + if (restriction_value.find("only_") == 0) + { + is_only_restriction = true; + } + } + } + + InputRestrictionContainer restriction_container(is_only_restriction); + + for (const auto &member : relation.members()) + { + const char *role = member.role(); + if (strcmp("from", role) != 0 && strcmp("to", role) != 0 && strcmp("via", role) != 0) + { + continue; + } + + switch (member.type()) + { + case osmium::item_type::node: + // Make sure nodes appear only in the role if a via node + if (0 == strcmp("from", role) || 0 == strcmp("to", role)) + { + continue; + } + BOOST_ASSERT(0 == strcmp("via", role)); + + // set via node id + restriction_container.restriction.via.node = member.ref(); + break; + + case osmium::item_type::way: + BOOST_ASSERT(0 == strcmp("from", role) || 0 == strcmp("to", role) || + 0 == strcmp("via", role)); + if (0 == strcmp("from", role)) + { + restriction_container.restriction.from.way = member.ref(); + } + else if (0 == strcmp("to", role)) + { + restriction_container.restriction.to.way = member.ref(); + } + // else if (0 == strcmp("via", role)) + // { + // not yet suppported + // restriction_container.restriction.via.way = member.ref(); + // } + break; + case osmium::item_type::relation: + // not yet supported, but who knows what the future holds... + break; + default: + // shouldn't ever happen + break; + } + } + return mapbox::util::optional(restriction_container); +} + +bool RestrictionParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const +{ + // should this restriction be ignored? yes if there's an overlap between: + // a) the list of modes in the except tag of the restriction + // (except_tag_string), eg: except=bus;bicycle + // b) the lua profile defines a hierachy of modes, + // eg: [access, vehicle, bicycle] + + if (except_tag_string.empty()) + { + return false; + } + + // Be warned, this is quadratic work here, but we assume that + // only a few exceptions are actually defined. + std::vector exceptions; + boost::algorithm::split_regex(exceptions, except_tag_string, boost::regex("[;][ ]*")); + + return std::any_of(std::begin(exceptions), std::end(exceptions), + [&](const std::string ¤t_string) + { + if (std::end(restriction_exceptions) != + std::find(std::begin(restriction_exceptions), + std::end(restriction_exceptions), current_string)) + { + return true; + } + return false; + }); +} diff --git a/3party/osrm/osrm-backend/extractor/restriction_parser.hpp b/3party/osrm/osrm-backend/extractor/restriction_parser.hpp new file mode 100755 index 0000000000..0a632d83ec --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/restriction_parser.hpp @@ -0,0 +1,62 @@ +/* + +Copyright (c) 2014, 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 RESTRICTION_PARSER_HPP +#define RESTRICTION_PARSER_HPP + +#include "../data_structures/restriction.hpp" + +#include +#include + +#include + +#include +#include + +struct lua_State; +class ScriptingEnvironment; + +class RestrictionParser +{ + public: + // RestrictionParser(ScriptingEnvironment &scripting_environment); + RestrictionParser(lua_State *lua_state); + mapbox::util::optional + 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; + + // lua_State *lua_state; + std::vector restriction_exceptions; + bool use_turn_restrictions; +}; + +#endif /* RESTRICTION_PARSER_HPP */ diff --git a/3party/osrm/osrm-backend/extractor/scripting_environment.cpp b/3party/osrm/osrm-backend/extractor/scripting_environment.cpp new file mode 100755 index 0000000000..972772246a --- /dev/null +++ b/3party/osrm/osrm-backend/extractor/scripting_environment.cpp @@ -0,0 +1,151 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "scripting_environment.hpp" + +#include "extraction_helper_functions.hpp" +#include "extraction_node.hpp" +#include "extraction_way.hpp" +#include "../data_structures/external_memory_node.hpp" +#include "../util/lua_util.hpp" +#include "../util/osrm_exception.hpp" +#include "../util/simple_logger.hpp" +#include "../typedefs.h" + +#include + +#include + +#include +namespace +{ +// wrapper method as luabind doesn't automatically overload funcs w/ default parameters +template +auto get_value_by_key(T const &object, const char *key) -> decltype(object.get_value_by_key(key)) +{ + return object.get_value_by_key(key, ""); +} + +int lua_error_callback(lua_State *L) // This is so I can use my own function as an +// exception handler, pcall_log() +{ + luabind::object error_msg(luabind::from_stack(L, -1)); + std::ostringstream error_stream; + error_stream << error_msg; + throw osrm::exception("ERROR occured in profile script:\n" + error_stream.str()); +} +} + +ScriptingEnvironment::ScriptingEnvironment(const std::string &file_name) : file_name(file_name) +{ + SimpleLogger().Write() << "Using script " << file_name; +} + +void ScriptingEnvironment::init_lua_state(lua_State *lua_state) +{ + typedef double (osmium::Location::*location_member_ptr_type)() const; + + luabind::open(lua_state); + // open utility libraries string library; + luaL_openlibs(lua_state); + + luaAddScriptFolderToLoadPath(lua_state, file_name.c_str()); + + // Add our function to the state's global scope + luabind::module(lua_state)[ + luabind::def("print", LUA_print), + luabind::def("durationIsValid", durationIsValid), + luabind::def("parseDuration", parseDuration), + + luabind::class_>("vector") + .def("Add", static_cast::*)(const std::string &)>( + &std::vector::push_back)), + + luabind::class_("Location") + .def("lat", &osmium::Location::lat) + .def("lon", &osmium::Location::lon), + + luabind::class_("Node") + // .def("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) + .def("id", &osmium::Node::id), + + luabind::class_("ResultNode") + .def_readwrite("traffic_lights", &ExtractionNode::traffic_lights) + .def_readwrite("barrier", &ExtractionNode::barrier), + + luabind::class_("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("ignore_in_index", &ExtractionWay::ignore_in_grid) + .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) + .enum_("constants")[ + luabind::value("notSure", 0), + luabind::value("oneway", 1), + luabind::value("bidirectional", 2), + luabind::value("opposite", 3) + ], + luabind::class_("Way") + .def("get_value_by_key", &osmium::Way::get_value_by_key) + .def("get_value_by_key", &get_value_by_key) + .def("id", &osmium::Way::id) + ]; + + if (0 != luaL_dofile(lua_state, file_name.c_str())) + { + luabind::object error_msg(luabind::from_stack(lua_state, -1)); + std::ostringstream error_stream; + error_stream << error_msg; + throw osrm::exception("ERROR occured in profile script:\n" + error_stream.str()); + } +} + +lua_State *ScriptingEnvironment::get_lua_state() +{ + std::lock_guard lock(init_mutex); + bool initialized = false; + auto &ref = script_contexts.local(initialized); + if (!initialized) + { + std::shared_ptr state(luaL_newstate(), lua_close); + ref = state; + init_lua_state(ref.get()); + } + luabind::set_pcall_callback(&lua_error_callback); + + return ref.get(); +} diff --git a/3party/osrm/osrm-backend/Extractor/ScriptingEnvironment.h b/3party/osrm/osrm-backend/extractor/scripting_environment.hpp old mode 100644 new mode 100755 similarity index 80% rename from 3party/osrm/osrm-backend/Extractor/ScriptingEnvironment.h rename to 3party/osrm/osrm-backend/extractor/scripting_environment.hpp index 2b1fffead9..be05103c8c --- a/3party/osrm/osrm-backend/Extractor/ScriptingEnvironment.h +++ b/3party/osrm/osrm-backend/extractor/scripting_environment.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,11 +25,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SCRIPTINGENVIRONMENT_H_ -#define SCRIPTINGENVIRONMENT_H_ +#ifndef SCRIPTING_ENVIRONMENT_HPP +#define SCRIPTING_ENVIRONMENT_HPP #include #include +#include #include struct lua_State; @@ -37,16 +38,16 @@ struct lua_State; class ScriptingEnvironment { public: - ScriptingEnvironment(); - explicit ScriptingEnvironment(const char *file_name); + ScriptingEnvironment() = delete; + explicit ScriptingEnvironment(const std::string &file_name); - lua_State *getLuaState(); + lua_State *get_lua_state(); private: - void initLuaState(lua_State* lua_state); - + void init_lua_state(lua_State *lua_state); + std::mutex init_mutex; std::string file_name; tbb::enumerable_thread_specific> script_contexts; }; -#endif /* SCRIPTINGENVIRONMENT_H_ */ +#endif /* SCRIPTING_ENVIRONMENT_HPP */ diff --git a/3party/osrm/osrm-backend/features/bicycle/access.feature b/3party/osrm/osrm-backend/features/bicycle/access.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/access_node.feature b/3party/osrm/osrm-backend/features/bicycle/access_node.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/area.feature b/3party/osrm/osrm-backend/features/bicycle/area.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/barrier.feature b/3party/osrm/osrm-backend/features/bicycle/barrier.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/bridge.feature b/3party/osrm/osrm-backend/features/bicycle/bridge.feature new file mode 100755 index 0000000000..232581647e --- /dev/null +++ b/3party/osrm/osrm-backend/features/bicycle/bridge.feature @@ -0,0 +1,47 @@ +@routing @bicycle @bridge +Feature: Bicycle - Handle movable bridge + + Background: + Given the profile "bicycle" + + Scenario: Car - Use a ferry route + Given the node map + | a | b | c | | | + | | | d | | | + | | | e | f | g | + + And the ways + | nodes | highway | bridge | bicycle | + | abc | primary | | | + | cde | | movable | yes | + | efg | primary | | | + + When I route I should get + | from | to | route | modes | + | a | g | abc,cde,efg | 1,5,1 | + | b | f | abc,cde,efg | 1,5,1 | + | e | c | cde | 5 | + | e | b | cde,abc | 5,1 | + | e | a | cde,abc | 5,1 | + | c | e | cde | 5 | + | c | f | cde,efg | 5,1 | + | c | g | cde,efg | 5,1 | + + Scenario: Car - Properly handle durations + Given the node map + | a | b | c | | | + | | | d | | | + | | | e | f | g | + + And the ways + | nodes | highway | bridge | duration | + | abc | primary | | | + | cde | | movable | 00:05:00 | + | efg | primary | | | + + When I route I should get + | from | to | route | modes | speed | + | a | g | abc,cde,efg | 1,5,1 | 5 km/h | + | b | f | abc,cde,efg | 1,5,1 | 3 km/h | + | c | e | cde | 5 | 2 km/h | + | e | c | cde | 5 | 2 km/h | diff --git a/3party/osrm/osrm-backend/features/bicycle/cycleway.feature b/3party/osrm/osrm-backend/features/bicycle/cycleway.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/destination.feature b/3party/osrm/osrm-backend/features/bicycle/destination.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/ferry.feature b/3party/osrm/osrm-backend/features/bicycle/ferry.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/maxspeed.feature b/3party/osrm/osrm-backend/features/bicycle/maxspeed.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/mode.feature b/3party/osrm/osrm-backend/features/bicycle/mode.feature old mode 100644 new mode 100755 index 195a37f67b..2bfa4de5b3 --- a/3party/osrm/osrm-backend/features/bicycle/mode.feature +++ b/3party/osrm/osrm-backend/features/bicycle/mode.feature @@ -9,145 +9,145 @@ Feature: Bike - Mode flag Background: Given the profile "bicycle" - + Scenario: Bike - Mode when using a ferry - Given the node map - | a | b | | - | | c | d | + Given the node map + | a | b | | + | | c | d | - And the ways - | nodes | highway | route | duration | - | ab | primary | | | - | bc | | ferry | 0:01 | - | cd | primary | | | + And the ways + | nodes | highway | route | duration | + | ab | primary | | | + | bc | | ferry | 0:01 | + | cd | primary | | | - When I route I should get - | from | to | route | turns | modes | - | a | d | ab,bc,cd | head,right,left,destination | 1,3,1 | - | d | a | cd,bc,ab | head,right,left,destination | 1,3,1 | - | c | a | bc,ab | head,left,destination | 3,1 | - | d | b | cd,bc | head,right,destination | 1,3 | - | a | c | ab,bc | head,right,destination | 1,3 | - | b | d | bc,cd | head,left,destination | 3,1 | + When I route I should get + | from | to | route | turns | modes | + | a | d | ab,bc,cd | head,right,left,destination | 1,3,1 | + | d | a | cd,bc,ab | head,right,left,destination | 1,3,1 | + | c | a | bc,ab | head,left,destination | 3,1 | + | d | b | cd,bc | head,right,destination | 1,3 | + | a | c | ab,bc | head,right,destination | 1,3 | + | b | d | bc,cd | head,left,destination | 3,1 | Scenario: Bike - Mode when using a train - Given the node map - | a | b | | - | | c | d | + Given the node map + | a | b | | + | | c | d | - And the ways - | nodes | highway | railway | bicycle | - | ab | primary | | | - | bc | | train | yes | - | cd | primary | | | + And the ways + | nodes | highway | railway | bicycle | + | ab | primary | | | + | bc | | train | yes | + | cd | primary | | | - When I route I should get - | from | to | route | turns | modes | - | a | d | ab,bc,cd | head,right,left,destination | 1,4,1 | - | d | a | cd,bc,ab | head,right,left,destination | 1,4,1 | - | c | a | bc,ab | head,left,destination | 4,1 | - | d | b | cd,bc | head,right,destination | 1,4 | - | a | c | ab,bc | head,right,destination | 1,4 | - | b | d | bc,cd | head,left,destination | 4,1 | + When I route I should get + | from | to | route | turns | modes | + | a | d | ab,bc,cd | head,right,left,destination | 1,4,1 | + | d | a | cd,bc,ab | head,right,left,destination | 1,4,1 | + | c | a | bc,ab | head,left,destination | 4,1 | + | d | b | cd,bc | head,right,destination | 1,4 | + | a | c | ab,bc | head,right,destination | 1,4 | + | b | d | bc,cd | head,left,destination | 4,1 | Scenario: Bike - Mode when pushing bike against oneways - Given the node map - | a | b | | - | | c | d | + Given the node map + | a | b | | + | | c | d | - And the ways - | nodes | highway | oneway | - | ab | primary | | - | bc | primary | yes | - | cd | primary | | + And the ways + | nodes | highway | oneway | + | ab | primary | | + | bc | primary | yes | + | cd | primary | | - When I route I should get - | from | to | route | turns | modes | - | a | d | ab,bc,cd | head,right,left,destination | 1,1,1 | - | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 | - | c | a | bc,ab | head,left,destination | 2,1 | - | d | b | cd,bc | head,right,destination | 1,2 | - | a | c | ab,bc | head,right,destination | 1,1 | - | b | d | bc,cd | head,left,destination | 1,1 | + When I route I should get + | from | to | route | turns | modes | + | a | d | ab,bc,cd | head,right,left,destination | 1,1,1 | + | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 | + | c | a | bc,ab | head,left,destination | 2,1 | + | d | b | cd,bc | head,right,destination | 1,2 | + | a | c | ab,bc | head,right,destination | 1,1 | + | b | d | bc,cd | head,left,destination | 1,1 | Scenario: Bike - Mode when pushing on pedestrain streets - Given the node map - | a | b | | - | | c | d | + Given the node map + | a | b | | + | | c | d | - And the ways - | nodes | highway | - | ab | primary | - | bc | pedestrian | - | cd | primary | + And the ways + | nodes | highway | + | ab | primary | + | bc | pedestrian | + | cd | primary | - When I route I should get - | from | to | route | turns | modes | - | a | d | ab,bc,cd | head,right,left,destination | 1,2,1 | - | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 | - | c | a | bc,ab | head,left,destination | 2,1 | - | d | b | cd,bc | head,right,destination | 1,2 | - | a | c | ab,bc | head,right,destination | 1,2 | - | b | d | bc,cd | head,left,destination | 2,1 | + When I route I should get + | from | to | route | turns | modes | + | a | d | ab,bc,cd | head,right,left,destination | 1,2,1 | + | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 | + | c | a | bc,ab | head,left,destination | 2,1 | + | d | b | cd,bc | head,right,destination | 1,2 | + | a | c | ab,bc | head,right,destination | 1,2 | + | b | d | bc,cd | head,left,destination | 2,1 | Scenario: Bike - Mode when pushing on pedestrain areas - Given the node map - | a | b | | | - | | c | d | f | + Given the node map + | a | b | | | + | | c | d | f | - And the ways - | nodes | highway | area | - | ab | primary | | - | bcd | pedestrian | yes | - | df | primary | | + And the ways + | nodes | highway | area | + | ab | primary | | + | bcd | pedestrian | yes | + | df | primary | | - When I route I should get - | from | to | route | modes | - | a | f | ab,bcd,df | 1,2,1 | - | f | a | df,bcd,ab | 1,2,1 | - | d | a | bcd,ab | 2,1 | - | f | b | df,bcd | 1,2 | - | a | d | ab,bcd | 1,2 | - | b | f | bcd,df | 2,1 | + When I route I should get + | from | to | route | modes | + | a | f | ab,bcd,df | 1,2,1 | + | f | a | df,bcd,ab | 1,2,1 | + | d | a | bcd,ab | 2,1 | + | f | b | df,bcd | 1,2 | + | a | d | ab,bcd | 1,2 | + | b | f | bcd,df | 2,1 | Scenario: Bike - Mode when pushing on steps - Given the node map - | a | b | | | - | | c | d | f | + Given the node map + | a | b | | | + | | c | d | f | - And the ways - | nodes | highway | - | ab | primary | - | bc | steps | - | cd | primary | + And the ways + | nodes | highway | + | ab | primary | + | bc | steps | + | cd | primary | - When I route I should get - | from | to | route | turns | modes | - | a | d | ab,bc,cd | head,right,left,destination | 1,2,1 | - | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 | - | c | a | bc,ab | head,left,destination | 2,1 | - | d | b | cd,bc | head,right,destination | 1,2 | - | a | c | ab,bc | head,right,destination | 1,2 | - | b | d | bc,cd | head,left,destination | 2,1 | + When I route I should get + | from | to | route | turns | modes | + | a | d | ab,bc,cd | head,right,left,destination | 1,2,1 | + | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 | + | c | a | bc,ab | head,left,destination | 2,1 | + | d | b | cd,bc | head,right,destination | 1,2 | + | a | c | ab,bc | head,right,destination | 1,2 | + | b | d | bc,cd | head,left,destination | 2,1 | Scenario: Bike - Mode when bicycle=dismount - Given the node map - | a | b | | | - | | c | d | f | + Given the node map + | a | b | | | + | | c | d | f | - And the ways - | nodes | highway | bicycle | - | ab | primary | | - | bc | primary | dismount | - | cd | primary | | + And the ways + | nodes | highway | bicycle | + | ab | primary | | + | bc | primary | dismount | + | cd | primary | | - When I route I should get - | from | to | route | turns | modes | - | a | d | ab,bc,cd | head,right,left,destination | 1,2,1 | - | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 | - | c | a | bc,ab | head,left,destination | 2,1 | - | d | b | cd,bc | head,right,destination | 1,2 | - | a | c | ab,bc | head,right,destination | 1,2 | + When I route I should get + | from | to | route | turns | modes | + | a | d | ab,bc,cd | head,right,left,destination | 1,2,1 | + | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 | + | c | a | bc,ab | head,left,destination | 2,1 | + | d | b | cd,bc | head,right,destination | 1,2 | + | a | c | ab,bc | head,right,destination | 1,2 | | b | d | bc,cd | head,left,destination | 2,1 | Scenario: Bicycle - Modes when starting on forward oneway diff --git a/3party/osrm/osrm-backend/features/bicycle/names.feature b/3party/osrm/osrm-backend/features/bicycle/names.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/oneway.feature b/3party/osrm/osrm-backend/features/bicycle/oneway.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/pushing.feature b/3party/osrm/osrm-backend/features/bicycle/pushing.feature old mode 100644 new mode 100755 index 7cb5400bca..5741fb1c0a --- a/3party/osrm/osrm-backend/features/bicycle/pushing.feature +++ b/3party/osrm/osrm-backend/features/bicycle/pushing.feature @@ -32,7 +32,7 @@ Feature: Bike - Accessability of different way types | primary | -1 | foot | bike | | pedestrian | -1 | foot | foot | - @square + @square Scenario: Bike - Push bikes on pedestrian areas Given the node map | x | | @@ -62,7 +62,7 @@ Feature: Bike - Accessability of different way types | motorway | yes | foot | | | runway | | | | | runway | yes | foot | foot | - + @todo Scenario: Bike - Pushing bikes on ways with foot=yes in one direction Then routability should be @@ -72,20 +72,20 @@ Feature: Bike - Accessability of different way types | motorway | | yes | | foot | @construction - Scenario: Bike - Don't allow routing on ways still under construction + Scenario: Bike - Don't allow routing on ways still under construction Then routability should be | highway | foot | bicycle | bothw | | primary | | | x | | construction | | | | | construction | yes | | | | construction | | yes | | - + @roundabout Scenario: Bike - Don't push bikes against oneway flow on roundabouts Then routability should be | junction | forw | backw | | roundabout | x | | - + Scenario: Bike - Instructions when pushing bike on oneways Given the node map | a | b | | diff --git a/3party/osrm/osrm-backend/features/bicycle/ref.feature b/3party/osrm/osrm-backend/features/bicycle/ref.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/restrictions.feature b/3party/osrm/osrm-backend/features/bicycle/restrictions.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/roundabout.feature b/3party/osrm/osrm-backend/features/bicycle/roundabout.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/stop_area.feature b/3party/osrm/osrm-backend/features/bicycle/stop_area.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/surface.feature b/3party/osrm/osrm-backend/features/bicycle/surface.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/train.feature b/3party/osrm/osrm-backend/features/bicycle/train.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/turn_penalty.feature b/3party/osrm/osrm-backend/features/bicycle/turn_penalty.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/bicycle/way.feature b/3party/osrm/osrm-backend/features/bicycle/way.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/car/access.feature b/3party/osrm/osrm-backend/features/car/access.feature old mode 100644 new mode 100755 index 37dfed4c60..5fd56f3951 --- a/3party/osrm/osrm-backend/features/car/access.feature +++ b/3party/osrm/osrm-backend/features/car/access.feature @@ -93,6 +93,7 @@ Feature: Car - Restricted access | private | | | agricultural | | | forestry | | + | psv | | | some_tag | x | @@ -106,6 +107,7 @@ Feature: Car - Restricted access | private | | | agricultural | | | forestry | | + | psv | | | some_tag | x | Scenario: Car - Access tags on both node and way diff --git a/3party/osrm/osrm-backend/features/car/barrier.feature b/3party/osrm/osrm-backend/features/car/barrier.feature old mode 100644 new mode 100755 index e637049860..7c89688c9e --- a/3party/osrm/osrm-backend/features/car/barrier.feature +++ b/3party/osrm/osrm-backend/features/car/barrier.feature @@ -10,6 +10,7 @@ Feature: Car - Barriers | | x | | bollard | | | gate | x | + | lift_gate | x | | cattle_grid | x | | border_control | x | | toll_booth | x | diff --git a/3party/osrm/osrm-backend/features/car/bridge.feature b/3party/osrm/osrm-backend/features/car/bridge.feature new file mode 100755 index 0000000000..41dc10bdb6 --- /dev/null +++ b/3party/osrm/osrm-backend/features/car/bridge.feature @@ -0,0 +1,47 @@ +@routing @car @bridge +Feature: Car - Handle movable bridge + + Background: + Given the profile "car" + + Scenario: Car - Use a ferry route + Given the node map + | a | b | c | | | + | | | d | | | + | | | e | f | g | + + And the ways + | nodes | highway | bridge | bicycle | + | abc | primary | | | + | cde | | movable | yes | + | efg | primary | | | + + When I route I should get + | from | to | route | modes | + | a | g | abc,cde,efg | 1,3,1 | + | b | f | abc,cde,efg | 1,3,1 | + | e | c | cde | 3 | + | e | b | cde,abc | 3,1 | + | e | a | cde,abc | 3,1 | + | c | e | cde | 3 | + | c | f | cde,efg | 3,1 | + | c | g | cde,efg | 3,1 | + + Scenario: Car - Properly handle durations + Given the node map + | a | b | c | | | + | | | d | | | + | | | e | f | g | + + And the ways + | nodes | highway | bridge | duration | + | abc | primary | | | + | cde | | movable | 00:05:00 | + | efg | primary | | | + + When I route I should get + | from | to | route | modes | speed | + | a | g | abc,cde,efg | 1,3,1 | 6 km/h | + | b | f | abc,cde,efg | 1,3,1 | 4 km/h | + | c | e | cde | 3 | 2 km/h | + | e | c | cde | 3 | 2 km/h | diff --git a/3party/osrm/osrm-backend/features/car/destination.feature b/3party/osrm/osrm-backend/features/car/destination.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/car/ferry.feature b/3party/osrm/osrm-backend/features/car/ferry.feature old mode 100644 new mode 100755 index 0e1fe98e52..eb245598ab --- a/3party/osrm/osrm-backend/features/car/ferry.feature +++ b/3party/osrm/osrm-backend/features/car/ferry.feature @@ -27,7 +27,7 @@ Feature: Car - Handle ferry routes | c | f | cde,efg | 2,1 | | c | g | cde,efg | 2,1 | - Scenario: Car - Properly handle durations + Scenario: Car - Properly handle simple durations Given the node map | a | b | c | | | | | | d | | | @@ -41,7 +41,26 @@ Feature: Car - Handle ferry routes When I route I should get | from | to | route | modes | speed | - | a | g | abc,cde,efg | 1,2,1 | 24 km/h | - | b | f | abc,cde,efg | 1,2,1 | 19 km/h | + | a | g | abc,cde,efg | 1,2,1 | 26 km/h | + | b | f | abc,cde,efg | 1,2,1 | 20 km/h | + | c | e | cde | 2 | 12 km/h | + | e | c | cde | 2 | 12 km/h | + + Scenario: Car - Properly handle ISO 8601 durations + Given the node map + | a | b | c | | | + | | | d | | | + | | | e | f | g | + + And the ways + | nodes | highway | route | duration | + | abc | primary | | | + | cde | | ferry | PT1M | + | efg | primary | | | + + When I route I should get + | from | to | route | modes | speed | + | a | g | abc,cde,efg | 1,2,1 | 26 km/h | + | b | f | abc,cde,efg | 1,2,1 | 20 km/h | | c | e | cde | 2 | 12 km/h | | e | c | cde | 2 | 12 km/h | diff --git a/3party/osrm/osrm-backend/features/car/link.feature b/3party/osrm/osrm-backend/features/car/link.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/car/maxspeed.feature b/3party/osrm/osrm-backend/features/car/maxspeed.feature old mode 100644 new mode 100755 index 4a548020c4..781f4c6173 --- a/3party/osrm/osrm-backend/features/car/maxspeed.feature +++ b/3party/osrm/osrm-backend/features/car/maxspeed.feature @@ -8,19 +8,25 @@ OSRM will use 4/5 of the projected free-flow speed. Scenario: Car - Respect maxspeeds when lower that way type speed Given the node map - | a | b | c | d | + | a | b | c | d | e | f | g | And the ways - | nodes | highway | maxspeed | - | ab | trunk | | - | bc | trunk | 60 | - | cd | trunk | FR:urban | + | nodes | highway | maxspeed | + | ab | trunk | | + | bc | trunk | 60 | + | cd | trunk | FR:urban | + | de | trunk | CH:rural | + | ef | trunk | CH:trunk | + | fg | trunk | CH:motorway | When I route I should get - | from | to | route | speed | - | a | b | ab | 67 km/h | - | b | c | bc | 48 km/h +- 1 | - | c | d | cd | 40 km/h | + | from | to | route | speed | + | a | b | ab | 78 km/h | + | b | c | bc | 59 km/h +- 1 | + | c | d | cd | 50 km/h | + | d | e | de | 75 km/h | + | e | f | ef | 90 km/h | + | f | g | fg | 105 km/h | Scenario: Car - Do not ignore maxspeed when higher than way speed Given the node map @@ -34,22 +40,22 @@ OSRM will use 4/5 of the projected free-flow speed. When I route I should get | from | to | route | speed | - | a | b | ab | 20 km/h | - | b | c | bc | 72 km/h +- 1 | - | c | d | cd | 40 km/h | + | a | b | ab | 31 km/h | + | b | c | bc | 83 km/h +- 1 | + | c | d | cd | 50 km/h | Scenario: Car - Forward/backward maxspeed Given a grid size of 100 meters Then routability should be | highway | maxspeed | maxspeed:forward | maxspeed:backward | forw | backw | - | primary | | | | 51 km/h | 51 km/h | - | primary | 60 | | | 48 km/h | 48 km/h | - | primary | | 60 | | 48 km/h | 51 km/h | - | primary | | | 60 | 51 km/h | 48 km/h | - | primary | 15 | 60 | | 48 km/h | 12 km/h | - | primary | 15 | | 60 | 12 km/h | 48 km/h | - | primary | 15 | 30 | 60 | 24 km/h | 48 km/h | + | primary | | | | 65 km/h | 65 km/h | + | primary | 60 | | | 60 km/h | 60 km/h | + | primary | | 60 | | 60 km/h | 65 km/h | + | primary | | | 60 | 65 km/h | 60 km/h | + | primary | 15 | 60 | | 60 km/h | 23 km/h | + | primary | 15 | | 60 | 23 km/h | 60 km/h | + | primary | 15 | 30 | 60 | 34 km/h | 60 km/h | Scenario: Car - Maxspeed should not allow routing on unroutable ways Then routability should be @@ -67,3 +73,23 @@ OSRM will use 4/5 of the projected free-flow speed. | runway | | | 100 | | | | | runway | | | | 100 | | | | runway | | | | | 100 | | + + Scenario: Car - Too narrow streets should be ignored or incur a penalty + Then routability should be + + | highway | maxspeed | width | maxspeed:forward | maxspeed:backward | forw | backw | + | primary | | | | | 63 km/h | 63 km/h | + | primary | | 3 | | | 32 km/h | 32 km/h | + | primary | 60 | | | | 59 km/h | 59 km/h | + | primary | 60 | 3 | | | 30 km/h | 30 km/h | + | primary | | | 60 | | 59 km/h | 63 km/h | + | primary | | 3 | 60 | | 30 km/h | 32 km/h | + | primary | | | | 60 | 63 km/h | 59 km/h | + | primary | | 3 | | 60 | 32 km/h | 30 km/h | + | primary | 15 | | 60 | | 59 km/h | 23 km/h | + | primary | 15 | 3 | 60 | | 30 km/h | 7 km/h | + | primary | 15 | | | 60 | 23 km/h | 59 km/h | + | primary | 15 | 3 | | 60 | 7 km/h | 30 km/h | + | primary | 15 | | 30 | 60 | 34 km/h | 59 km/h | + | primary | 15 | 3 | 30 | 60 | 15 km/h | 30 km/h | + diff --git a/3party/osrm/osrm-backend/features/car/names.feature b/3party/osrm/osrm-backend/features/car/names.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/car/oneway.feature b/3party/osrm/osrm-backend/features/car/oneway.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/car/permissive.feature b/3party/osrm/osrm-backend/features/car/permissive.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/car/restrictions.feature b/3party/osrm/osrm-backend/features/car/restrictions.feature old mode 100644 new mode 100755 index a54f054baf..f381f2f8c0 --- a/3party/osrm/osrm-backend/features/car/restrictions.feature +++ b/3party/osrm/osrm-backend/features/car/restrictions.feature @@ -380,3 +380,4 @@ Feature: Car - Turn restrictions | from | to | route | | a | b | ax,xy,yb | | b | a | yb,xy,ax | + diff --git a/3party/osrm/osrm-backend/features/car/roundabout.feature b/3party/osrm/osrm-backend/features/car/roundabout.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/car/shuttle_train.feature b/3party/osrm/osrm-backend/features/car/shuttle_train.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/car/speed.feature b/3party/osrm/osrm-backend/features/car/speed.feature old mode 100644 new mode 100755 index 5682f31949..a81baeb85a --- a/3party/osrm/osrm-backend/features/car/speed.feature +++ b/3party/osrm/osrm-backend/features/car/speed.feature @@ -8,17 +8,17 @@ Feature: Car - speeds Scenario: Car - speed of various way types Then routability should be | highway | oneway | bothw | - | motorway | no | 72 km/h | - | motorway_link | no | 36 km/h | - | trunk | no | 67 km/h +- 1 | - | trunk_link | no | 32 km/h +- 1 | - | primary | no | 52 km/h +- 1 | - | primary_link | no | 24 km/h | - | secondary | no | 43 km/h +- 1 | - | secondary_link | no | 20 km/h | - | tertiary | no | 32 km/h | - | tertiary_link | no | 16 km/h | - | unclassified | no | 20 km/h | - | residential | no | 20 km/h | - | living_street | no | 8 km/h | - | service | no | 12 km/h | + | motorway | no | 82 km/h | + | motorway_link | no | 47 km/h | + | trunk | no | 79 km/h +- 1 | + | trunk_link | no | 43 km/h +- 1 | + | primary | no | 63 km/h +- 1 | + | primary_link | no | 34 km/h | + | secondary | no | 54 km/h +- 1 | + | secondary_link | no | 31 km/h | + | tertiary | no | 43 km/h | + | tertiary_link | no | 26 km/h | + | unclassified | no | 31 km/h | + | residential | no | 31 km/h | + | living_street | no | 18 km/h | + | service | no | 23 km/h | diff --git a/3party/osrm/osrm-backend/features/car/surface.feature b/3party/osrm/osrm-backend/features/car/surface.feature old mode 100644 new mode 100755 index cd31acc983..5dd4ed66db --- a/3party/osrm/osrm-backend/features/car/surface.feature +++ b/3party/osrm/osrm-backend/features/car/surface.feature @@ -26,7 +26,7 @@ Feature: Car - Surfaces | trunk | very_horrible | x | | trunk | impassable | | | trunk | nonsense | x | - + Scenario: Car - Routabiliy of surface tags Then routability should be | highway | surface | bothw | @@ -64,64 +64,64 @@ Feature: Car - Surfaces Scenario: Car - Surface should reduce speed Then routability should be | highway | oneway | surface | forw | backw | - | motorway | no | | 72 km/h +-1 | 72 km/h +-1 | - | motorway | no | asphalt | 72 km/h +-1 | 72 km/h +-1 | - | motorway | no | concrete | 72 km/h +-1 | 72 km/h +-1 | - | motorway | no | concrete:plates | 72 km/h +-1 | 72 km/h +-1 | - | motorway | no | concrete:lanes | 72 km/h +-1 | 72 km/h +-1 | - | motorway | no | paved | 72 km/h +-1 | 72 km/h +-1 | - | motorway | no | cement | 65 km/h +-1 | 65 km/h +-1 | - | motorway | no | compacted | 65 km/h +-1 | 65 km/h +-1 | - | motorway | no | fine_gravel | 65 km/h +-1 | 65 km/h +-1 | - | motorway | no | paving_stones | 48 km/h +-1 | 48 km/h +-1 | - | motorway | no | metal | 48 km/h +-1 | 48 km/h +-1 | - | motorway | no | bricks | 48 km/h +-1 | 48 km/h +-1 | - | motorway | no | grass | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | wood | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | sett | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | grass_paver | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | gravel | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | unpaved | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | ground | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | dirt | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | pebblestone | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | tartan | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | cobblestone | 24 km/h +-1 | 24 km/h +-1 | - | motorway | no | clay | 24 km/h +-1 | 24 km/h +-1 | - | motorway | no | earth | 16 km/h +-1 | 16 km/h +-1 | - | motorway | no | stone | 16 km/h +-1 | 16 km/h +-1 | - | motorway | no | rocky | 16 km/h +-1 | 16 km/h +-1 | - | motorway | no | sand | 16 km/h +-1 | 16 km/h +-1 | + | motorway | no | | 80 km/h +-1 | 80 km/h +-1 | + | motorway | no | asphalt | 80 km/h +-1 | 80 km/h +-1 | + | motorway | no | concrete | 80 km/h +-1 | 80 km/h +-1 | + | motorway | no | concrete:plates | 80 km/h +-1 | 80 km/h +-1 | + | motorway | no | concrete:lanes | 80 km/h +-1 | 80 km/h +-1 | + | motorway | no | paved | 80 km/h +-1 | 80 km/h +-1 | + | motorway | no | cement | 72 km/h +-1 | 72 km/h +-1 | + | motorway | no | compacted | 72 km/h +-1 | 72 km/h +-1 | + | motorway | no | fine_gravel | 72 km/h +-1 | 72 km/h +-1 | + | motorway | no | paving_stones | 60 km/h +-1 | 60 km/h +-1 | + | motorway | no | metal | 60 km/h +-1 | 60 km/h +-1 | + | motorway | no | bricks | 60 km/h +-1 | 60 km/h +-1 | + | motorway | no | grass | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | wood | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | sett | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | grass_paver | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | gravel | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | unpaved | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | ground | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | dirt | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | pebblestone | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | tartan | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | cobblestone | 34 km/h +-1 | 34 km/h +-1 | + | motorway | no | clay | 34 km/h +-1 | 34 km/h +-1 | + | motorway | no | earth | 26 km/h +-1 | 26 km/h +-1 | + | motorway | no | stone | 26 km/h +-1 | 26 km/h +-1 | + | motorway | no | rocky | 26 km/h +-1 | 26 km/h +-1 | + | motorway | no | sand | 26 km/h +-1 | 26 km/h +-1 | Scenario: Car - Tracktypes should reduce speed Then routability should be | highway | oneway | tracktype | forw | backw | - | motorway | no | | 72 km/h +-1 | 72 km/h +-1 | - | motorway | no | grade1 | 48 km/h +-1 | 48 km/h +-1 | - | motorway | no | grade2 | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | grade3 | 24 km/h +-1 | 24 km/h +-1 | - | motorway | no | grade4 | 20 km/h +-1 | 20 km/h +-1 | - | motorway | no | grade5 | 16 km/h +-1 | 16 km/h +-1 | + | motorway | no | | 80 km/h +-1 | 80 km/h +-1 | + | motorway | no | grade1 | 60 km/h +-1 | 60 km/h +-1 | + | motorway | no | grade2 | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | grade3 | 34 km/h +-1 | 34 km/h +-1 | + | motorway | no | grade4 | 31 km/h +-1 | 31 km/h +-1 | + | motorway | no | grade5 | 26 km/h +-1 | 26 km/h +-1 | Scenario: Car - Smoothness should reduce speed Then routability should be | highway | oneway | smoothness | forw | backw | - | motorway | no | | 72 km/h +-1 | 72 km/h +-1 | - | motorway | no | intermediate | 65 km/h +-1 | 65 km/h +-1 | - | motorway | no | bad | 32 km/h +-1 | 32 km/h +-1 | - | motorway | no | very_bad | 16 km/h +-1 | 16 km/h +-1 | - | motorway | no | horrible | 8 km/h +-1 | 8 km/h +-1 | - | motorway | no | very_horrible | 4 km/h +-1 | 4 km/h +-1 | + | motorway | no | | 80 km/h +-1 | 80 km/h +-1 | + | motorway | no | intermediate | 72 km/h +-1 | 72 km/h +-1 | + | motorway | no | bad | 42 km/h +-1 | 42 km/h +-1 | + | motorway | no | very_bad | 26 km/h +-1 | 26 km/h +-1 | + | motorway | no | horrible | 18 km/h +-1 | 18 km/h +-1 | + | motorway | no | very_horrible | 15 km/h +-1 | 15 km/h +-1 | Scenario: Car - Combination of surface tags should use lowest speed Then routability should be | highway | oneway | tracktype | surface | smoothness | backw | forw | - | motorway | no | | | | 72 km/h | 72 km/h | - | service | no | grade1 | asphalt | excellent | 12 km/h | 12 km/h | - | motorway | no | grade5 | asphalt | excellent | 16 km/h | 16 km/h | - | motorway | no | grade1 | mud | excellent | 8 km/h | 8 km/h | - | motorway | no | grade1 | asphalt | very_horrible | 4 km/h | 4 km/h | - | service | no | grade5 | mud | very_horrible | 4 km/h | 4 km/h | + | motorway | no | | | | 80 km/h | 80 km/h | + | service | no | grade1 | asphalt | excellent | 23 km/h | 23 km/h | + | motorway | no | grade5 | asphalt | excellent | 26 km/h | 26 km/h | + | motorway | no | grade1 | mud | excellent | 18 km/h | 18 km/h | + | motorway | no | grade1 | asphalt | very_horrible | 15 km/h | 15 km/h | + | service | no | grade5 | mud | very_horrible | 15 km/h | 15 km/h | Scenario: Car - Surfaces should not affect oneway direction Then routability should be @@ -138,3 +138,4 @@ Feature: Car - Surfaces | primary | -1 | grade1 | excellent | asphalt | | x | | primary | -1 | grade5 | very_bad | mud | | x | | primary | -1 | nonsense | nonsense | nonsense | | x | + diff --git a/3party/osrm/osrm-backend/features/car/way.feature b/3party/osrm/osrm-backend/features/car/way.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/access.feature b/3party/osrm/osrm-backend/features/foot/access.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/access_node.feature b/3party/osrm/osrm-backend/features/foot/access_node.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/area.feature b/3party/osrm/osrm-backend/features/foot/area.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/barrier.feature b/3party/osrm/osrm-backend/features/foot/barrier.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/ferry.feature b/3party/osrm/osrm-backend/features/foot/ferry.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/maxspeed.feature b/3party/osrm/osrm-backend/features/foot/maxspeed.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/names.feature b/3party/osrm/osrm-backend/features/foot/names.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/oneway.feature b/3party/osrm/osrm-backend/features/foot/oneway.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/ref.feature b/3party/osrm/osrm-backend/features/foot/ref.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/restrictions.feature b/3party/osrm/osrm-backend/features/foot/restrictions.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/roundabout.feature b/3party/osrm/osrm-backend/features/foot/roundabout.feature old mode 100644 new mode 100755 index 7808c46e88..5aa9860fb3 --- a/3party/osrm/osrm-backend/features/foot/roundabout.feature +++ b/3party/osrm/osrm-backend/features/foot/roundabout.feature @@ -3,12 +3,12 @@ Feature: Roundabout Instructions Background: Given the profile "foot" - + @todo Scenario: Foot - Roundabout instructions # You can walk in both directions on a roundabout, bu the normal roundabout instructions don't # make sense when you're going the opposite way around the roundabout. - + Given the node map | | | v | | | | | | d | | | diff --git a/3party/osrm/osrm-backend/features/foot/surface.feature b/3party/osrm/osrm-backend/features/foot/surface.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/foot/way.feature b/3party/osrm/osrm-backend/features/foot/way.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/locate/locate.feature b/3party/osrm/osrm-backend/features/locate/locate.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/nearest/pick.feature b/3party/osrm/osrm-backend/features/nearest/pick.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/nearest/projection.feature b/3party/osrm/osrm-backend/features/nearest/projection.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/options/extract/files.feature b/3party/osrm/osrm-backend/features/options/extract/files.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/options/extract/help.feature b/3party/osrm/osrm-backend/features/options/extract/help.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/options/extract/invalid.feature b/3party/osrm/osrm-backend/features/options/extract/invalid.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/options/extract/version.feature b/3party/osrm/osrm-backend/features/options/extract/version.feature old mode 100644 new mode 100755 index 1f2ef91fdc..0dd5f65886 --- a/3party/osrm/osrm-backend/features/options/extract/version.feature +++ b/3party/osrm/osrm-backend/features/options/extract/version.feature @@ -6,7 +6,7 @@ Feature: osrm-extract command line options: version Background: Given the profile "testbot" - + Scenario: osrm-extract - Version, short When I run "osrm-extract --v" Then stderr should be empty diff --git a/3party/osrm/osrm-backend/features/options/prepare/files.feature b/3party/osrm/osrm-backend/features/options/prepare/files.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/options/prepare/help.feature b/3party/osrm/osrm-backend/features/options/prepare/help.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/options/prepare/invalid.feature b/3party/osrm/osrm-backend/features/options/prepare/invalid.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/options/prepare/version.feature b/3party/osrm/osrm-backend/features/options/prepare/version.feature old mode 100644 new mode 100755 index 196409b9bd..7a821c626e --- a/3party/osrm/osrm-backend/features/options/prepare/version.feature +++ b/3party/osrm/osrm-backend/features/options/prepare/version.feature @@ -6,7 +6,7 @@ Feature: osrm-prepare command line options: version Background: Given the profile "testbot" - + Scenario: osrm-prepare - Version, short When I run "osrm-prepare --v" Then stderr should be empty diff --git a/3party/osrm/osrm-backend/features/options/routed/files.feature b/3party/osrm/osrm-backend/features/options/routed/files.feature old mode 100644 new mode 100755 index 9be77f775e..15ce679eb3 --- a/3party/osrm/osrm-backend/features/options/routed/files.feature +++ b/3party/osrm/osrm-backend/features/options/routed/files.feature @@ -3,7 +3,7 @@ Feature: osrm-routed command line options: files # Normally when launching osrm-routed, it will keep running as a server until it's shut down. # For testing program options, the --trial option is used, which causes osrm-routed to quit # immediately after initialization. This makes testing easier and faster. -# +# # The {prepared_base} part of the options to osrm-routed will be expanded to the actual base path of # the prepared input file. diff --git a/3party/osrm/osrm-backend/features/options/routed/help.feature b/3party/osrm/osrm-backend/features/options/routed/help.feature old mode 100644 new mode 100755 index 9603c40dde..c0fca4717c --- a/3party/osrm/osrm-backend/features/options/routed/help.feature +++ b/3party/osrm/osrm-backend/features/options/routed/help.feature @@ -24,8 +24,10 @@ Feature: osrm-routed command line options: help And stdout should contain "--ip" And stdout should contain "--port" And stdout should contain "--threads" - And stdout should contain "--sharedmemory" - And stdout should contain 22 lines + And stdout should contain "--shared-memory" + And stdout should contain "--max-table-size" + And stdout should contain "--max-matching-size" + And stdout should contain 26 lines And it should exit with code 0 Scenario: osrm-routed - Help, short @@ -48,8 +50,10 @@ Feature: osrm-routed command line options: help And stdout should contain "--ip" And stdout should contain "--port" And stdout should contain "--threads" - And stdout should contain "--sharedmemory" - And stdout should contain 22 lines + And stdout should contain "--shared-memory" + And stdout should contain "--max-table-size" + And stdout should contain "--max-matching-size" + And stdout should contain 26 lines And it should exit with code 0 Scenario: osrm-routed - Help, long @@ -72,6 +76,8 @@ Feature: osrm-routed command line options: help And stdout should contain "--ip" And stdout should contain "--port" And stdout should contain "--threads" - And stdout should contain "--sharedmemory" - And stdout should contain 22 lines + And stdout should contain "--shared-memory" + And stdout should contain "--max-table-size" + And stdout should contain "--max-matching-size" + And stdout should contain 26 lines And it should exit with code 0 diff --git a/3party/osrm/osrm-backend/features/options/routed/invalid.feature b/3party/osrm/osrm-backend/features/options/routed/invalid.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/options/routed/version.feature b/3party/osrm/osrm-backend/features/options/routed/version.feature old mode 100644 new mode 100755 index ea600c0646..b544e36e6e --- a/3party/osrm/osrm-backend/features/options/routed/version.feature +++ b/3party/osrm/osrm-backend/features/options/routed/version.feature @@ -6,7 +6,7 @@ Feature: osrm-routed command line options: version Background: Given the profile "testbot" - + Scenario: osrm-routed - Version, short When I run "osrm-routed --v" Then stderr should be empty diff --git a/3party/osrm/osrm-backend/features/step_definitions/data.rb b/3party/osrm/osrm-backend/features/step_definitions/data.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/step_definitions/distance_matrix.rb b/3party/osrm/osrm-backend/features/step_definitions/distance_matrix.rb new file mode 100755 index 0000000000..f85bdcc073 --- /dev/null +++ b/3party/osrm/osrm-backend/features/step_definitions/distance_matrix.rb @@ -0,0 +1,56 @@ +When /^I request a travel time matrix I should get$/ do |table| + + no_route = 2147483647 # MAX_INT + + raise "*** Top-left cell of matrix table must be empty" unless table.headers[0]=="" + + nodes = [] + column_headers = table.headers[1..-1] + row_headers = table.rows.map { |h| h.first } + unless column_headers==row_headers + raise "*** Column and row headers must match in matrix table, got #{column_headers.inspect} and #{row_headers.inspect}" + end + column_headers.each do |node_name| + node = find_node_by_name(node_name) + raise "*** unknown node '#{node_name}" unless node + nodes << node + end + + reprocess + actual = [] + actual << table.headers + OSRMLoader.load(self,"#{prepared_file}.osrm") do + + # compute matrix + params = @query_params + response = request_table nodes, params + if response.body.empty? == false + json = JSON.parse response.body + result = json['distance_table'] + end + + # compare actual and expected result, one row at a time + table.rows.each_with_index do |row,ri| + + # fuzzy match + ok = true + 0.upto(nodes.size-1) do |i| + if FuzzyMatch.match result[ri][i], row[i+1] + result[ri][i] = row[i+1] + elsif row[i+1]=="" and result[ri][i]==no_route + result[ri][i] = "" + else + result[ri][i] = result[ri][i].to_s + ok = false + end + end + + # add row header + r = [row[0],result[ri]].flatten + + # store row for comparison + actual << r + end + end + table.routing_diff! actual +end diff --git a/3party/osrm/osrm-backend/features/step_definitions/locate.rb b/3party/osrm/osrm-backend/features/step_definitions/locate.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/step_definitions/matching.rb b/3party/osrm/osrm-backend/features/step_definitions/matching.rb new file mode 100755 index 0000000000..3f3181f64f --- /dev/null +++ b/3party/osrm/osrm-backend/features/step_definitions/matching.rb @@ -0,0 +1,96 @@ +When /^I match I should get$/ do |table| + reprocess + actual = [] + OSRMLoader.load(self,"#{prepared_file}.osrm") do + table.hashes.each_with_index do |row,ri| + if row['request'] + got = {'request' => row['request'] } + response = request_url row['request'] + else + params = @query_params + trace = [] + timestamps = [] + if row['trace'] + row['trace'].each_char do |n| + node = find_node_by_name(n.strip) + raise "*** unknown waypoint node '#{n.strip}" unless node + trace << node + end + if row['timestamps'] + timestamps = row['timestamps'].split(" ").compact.map { |t| t.to_i} + end + got = {'trace' => row['trace'] } + response = request_matching trace, timestamps, params + else + raise "*** no trace" + end + end + + row.each_pair do |k,v| + if k =~ /param:(.*)/ + if v=='(nil)' + params[$1]=nil + elsif v!=nil + params[$1]=v + end + got[k]=v + end + end + + if response.body.empty? == false + json = JSON.parse response.body + end + + if table.headers.include? 'status' + got['status'] = json['status'].to_s + end + if table.headers.include? 'message' + got['message'] = json['status_message'] + end + if table.headers.include? '#' # comment column + got['#'] = row['#'] # copy value so it always match + end + + sub_matchings = [] + if response.code == "200" + if table.headers.include? 'matchings' + sub_matchings = json['matchings'].compact.map { |sub| sub['matched_points']} + end + end + + ok = true + encoded_result = "" + extended_target = "" + row['matchings'].split(',').each_with_index do |sub, sub_idx| + if sub_idx >= sub_matchings.length + ok = false + break + end + sub.length.times do |node_idx| + node = find_node_by_name(sub[node_idx]) + out_node = sub_matchings[sub_idx][node_idx] + if FuzzyMatch.match_location out_node, node + encoded_result += sub[node_idx] + extended_target += sub[node_idx] + else + encoded_result += "? [#{out_node[0]},#{out_node[1]}]" + extended_target += "#{sub[node_idx]} [#{node.lat},#{node.lon}]" + ok = false + end + end + end + if ok + got['matchings'] = row['matchings'] + got['timestamps'] = row['timestamps'] + else + got['matchings'] = encoded_result + row['matchings'] = extended_target + log_fail row,got, { 'matching' => {:query => @query, :response => response} } + end + + actual << got + end + end + table.routing_diff! actual +end + diff --git a/3party/osrm/osrm-backend/features/step_definitions/nearest.rb b/3party/osrm/osrm-backend/features/step_definitions/nearest.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/step_definitions/options.rb b/3party/osrm/osrm-backend/features/step_definitions/options.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/step_definitions/requests.rb b/3party/osrm/osrm-backend/features/step_definitions/requests.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/step_definitions/routability.rb b/3party/osrm/osrm-backend/features/step_definitions/routability.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/step_definitions/routing.rb b/3party/osrm/osrm-backend/features/step_definitions/routing.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/step_definitions/timestamp.rb b/3party/osrm/osrm-backend/features/step_definitions/timestamp.rb old mode 100644 new mode 100755 index 77a614c964..df456152be --- a/3party/osrm/osrm-backend/features/step_definitions/timestamp.rb +++ b/3party/osrm/osrm-backend/features/step_definitions/timestamp.rb @@ -3,5 +3,5 @@ Then /^I should get a valid timestamp/ do step "response should be valid JSON" step "response should be well-formed" expect(@json['timestamp'].class).to eq(String) - expect(@json['timestamp']).to eq(OSM_TIMESTAMP) + expect(@json['timestamp']).to eq("2000-01-01T00:00:00Z") end diff --git a/3party/osrm/osrm-backend/features/stress/launch.feature b/3party/osrm/osrm-backend/features/stress/launch.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/config.rb b/3party/osrm/osrm-backend/features/support/config.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/cucumber.rb b/3party/osrm/osrm-backend/features/support/cucumber.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/data.rb b/3party/osrm/osrm-backend/features/support/data.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/env.rb b/3party/osrm/osrm-backend/features/support/env.rb old mode 100644 new mode 100755 index a01341dd6a..f9a4fe4367 --- a/3party/osrm/osrm-backend/features/support/env.rb +++ b/3party/osrm/osrm-backend/features/support/env.rb @@ -64,6 +64,19 @@ unless File.exists? TEST_FOLDER raise "*** Test folder #{TEST_FOLDER} doesn't exist." end +def verify_osrm_is_not_running + if OSRMLoader::OSRMBaseLoader.new.osrm_up? + raise "*** osrm-routed is already running." + end +end + +def verify_existance_of_binaries + ["osrm-extract", "osrm-prepare", "osrm-routed"].each do |bin| + unless File.exists? "#{BIN_PATH}/#{bin}" + raise "*** #{BIN_PATH}/#{bin} is missing. Build failed?" + end + end +end if ENV['OS']=~/Windows.*/ then EXE='.exe' @@ -74,10 +87,9 @@ else end AfterConfiguration do |config| - if OSRMLoader::OSRMBaseLoader.new.osrm_up? - raise "*** osrm-routed is already running." - end clear_log_files + verify_osrm_is_not_running + verify_existance_of_binaries end at_exit do diff --git a/3party/osrm/osrm-backend/features/support/exceptions.rb b/3party/osrm/osrm-backend/features/support/exceptions.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/file.rb b/3party/osrm/osrm-backend/features/support/file.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/fuzzy.rb b/3party/osrm/osrm-backend/features/support/fuzzy.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/hash.rb b/3party/osrm/osrm-backend/features/support/hash.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/hooks.rb b/3party/osrm/osrm-backend/features/support/hooks.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/launch.rb b/3party/osrm/osrm-backend/features/support/launch.rb old mode 100644 new mode 100755 index f6667fad6d..d8d23aeaa6 --- a/3party/osrm/osrm-backend/features/support/launch.rb +++ b/3party/osrm/osrm-backend/features/support/launch.rb @@ -1,5 +1,6 @@ require 'socket' require 'open3' +require 'json' # Only one isntance of osrm-routed is ever launched, to avoid collisions. # The default is to keep osrm-routed running and load data with datastore. @@ -117,7 +118,7 @@ class OSRMLoader def osrm_up return if osrm_up? - @@pid = Process.spawn("#{BIN_PATH}/osrm-routed --sharedmemory=1 --port #{OSRM_PORT}",:out=>OSRM_ROUTED_LOG_FILE, :err=>OSRM_ROUTED_LOG_FILE) + @@pid = Process.spawn("#{BIN_PATH}/osrm-routed --shared-memory=1 --port #{OSRM_PORT}",:out=>OSRM_ROUTED_LOG_FILE, :err=>OSRM_ROUTED_LOG_FILE) Process.detach(@@pid) # avoid zombie processes end end diff --git a/3party/osrm/osrm-backend/features/support/locate.rb b/3party/osrm/osrm-backend/features/support/locate.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/log.rb b/3party/osrm/osrm-backend/features/support/log.rb old mode 100644 new mode 100755 index e480bdb0c4..8e6f9c1463 --- a/3party/osrm/osrm-backend/features/support/log.rb +++ b/3party/osrm/osrm-backend/features/support/log.rb @@ -6,7 +6,7 @@ LOG_FILE = 'fail.log' def clear_log_files Dir.chdir TEST_FOLDER do - # emptying existing files, rather than deleting and writing new ones makes it + # emptying existing files, rather than deleting and writing new ones makes it # easier to use tail -f from the command line `echo '' > #{OSRM_ROUTED_LOG_FILE}` `echo '' > #{PREPROCESS_LOG_FILE}` diff --git a/3party/osrm/osrm-backend/features/support/match.rb b/3party/osrm/osrm-backend/features/support/match.rb new file mode 100755 index 0000000000..bf51189a40 --- /dev/null +++ b/3party/osrm/osrm-backend/features/support/match.rb @@ -0,0 +1,26 @@ +require 'net/http' + +HOST = "http://127.0.0.1:#{OSRM_PORT}" + +def request_matching trace=[], timestamps=[], options={} + defaults = { 'output' => 'json' } + locs = trace.compact.map { |w| "loc=#{w.lat},#{w.lon}" } + ts = timestamps.compact.map { |t| "t=#{t}" } + if ts.length > 0 + trace_params = locs.zip(ts).map { |a| a.join('&')} + else + trace_params = locs + end + params = (trace_params + defaults.merge(options).to_param).join('&') + params = nil if params=="" + uri = URI.parse ["#{HOST}/match", params].compact.join('?') + @query = uri.to_s + Timeout.timeout(OSRM_TIMEOUT) do + Net::HTTP.get_response uri + end +rescue Errno::ECONNREFUSED => e + raise "*** osrm-routed is not running." +rescue Timeout::Error + raise "*** osrm-routed did not respond." +end + diff --git a/3party/osrm/osrm-backend/features/support/nearest.rb b/3party/osrm/osrm-backend/features/support/nearest.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/osm_parser.rb b/3party/osrm/osrm-backend/features/support/osm_parser.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/osmlib.rb b/3party/osrm/osrm-backend/features/support/osmlib.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/support/route.rb b/3party/osrm/osrm-backend/features/support/route.rb old mode 100644 new mode 100755 index 745edc0fdb..a8c78227ed --- a/3party/osrm/osrm-backend/features/support/route.rb +++ b/3party/osrm/osrm-backend/features/support/route.rb @@ -43,6 +43,11 @@ def request_route waypoints, params={} request_path "viaroute", waypoints, defaults.merge(params) end +def request_table waypoints, params={} + defaults = { 'output' => 'json' } + request_path "table", waypoints, defaults.merge(params) +end + def got_route? response if response.code == "200" && !response.body.empty? json = JSON.parse response.body diff --git a/3party/osrm/osrm-backend/features/support/run.rb b/3party/osrm/osrm-backend/features/support/run.rb old mode 100644 new mode 100755 index 0e64b93de5..42dc597a15 --- a/3party/osrm/osrm-backend/features/support/run.rb +++ b/3party/osrm/osrm-backend/features/support/run.rb @@ -4,20 +4,20 @@ def run_bin bin, options if opt.include? '{osm_base}' raise "*** {osm_base} is missing" unless osm_file - opt.gsub! "{osm_base}", "#{osm_file}" + opt.gsub! "{osm_base}", "#{osm_file}" end if opt.include? '{extracted_base}' raise "*** {extracted_base} is missing" unless extracted_file - opt.gsub! "{extracted_base}", "#{extracted_file}" + opt.gsub! "{extracted_base}", "#{extracted_file}" end if opt.include? '{prepared_base}' raise "*** {prepared_base} is missing" unless prepared_file - opt.gsub! "{prepared_base}", "#{prepared_file}" + opt.gsub! "{prepared_base}", "#{prepared_file}" end if opt.include? '{profile}' - opt.gsub! "{profile}", "#{PROFILES_PATH}/#{@profile}.lua" + opt.gsub! "{profile}", "#{PROFILES_PATH}/#{@profile}.lua" end cmd = "#{QQ}#{BIN_PATH}/#{bin}#{EXE}#{QQ} #{opt} 2>error.log" diff --git a/3party/osrm/osrm-backend/features/support/shortcuts.rb b/3party/osrm/osrm-backend/features/support/shortcuts.rb old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/bad.feature b/3party/osrm/osrm-backend/features/testbot/bad.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/basic.feature b/3party/osrm/osrm-backend/features/testbot/basic.feature old mode 100644 new mode 100755 index 2b35d29a01..599b0628af --- a/3party/osrm/osrm-backend/features/testbot/basic.feature +++ b/3party/osrm/osrm-backend/features/testbot/basic.feature @@ -233,7 +233,7 @@ Feature: Basic Routing | d | a | abcd | | a | m | aeim | | m | a | aeim | - + Scenario: Testbot - Triangle challenge Given the node map | | | | d | diff --git a/3party/osrm/osrm-backend/features/testbot/bearing.feature b/3party/osrm/osrm-backend/features/testbot/bearing.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/bearing_param.feature b/3party/osrm/osrm-backend/features/testbot/bearing_param.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/bugs.feature b/3party/osrm/osrm-backend/features/testbot/bugs.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/compression.feature b/3party/osrm/osrm-backend/features/testbot/compression.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/datastore.feature b/3party/osrm/osrm-backend/features/testbot/datastore.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/distance.feature b/3party/osrm/osrm-backend/features/testbot/distance.feature old mode 100644 new mode 100755 index 1f777d24f4..55b5f64165 --- a/3party/osrm/osrm-backend/features/testbot/distance.feature +++ b/3party/osrm/osrm-backend/features/testbot/distance.feature @@ -145,7 +145,7 @@ Feature: Distance calculation | a | h | abcdefgh | 70m +-14 | Scenario: Geometric distances - Given a grid size of 1000 meters + Given a grid size of 100 meters Given the node map | v | w | y | a | b | c | d | | u | | | | | | e | @@ -184,30 +184,30 @@ Feature: Distance calculation When I route I should get | from | to | route | distance | - | x | a | xa | 3000m +-2 | - | x | b | xb | 3162m +-2 | - | x | c | xc | 3606m +-2 | - | x | d | xd | 4243m +-2 | - | x | e | xe | 3606m +-2 | - | x | f | xf | 3162m +-2 | - | x | g | xg | 3000m +-2 | - | x | h | xh | 3162m +-2 | - | x | i | xi | 3606m +-2 | - | x | j | xj | 4243m +-2 | - | x | k | xk | 3606m +-2 | - | x | l | xl | 3162m +-2 | - | x | m | xm | 3000m +-2 | - | x | n | xn | 3162m +-2 | - | x | o | xo | 3606m +-2 | - | x | p | xp | 4243m +-2 | - | x | q | xq | 3606m +-2 | - | x | r | xr | 3162m +-2 | - | x | s | xs | 3000m +-2 | - | x | t | xt | 3162m +-2 | - | x | u | xu | 3606m +-2 | - | x | v | xv | 4243m +-2 | - | x | w | xw | 3606m +-2 | - | x | y | xy | 3162m +-2 | + | x | a | xa | 300m +-2 | + | x | b | xb | 316m +-2 | + | x | c | xc | 360m +-2 | + | x | d | xd | 424m +-2 | + | x | e | xe | 360m +-2 | + | x | f | xf | 316m +-2 | + | x | g | xg | 300m +-2 | + | x | h | xh | 316m +-2 | + | x | i | xi | 360m +-2 | + | x | j | xj | 424m +-2 | + | x | k | xk | 360m +-2 | + | x | l | xl | 316m +-2 | + | x | m | xm | 300m +-2 | + | x | n | xn | 316m +-2 | + | x | o | xo | 360m +-2 | + | x | p | xp | 424m +-2 | + | x | q | xq | 360m +-2 | + | x | r | xr | 316m +-2 | + | x | s | xs | 300m +-2 | + | x | t | xt | 316m +-2 | + | x | u | xu | 360m +-2 | + | x | v | xv | 424m +-2 | + | x | w | xw | 360m +-2 | + | x | y | xy | 316m +-2 | @maze Scenario: Distance of a maze of short segments diff --git a/3party/osrm/osrm-backend/features/testbot/distance_matrix.feature b/3party/osrm/osrm-backend/features/testbot/distance_matrix.feature new file mode 100755 index 0000000000..390ae9847d --- /dev/null +++ b/3party/osrm/osrm-backend/features/testbot/distance_matrix.feature @@ -0,0 +1,102 @@ +@matrix @testbot +Feature: Basic Distance Matrix +# note that results are travel time, specified in 1/10th of seconds +# since testbot uses a default speed of 100m/10s, the result matches +# the number of meters as long as the way type is the default 'primary' + + Background: + Given the profile "testbot" + + Scenario: Testbot - Travel time matrix of minimal network + Given the node map + | a | b | + + And the ways + | nodes | + | ab | + + When I request a travel time matrix I should get + | | a | b | + | a | 0 | 100 | + | b | 100 | 0 | + + Scenario: Testbot - Travel time matrix with different way speeds + Given the node map + | a | b | c | d | + + And the ways + | nodes | highway | + | ab | primary | + | bc | secondary | + | cd | tertiary | + + When I request a travel time matrix I should get + | | a | b | c | d | + | a | 0 | 100 | 300 | 600 | + | b | 100 | 0 | 200 | 500 | + | c | 300 | 200 | 0 | 300 | + | d | 600 | 500 | 300 | 0 | + + Scenario: Testbot - Travel time matrix with fuzzy match + Given the node map + | a | b | + + And the ways + | nodes | + | ab | + + When I request a travel time matrix I should get + | | a | b | + | a | 0 | 95 +- 10 | + | b | 95 ~10% | 0 | + + Scenario: Testbot - Travel time matrix of small grid + Given the node map + | a | b | c | + | d | e | f | + + And the ways + | nodes | + | abc | + | def | + | ad | + | be | + | cf | + + When I request a travel time matrix I should get + | | a | b | e | f | + | a | 0 | 100 | 200 | 300 | + | b | 100 | 0 | 100 | 200 | + | e | 200 | 100 | 0 | 100 | + | f | 300 | 200 | 100 | 0 | + + Scenario: Testbot - Travel time matrix of network with unroutable parts + Given the node map + | a | b | + + And the ways + | nodes | oneway | + | ab | yes | + + When I request a travel time matrix I should get + | | a | b | + | a | 0 | 100 | + | b | | 0 | + + Scenario: Testbot - Travel time matrix of network with oneways + Given the node map + | x | a | b | y | + | | d | e | | + + And the ways + | nodes | oneway | + | abeda | yes | + | xa | | + | by | | + + When I request a travel time matrix I should get + | | x | y | d | e | + | x | 0 | 300 | 400 | 300 | + | y | 500 | 0 | 300 | 200 | + | d | 200 | 300 | 0 | 300 | + | e | 300 | 400 | 100 | 0 | diff --git a/3party/osrm/osrm-backend/features/testbot/duration.feature b/3party/osrm/osrm-backend/features/testbot/duration.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/example.feature b/3party/osrm/osrm-backend/features/testbot/example.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/fastest.feature b/3party/osrm/osrm-backend/features/testbot/fastest.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/ferry.feature b/3party/osrm/osrm-backend/features/testbot/ferry.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/fixed.feature b/3party/osrm/osrm-backend/features/testbot/fixed.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/geometry.feature b/3party/osrm/osrm-backend/features/testbot/geometry.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/graph.feature b/3party/osrm/osrm-backend/features/testbot/graph.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/impedance.feature b/3party/osrm/osrm-backend/features/testbot/impedance.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/load.feature b/3party/osrm/osrm-backend/features/testbot/load.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/loop.feature b/3party/osrm/osrm-backend/features/testbot/loop.feature old mode 100644 new mode 100755 index fe898ecf08..72cad33c03 --- a/3party/osrm/osrm-backend/features/testbot/loop.feature +++ b/3party/osrm/osrm-backend/features/testbot/loop.feature @@ -64,13 +64,13 @@ Feature: Avoid weird loops caused by rounding errors | | d | | And the ways - | nodes | highway | - | ab | primary | - | bc | primary | - | cd | primary | - | be | secondary | - | ef | secondary | - | cf | secondary | + | nodes | highway | + | ab | residential | + | bc | residential | + | cd | residential | + | be | primary | + | ef | primary | + | cf | primary | When I route I should get | waypoints | route | turns | diff --git a/3party/osrm/osrm-backend/features/testbot/matching.feature b/3party/osrm/osrm-backend/features/testbot/matching.feature new file mode 100755 index 0000000000..774e8a9d69 --- /dev/null +++ b/3party/osrm/osrm-backend/features/testbot/matching.feature @@ -0,0 +1,55 @@ +@match @testbot +Feature: Basic Map Matching + + Background: + Given the profile "testbot" + Given a grid size of 10 meters + + Scenario: Testbot - Map matching with trace splitting + Given the node map + | a | b | c | d | + | | | e | | + + And the ways + | nodes | oneway | + | abcd | no | + + When I match I should get + | trace | timestamps | matchings | + | abcd | 0 1 62 63 | ab,cd | + + Scenario: Testbot - Map matching with small distortion + Given the node map + | a | b | c | d | e | + | | f | | | | + | | | | | | + | | | | | | + | | | | | | + | | h | | | k | + + # The second way does not need to be a oneway + # but the grid spacing triggers the uturn + # detection on f + And the ways + | nodes | oneway | + | abcde | no | + | bfhke | yes | + + When I match I should get + | trace | matchings | + | afcde | abcde | + + Scenario: Testbot - Map matching with oneways + Given the node map + | a | b | c | d | + | e | f | g | h | + + And the ways + | nodes | oneway | + | abcd | yes | + | hgfe | yes | + + When I match I should get + | trace | matchings | + | dcba | hgfe | + diff --git a/3party/osrm/osrm-backend/features/testbot/maxspeed.feature b/3party/osrm/osrm-backend/features/testbot/maxspeed.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/mode.feature b/3party/osrm/osrm-backend/features/testbot/mode.feature old mode 100644 new mode 100755 index 54b99d3a11..11fe83a427 --- a/3party/osrm/osrm-backend/features/testbot/mode.feature +++ b/3party/osrm/osrm-backend/features/testbot/mode.feature @@ -11,7 +11,7 @@ Feature: Testbot - Travel mode Background: Given the profile "testbot" - + Scenario: Testbot - Modes in each direction, different forward/backward speeds Given the node map | | 0 | 1 | | diff --git a/3party/osrm/osrm-backend/features/testbot/oneway.feature b/3party/osrm/osrm-backend/features/testbot/oneway.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/opposite.feature b/3party/osrm/osrm-backend/features/testbot/opposite.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/origin.feature b/3party/osrm/osrm-backend/features/testbot/origin.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/overlap.feature b/3party/osrm/osrm-backend/features/testbot/overlap.feature old mode 100644 new mode 100755 index 6599e3c766..509867fb5d --- a/3party/osrm/osrm-backend/features/testbot/overlap.feature +++ b/3party/osrm/osrm-backend/features/testbot/overlap.feature @@ -1,11 +1,11 @@ @routing @testbot @overlap Feature: Testbot - overlapping ways - + Background: Given the profile "testbot" @bug @610 - Scenario: Testbot - multiple way between same nodes + Scenario: Testbot - multiple way between same nodes Note that cb is connecting the same two nodes as bc Given the node map | a | b | c | d | @@ -21,7 +21,7 @@ Feature: Testbot - overlapping ways | from | to | route | | a | d | ab,bc,cd | | d | a | cd,bc,ab | - + @bug @610 Scenario: Testbot - area on top of way Given the node map diff --git a/3party/osrm/osrm-backend/features/testbot/penalty.feature b/3party/osrm/osrm-backend/features/testbot/penalty.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/planetary.feature b/3party/osrm/osrm-backend/features/testbot/planetary.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/projection.feature b/3party/osrm/osrm-backend/features/testbot/projection.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/protobuffer.feature b/3party/osrm/osrm-backend/features/testbot/protobuffer.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/roundabout.feature b/3party/osrm/osrm-backend/features/testbot/roundabout.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/routes.feature b/3party/osrm/osrm-backend/features/testbot/routes.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/snap.feature b/3party/osrm/osrm-backend/features/testbot/snap.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/speed.feature b/3party/osrm/osrm-backend/features/testbot/speed.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/status.feature b/3party/osrm/osrm-backend/features/testbot/status.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/time.feature b/3party/osrm/osrm-backend/features/testbot/time.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/turns.feature b/3party/osrm/osrm-backend/features/testbot/turns.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/utf.feature b/3party/osrm/osrm-backend/features/testbot/utf.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/uturn.feature b/3party/osrm/osrm-backend/features/testbot/uturn.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/testbot/via.feature b/3party/osrm/osrm-backend/features/testbot/via.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/features/timestamp/timestamp.feature b/3party/osrm/osrm-backend/features/timestamp/timestamp.feature old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/include/osrm/coordinate.hpp b/3party/osrm/osrm-backend/include/osrm/coordinate.hpp new file mode 100755 index 0000000000..6318465e19 --- /dev/null +++ b/3party/osrm/osrm-backend/include/osrm/coordinate.hpp @@ -0,0 +1,71 @@ +/* + +Copyright (c) 2015, 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 COORDINATE_HPP_ +#define COORDINATE_HPP_ + +#include //for std::ostream +#include +#include + +namespace +{ +constexpr static const float COORDINATE_PRECISION = 1000000.f; +} + +struct FixedPointCoordinate +{ + int lat; + int lon; + + FixedPointCoordinate(); + FixedPointCoordinate(int lat, int lon); + + template + FixedPointCoordinate(const T &coordinate) + : lat(coordinate.lat), lon(coordinate.lon) + { + static_assert(std::is_same::value, + "coordinate types incompatible"); + static_assert(std::is_same::value, + "coordinate types incompatible"); + } + + bool is_valid() const; + bool operator==(const FixedPointCoordinate &other) const; + + float bearing(const FixedPointCoordinate &other) const; + void output(std::ostream &out) const; +}; + +inline std::ostream &operator<<(std::ostream &out_stream, FixedPointCoordinate const &coordinate) +{ + coordinate.output(out_stream); + return out_stream; +} + +#endif /* COORDINATE_HPP_ */ diff --git a/3party/osrm/osrm-backend/include/osrm/json_container.hpp b/3party/osrm/osrm-backend/include/osrm/json_container.hpp new file mode 100755 index 0000000000..40f39b8257 --- /dev/null +++ b/3party/osrm/osrm-backend/include/osrm/json_container.hpp @@ -0,0 +1,96 @@ +/* + +Copyright (c) 2013, 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. + +*/ + +// based on +// https://svn.apache.org/repos/asf/mesos/tags/release-0.9.0-incubating-RC0/src/common/json.hpp + +#ifndef JSON_CONTAINER_HPP +#define JSON_CONTAINER_HPP + +#include + +#include +#include +#include +#include + +namespace osrm +{ +namespace json +{ + +struct Object; +struct Array; + +struct String +{ + String() {} + String(const char *value) : value(value) {} + String(const std::string &value) : value(value) {} + std::string value; +}; + +struct Number +{ + Number() {} + Number(double value) : value(static_cast(value)) {} + double value; +}; + +struct True +{ +}; + +struct False +{ +}; + +struct Null +{ +}; + +using Value = mapbox::util::variant, + mapbox::util::recursive_wrapper, + True, + False, + Null>; + +struct Object +{ + std::unordered_map values; +}; + +struct Array +{ + std::vector values; +}; + +} // namespace JSON +} // namespace osrm +#endif // JSON_CONTAINER_HPP diff --git a/3party/osrm/osrm-backend/Util/MachineInfo.h b/3party/osrm/osrm-backend/include/osrm/libosrm_config.hpp old mode 100644 new mode 100755 similarity index 62% rename from 3party/osrm/osrm-backend/Util/MachineInfo.h rename to 3party/osrm/osrm-backend/include/osrm/libosrm_config.hpp index a9a88a1ec0..500abf5bd6 --- a/3party/osrm/osrm-backend/Util/MachineInfo.h +++ b/3party/osrm/osrm-backend/include/osrm/libosrm_config.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,33 +25,30 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MACHINE_INFO_H -#define MACHINE_INFO_H +#ifndef SERVER_CONFIG_HPP +#define SERVER_CONFIG_HPP -enum Endianness -{ LittleEndian = 1, - BigEndian = 2 }; +#include -// Function is optimized to a single 'mov eax,1' on GCC, clang and icc using -O3 -Endianness GetMachineEndianness() +struct libosrm_config { - int i(1); - char *p = (char *)&i; - if (1 == p[0]) + libosrm_config(const libosrm_config &) = delete; + libosrm_config() + : max_locations_distance_table(100), max_locations_map_matching(-1), + use_shared_memory(false) { - return LittleEndian; } - return BigEndian; -} -// Reverses Network Byte Order into something usable, compiles down to a bswap-mov combination -unsigned SwapEndian(unsigned x) -{ - if (GetMachineEndianness() == LittleEndian) + libosrm_config(const ServerPaths &paths, const bool flag, const int max_table, const int max_matching) + : server_paths(paths), max_locations_distance_table(max_table), + max_locations_map_matching(max_matching), use_shared_memory(flag) { - return ((x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24)); } - return x; -} -#endif // MACHINE_INFO_H + ServerPaths server_paths; + int max_locations_distance_table; + int max_locations_map_matching; + bool use_shared_memory; +}; + +#endif // SERVER_CONFIG_HPP diff --git a/3party/osrm/osrm-backend/Include/osrm/RouteParameters.h b/3party/osrm/osrm-backend/include/osrm/route_parameters.hpp old mode 100644 new mode 100755 similarity index 84% rename from 3party/osrm/osrm-backend/Include/osrm/RouteParameters.h rename to 3party/osrm/osrm-backend/include/osrm/route_parameters.hpp index 62f45148a5..9babbd763b --- a/3party/osrm/osrm-backend/Include/osrm/RouteParameters.h +++ b/3party/osrm/osrm-backend/include/osrm/route_parameters.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,10 +25,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ROUTE_PARAMETERS_H -#define ROUTE_PARAMETERS_H +#ifndef ROUTE_PARAMETERS_HPP +#define ROUTE_PARAMETERS_HPP -#include +#include #include @@ -49,6 +49,12 @@ struct RouteParameters void setAllUTurns(const bool flag); + void setClassify(const bool classify); + + void setMatchingBeta(const double beta); + + void setGPSPrecision(const double precision); + void setDeprecatedAPIFlag(const std::string &); void setChecksum(const unsigned check_sum); @@ -63,13 +69,15 @@ struct RouteParameters void addHint(const std::string &hint); + void addTimestamp(const unsigned timestamp); + void setLanguage(const std::string &language); void setGeometryFlag(const bool flag); void setCompressionFlag(const bool flag); - void addCoordinate(const boost::fusion::vector &coordinates); + void addCoordinate(const boost::fusion::vector &received_coordinates); short zoom_level; bool print_instructions; @@ -78,6 +86,9 @@ struct RouteParameters bool compression; bool deprecatedAPI; bool uturn_default; + bool classify; + double matching_beta; + double gps_precision; unsigned check_sum; short num_results; std::string service; @@ -85,8 +96,9 @@ struct RouteParameters std::string jsonp_parameter; std::string language; std::vector hints; + std::vector timestamps; std::vector uturns; std::vector coordinates; }; -#endif // ROUTE_PARAMETERS_H +#endif // ROUTE_PARAMETERS_HPP diff --git a/3party/osrm/osrm-backend/Include/osrm/ServerPaths.h b/3party/osrm/osrm-backend/include/osrm/server_paths.hpp old mode 100644 new mode 100755 similarity index 91% rename from 3party/osrm/osrm-backend/Include/osrm/ServerPaths.h rename to 3party/osrm/osrm-backend/include/osrm/server_paths.hpp index 52b60c7c42..669ee7de0f --- a/3party/osrm/osrm-backend/Include/osrm/ServerPaths.h +++ b/3party/osrm/osrm-backend/include/osrm/server_paths.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -33,6 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -typedef std::unordered_map ServerPaths; +using ServerPaths = std::unordered_map; #endif // SERVER_PATH_H diff --git a/3party/osrm/osrm-backend/Library/OSRM.h b/3party/osrm/osrm-backend/library/osrm.hpp old mode 100644 new mode 100755 similarity index 81% rename from 3party/osrm/osrm-backend/Library/OSRM.h rename to 3party/osrm/osrm-backend/library/osrm.hpp index 372e82c391..27acb40394 --- a/3party/osrm/osrm-backend/Library/OSRM.h +++ b/3party/osrm/osrm-backend/library/osrm.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,19 +25,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef OSRM_H -#define OSRM_H +#ifndef OSRM_HPP +#define OSRM_HPP -#include +#include #include class OSRM_impl; struct RouteParameters; -namespace http +namespace osrm { -class Reply; +namespace json +{ +struct Object; +} } class OSRM @@ -46,9 +49,9 @@ class OSRM std::unique_ptr OSRM_pimpl_; public: - explicit OSRM(ServerPaths paths, const bool use_shared_memory = false); + explicit OSRM(libosrm_config &lib_config); ~OSRM(); - void RunQuery(RouteParameters &route_parameters, http::Reply &reply); + int RunQuery(RouteParameters &route_parameters, osrm::json::Object &json_result); }; -#endif // OSRM_H +#endif // OSRM_HPP diff --git a/3party/osrm/osrm-backend/library/osrm_impl.cpp b/3party/osrm/osrm-backend/library/osrm_impl.cpp new file mode 100755 index 0000000000..5bb58d1749 --- /dev/null +++ b/3party/osrm/osrm-backend/library/osrm_impl.cpp @@ -0,0 +1,181 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +namespace boost +{ +namespace interprocess +{ +class named_mutex; +} +} + +#include "osrm_impl.hpp" +#include "osrm.hpp" + +#include "../plugins/distance_table.hpp" +#include "../plugins/hello_world.hpp" +#include "../plugins/locate.hpp" +#include "../plugins/nearest.hpp" +#include "../plugins/timestamp.hpp" +#include "../plugins/viaroute.hpp" +#include "../plugins/match.hpp" +#include "../server/data_structures/datafacade_base.hpp" +#include "../server/data_structures/internal_datafacade.hpp" +#include "../server/data_structures/shared_barriers.hpp" +#include "../server/data_structures/shared_datafacade.hpp" +#include "../util/make_unique.hpp" +#include "../util/routed_options.hpp" +#include "../util/simple_logger.hpp" + +#include +#include +#include + +#include + +#include +#include +#include +#include + +OSRM_impl::OSRM_impl(libosrm_config &lib_config) +{ + if (lib_config.use_shared_memory) + { + barrier = osrm::make_unique(); + query_data_facade = new SharedDataFacade(); + } + else + { + // populate base path + populate_base_path(lib_config.server_paths); + query_data_facade = new InternalDataFacade(lib_config.server_paths); + } + + // The following plugins handle all requests. + RegisterPlugin(new DistanceTablePlugin>( + query_data_facade, lib_config.max_locations_distance_table)); + RegisterPlugin(new HelloWorldPlugin()); + RegisterPlugin(new LocatePlugin>(query_data_facade)); + RegisterPlugin(new NearestPlugin>(query_data_facade)); + RegisterPlugin(new MapMatchingPlugin>( + query_data_facade, lib_config.max_locations_map_matching)); + RegisterPlugin(new TimestampPlugin>(query_data_facade)); + RegisterPlugin(new ViaRoutePlugin>(query_data_facade)); +} + +OSRM_impl::~OSRM_impl() +{ + delete query_data_facade; + for (PluginMap::value_type &plugin_pointer : plugin_map) + { + delete plugin_pointer.second; + } +} + +void OSRM_impl::RegisterPlugin(BasePlugin *plugin) +{ + SimpleLogger().Write() << "loaded plugin: " << plugin->GetDescriptor(); + if (plugin_map.find(plugin->GetDescriptor()) != plugin_map.end()) + { + delete plugin_map.find(plugin->GetDescriptor())->second; + } + plugin_map.emplace(plugin->GetDescriptor(), plugin); +} + +int OSRM_impl::RunQuery(RouteParameters &route_parameters, osrm::json::Object &json_result) +{ + const auto &plugin_iterator = plugin_map.find(route_parameters.service); + + if (plugin_map.end() == plugin_iterator) + { + return 400; + } + + increase_concurrent_query_count(); + plugin_iterator->second->HandleRequest(route_parameters, json_result); + decrease_concurrent_query_count(); + return 200; +} + +// decrease number of concurrent queries +void OSRM_impl::decrease_concurrent_query_count() +{ + if (!barrier) + { + return; + } + // lock query + boost::interprocess::scoped_lock query_lock( + barrier->query_mutex); + + // decrement query count + --(barrier->number_of_queries); + BOOST_ASSERT_MSG(0 <= barrier->number_of_queries, "invalid number of queries"); + + // notify all processes that were waiting for this condition + if (0 == barrier->number_of_queries) + { + barrier->no_running_queries_condition.notify_all(); + } +} + +// increase number of concurrent queries +void OSRM_impl::increase_concurrent_query_count() +{ + if (!barrier) + { + return; + } + + // lock update pending + boost::interprocess::scoped_lock pending_lock( + barrier->pending_update_mutex); + + // lock query + boost::interprocess::scoped_lock query_lock( + barrier->query_mutex); + + // unlock update pending + pending_lock.unlock(); + + // increment query count + ++(barrier->number_of_queries); + + (static_cast *>(query_data_facade)) + ->CheckAndReloadFacade(); +} + +// proxy code for compilation firewall +OSRM::OSRM(libosrm_config &lib_config) : OSRM_pimpl_(osrm::make_unique(lib_config)) {} + +OSRM::~OSRM() { OSRM_pimpl_.reset(); } + +int OSRM::RunQuery(RouteParameters &route_parameters, osrm::json::Object &json_result) +{ + return OSRM_pimpl_->RunQuery(route_parameters, json_result); +} diff --git a/3party/osrm/osrm-backend/Library/OSRM_impl.h b/3party/osrm/osrm-backend/library/osrm_impl.hpp old mode 100644 new mode 100755 similarity index 78% rename from 3party/osrm/osrm-backend/Library/OSRM_impl.h rename to 3party/osrm/osrm-backend/library/osrm_impl.hpp index a4af62cb65..a736c042f6 --- a/3party/osrm/osrm-backend/Library/OSRM_impl.h +++ b/3party/osrm/osrm-backend/library/osrm_impl.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,16 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef OSRM_IMPL_H -#define OSRM_IMPL_H +#ifndef OSRM_IMPL_HPP +#define OSRM_IMPL_HPP class BasePlugin; -namespace http { class Reply; } struct RouteParameters; -#include +#include "../data_structures/query_edge.hpp" -#include "../DataStructures/QueryEdge.h" +#include +#include #include #include @@ -49,10 +49,10 @@ class OSRM_impl using PluginMap = std::unordered_map; public: - OSRM_impl(ServerPaths paths, const bool use_shared_memory); + OSRM_impl(libosrm_config &lib_config); OSRM_impl(const OSRM_impl &) = delete; virtual ~OSRM_impl(); - void RunQuery(RouteParameters &route_parameters, http::Reply &reply); + int RunQuery(RouteParameters &route_parameters, osrm::json::Object &json_result); private: void RegisterPlugin(BasePlugin *plugin); @@ -61,6 +61,11 @@ class OSRM_impl std::unique_ptr barrier; // base class pointer to the objects BaseDataFacade *query_data_facade; + + // decrease number of concurrent queries + void decrease_concurrent_query_count(); + // increase number of concurrent queries + void increase_concurrent_query_count(); }; -#endif // OSRM_IMPL_H +#endif // OSRM_IMPL_HPP diff --git a/3party/osrm/osrm-backend/mapsme/converter.cpp b/3party/osrm/osrm-backend/mapsme/converter.cpp deleted file mode 100644 index 307c1d32f1..0000000000 --- a/3party/osrm/osrm-backend/mapsme/converter.cpp +++ /dev/null @@ -1,388 +0,0 @@ -#include "converter.hpp" - -#include - - -#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 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 facade(server_paths); - PrintStatus(true); - - uint32_t const nodeCount = facade.GetNumberOfNodes(); - - std::vector edges; - std::vector edgesData; - std::vector shortcuts; - std::vector edgeId; - - std::cout << "Repack graph..." << std::endl; - - typedef pair EdgeInfoT; - typedef vector 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(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 (static_cast(data.distance) <= last) - { - if (!edgeId.empty() && data.shortcut) - { - CHECK(shortcuts.back(), ()); - unsigned oldId = node - bits::ZigZagDecode(edgeId.back()); - - if (static_cast(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 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; - - 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 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 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 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); -} - -} diff --git a/3party/osrm/osrm-backend/mapsme/converter.hpp b/3party/osrm/osrm-backend/mapsme/converter.hpp deleted file mode 100644 index 77961dd3ca..0000000000 --- a/3party/osrm/osrm-backend/mapsme/converter.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -#include "../DataStructures/QueryEdge.h" - -namespace mapsme -{ - - -void GenerateRoutingIndex(const std::string & fPath); - -} diff --git a/3party/osrm/osrm-backend/mapsme/main.cpp b/3party/osrm/osrm-backend/mapsme/main.cpp deleted file mode 100644 index 5d626a9e61..0000000000 --- a/3party/osrm/osrm-backend/mapsme/main.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#include -#include -#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(), "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()); - - return 0; -} diff --git a/3party/osrm/osrm-backend/Plugins/DistanceTablePlugin.h b/3party/osrm/osrm-backend/plugins/distance_table.hpp old mode 100644 new mode 100755 similarity index 53% rename from 3party/osrm/osrm-backend/Plugins/DistanceTablePlugin.h rename to 3party/osrm/osrm-backend/plugins/distance_table.hpp index 715c4f52cf..d7a980419b --- a/3party/osrm/osrm-backend/Plugins/DistanceTablePlugin.h +++ b/3party/osrm/osrm-backend/plugins/distance_table.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2014, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,19 +25,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DISTANCE_TABLE_PLUGIN_H -#define DISTANCE_TABLE_PLUGIN_H +#ifndef DISTANCE_TABLE_HPP +#define DISTANCE_TABLE_HPP -#include "BasePlugin.h" +#include "plugin_base.hpp" -#include "../Algorithms/ObjectToBase64.h" -#include "../DataStructures/JSONContainer.h" -#include "../DataStructures/QueryEdge.h" -#include "../DataStructures/SearchEngine.h" -#include "../Descriptors/BaseDescriptor.h" -#include "../Util/make_unique.hpp" -#include "../Util/StringUtil.h" -#include "../Util/TimingUtil.h" +#include "../algorithms/object_encoder.hpp" +#include "../data_structures/query_edge.hpp" +#include "../data_structures/search_engine.hpp" +#include "../descriptors/descriptor_base.hpp" +#include "../util/json_renderer.hpp" +#include "../util/make_unique.hpp" +#include "../util/string_util.hpp" +#include "../util/timing_util.hpp" + +#include #include @@ -51,68 +53,51 @@ template class DistanceTablePlugin final : public BasePlugin { private: std::unique_ptr> search_engine_ptr; + int max_locations_distance_table; public: - explicit DistanceTablePlugin(DataFacadeT *facade) : descriptor_string("table"), facade(facade) + explicit DistanceTablePlugin(DataFacadeT *facade, const int max_locations_distance_table) + : max_locations_distance_table(max_locations_distance_table), descriptor_string("table"), + facade(facade) { search_engine_ptr = osrm::make_unique>(facade); } virtual ~DistanceTablePlugin() {} - const std::string GetDescriptor() const final { return descriptor_string; } + const std::string GetDescriptor() const override final { return descriptor_string; } - void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final + int HandleRequest(const RouteParameters &route_parameters, + osrm::json::Object &json_result) override final { - // check number of parameters - if (2 > route_parameters.coordinates.size()) + if (!check_all_coordinates(route_parameters.coordinates)) { - reply = http::Reply::StockReply(http::Reply::badRequest); - return; + return 400; } - RawRouteData raw_route; - raw_route.check_sum = facade->GetCheckSum(); - - if (std::any_of(begin(route_parameters.coordinates), - end(route_parameters.coordinates), - [&](FixedPointCoordinate coordinate) - { - return !coordinate.isValid(); - })) - { - reply = http::Reply::StockReply(http::Reply::badRequest); - return; - } - - for (const FixedPointCoordinate &coordinate : route_parameters.coordinates) - { - raw_route.raw_via_node_coordinates.emplace_back(std::move(coordinate)); - } - - const bool checksum_OK = (route_parameters.check_sum == raw_route.check_sum); + const bool checksum_OK = (route_parameters.check_sum == facade->GetCheckSum()); unsigned max_locations = - std::min(100u, static_cast(raw_route.raw_via_node_coordinates.size())); + std::min(static_cast(max_locations_distance_table), + static_cast(route_parameters.coordinates.size())); + PhantomNodeArray phantom_node_vector(max_locations); - for (unsigned i = 0; i < max_locations; ++i) + for (const auto i : osrm::irange(0u, max_locations)) { if (checksum_OK && i < route_parameters.hints.size() && !route_parameters.hints[i].empty()) { PhantomNode current_phantom_node; ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], current_phantom_node); - if (current_phantom_node.isValid(facade->GetNumberOfNodes())) + if (current_phantom_node.is_valid(facade->GetNumberOfNodes())) { phantom_node_vector[i].emplace_back(std::move(current_phantom_node)); continue; } } - facade->IncrementalFindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i], - phantom_node_vector[i], - route_parameters.zoom_level, - 1); + facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i], + phantom_node_vector[i], 1); - BOOST_ASSERT(phantom_node_vector[i].front().isValid(facade->GetNumberOfNodes())); + BOOST_ASSERT(phantom_node_vector[i].front().is_valid(facade->GetNumberOfNodes())); } // TIMER_START(distance_table); @@ -122,22 +107,22 @@ template class DistanceTablePlugin final : public BasePlugin if (!result_table) { - reply = http::Reply::StockReply(http::Reply::badRequest); - return; + return 400; } - JSON::Object json_object; - JSON::Array json_array; - const unsigned number_of_locations = static_cast(phantom_node_vector.size()); - for (unsigned row = 0; row < number_of_locations; ++row) + + osrm::json::Array json_array; + const auto number_of_locations = phantom_node_vector.size(); + for (const auto row : osrm::irange(0, number_of_locations)) { - JSON::Array json_row; + osrm::json::Array json_row; auto row_begin_iterator = result_table->begin() + (row * number_of_locations); auto row_end_iterator = result_table->begin() + ((row + 1) * number_of_locations); json_row.values.insert(json_row.values.end(), row_begin_iterator, row_end_iterator); json_array.values.push_back(json_row); } - json_object.values["distance_table"] = json_array; - JSON::render(reply.content, json_object); + json_result.values["distance_table"] = json_array; + // osrm::json::render(reply.content, json_object); + return 200; } private: @@ -145,4 +130,4 @@ template class DistanceTablePlugin final : public BasePlugin DataFacadeT *facade; }; -#endif // DISTANCE_TABLE_PLUGIN_H +#endif // DISTANCE_TABLE_HPP diff --git a/3party/osrm/osrm-backend/Plugins/HelloWorldPlugin.h b/3party/osrm/osrm-backend/plugins/hello_world.hpp old mode 100644 new mode 100755 similarity index 78% rename from 3party/osrm/osrm-backend/Plugins/HelloWorldPlugin.h rename to 3party/osrm/osrm-backend/plugins/hello_world.hpp index d9b4a8d0e2..faf5b10489 --- a/3party/osrm/osrm-backend/Plugins/HelloWorldPlugin.h +++ b/3party/osrm/osrm-backend/plugins/hello_world.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,12 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HELLO_WORLD_PLUGIN_H -#define HELLO_WORLD_PLUGIN_H +#ifndef HELLO_WORLD_HPP +#define HELLO_WORLD_HPP -#include "BasePlugin.h" -#include "../DataStructures/JSONContainer.h" -#include "../Util/cast.hpp" +#include "plugin_base.hpp" + +#include "../util/cast.hpp" +#include "../util/json_renderer.hpp" + +#include #include @@ -42,13 +45,11 @@ class HelloWorldPlugin final : public BasePlugin public: HelloWorldPlugin() : descriptor_string("hello") {} virtual ~HelloWorldPlugin() {} - const std::string GetDescriptor() const final { return descriptor_string; } + const std::string GetDescriptor() const override final { return descriptor_string; } - void HandleRequest(const RouteParameters &routeParameters, http::Reply &reply) final + int HandleRequest(const RouteParameters &routeParameters, + osrm::json::Object &json_result) override final { - reply.status = http::Reply::ok; - - JSON::Object json_result; std::string temp_string; json_result.values["title"] = "Hello World"; @@ -70,15 +71,17 @@ class HelloWorldPlugin final : public BasePlugin temp_string = cast::integral_to_string(routeParameters.coordinates.size()); json_result.values["location_count"] = temp_string; - JSON::Array json_locations; + osrm::json::Array json_locations; unsigned counter = 0; for (const FixedPointCoordinate &coordinate : routeParameters.coordinates) { - JSON::Object json_location; - JSON::Array json_coordinates; + osrm::json::Object json_location; + osrm::json::Array json_coordinates; - json_coordinates.values.push_back(coordinate.lat / COORDINATE_PRECISION); - json_coordinates.values.push_back(coordinate.lon / COORDINATE_PRECISION); + json_coordinates.values.push_back( + static_cast(coordinate.lat / COORDINATE_PRECISION)); + json_coordinates.values.push_back( + static_cast(coordinate.lon / COORDINATE_PRECISION)); json_location.values[cast::integral_to_string(counter)] = json_coordinates; json_locations.values.push_back(json_location); ++counter; @@ -86,7 +89,7 @@ class HelloWorldPlugin final : public BasePlugin json_result.values["locations"] = json_locations; json_result.values["hint_count"] = routeParameters.hints.size(); - JSON::Array json_hints; + osrm::json::Array json_hints; counter = 0; for (const std::string ¤t_hint : routeParameters.hints) { @@ -94,12 +97,11 @@ class HelloWorldPlugin final : public BasePlugin ++counter; } json_result.values["hints"] = json_hints; - - JSON::render(reply.content, json_result); + return 200; } private: std::string descriptor_string; }; -#endif // HELLO_WORLD_PLUGIN_H +#endif // HELLO_WORLD_HPP diff --git a/3party/osrm/osrm-backend/Plugins/LocatePlugin.h b/3party/osrm/osrm-backend/plugins/locate.hpp old mode 100644 new mode 100755 similarity index 74% rename from 3party/osrm/osrm-backend/Plugins/LocatePlugin.h rename to 3party/osrm/osrm-backend/plugins/locate.hpp index 1701bbe15a..144765ad82 --- a/3party/osrm/osrm-backend/Plugins/LocatePlugin.h +++ b/3party/osrm/osrm-backend/plugins/locate.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,12 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LOCATE_PLUGIN_H -#define LOCATE_PLUGIN_H +#ifndef LOCATE_HPP +#define LOCATE_HPP -#include "BasePlugin.h" -#include "../DataStructures/JSONContainer.h" -#include "../Util/StringUtil.h" +#include "plugin_base.hpp" + +#include "../util/json_renderer.hpp" +#include "../util/string_util.hpp" + +#include #include @@ -39,18 +42,18 @@ template class LocatePlugin final : public BasePlugin { public: explicit LocatePlugin(DataFacadeT *facade) : descriptor_string("locate"), facade(facade) {} - const std::string GetDescriptor() const final { return descriptor_string; } + const std::string GetDescriptor() const override final { return descriptor_string; } - void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final + int HandleRequest(const RouteParameters &route_parameters, + osrm::json::Object &json_result) override final { // check number of parameters - if (route_parameters.coordinates.empty() || !route_parameters.coordinates.front().isValid()) + if (route_parameters.coordinates.empty() || + !route_parameters.coordinates.front().is_valid()) { - reply = http::Reply::StockReply(http::Reply::badRequest); - return; + return 400; } - JSON::Object json_result; FixedPointCoordinate result; if (!facade->LocateClosestEndPointForCoordinate(route_parameters.coordinates.front(), result)) @@ -59,15 +62,13 @@ template class LocatePlugin final : public BasePlugin } else { - reply.status = http::Reply::ok; json_result.values["status"] = 0; - JSON::Array json_coordinate; + osrm::json::Array json_coordinate; json_coordinate.values.push_back(result.lat / COORDINATE_PRECISION); json_coordinate.values.push_back(result.lon / COORDINATE_PRECISION); json_result.values["mapped_coordinate"] = json_coordinate; } - - JSON::render(reply.content, json_result); + return 200; } private: @@ -75,4 +76,4 @@ template class LocatePlugin final : public BasePlugin DataFacadeT *facade; }; -#endif /* LOCATE_PLUGIN_H */ +#endif /* LOCATE_HPP */ diff --git a/3party/osrm/osrm-backend/plugins/match.hpp b/3party/osrm/osrm-backend/plugins/match.hpp new file mode 100755 index 0000000000..a866947b4b --- /dev/null +++ b/3party/osrm/osrm-backend/plugins/match.hpp @@ -0,0 +1,314 @@ +/* + +Copyright (c) 2015, 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 MATCH_HPP +#define MATCH_HPP + +#include "plugin_base.hpp" + +#include "../algorithms/bayes_classifier.hpp" +#include "../algorithms/object_encoder.hpp" +#include "../data_structures/search_engine.hpp" +#include "../descriptors/descriptor_base.hpp" +#include "../descriptors/json_descriptor.hpp" +#include "../routing_algorithms/map_matching.hpp" +#include "../util/compute_angle.hpp" +#include "../util/integer_range.hpp" +#include "../util/json_logger.hpp" +#include "../util/json_util.hpp" +#include "../util/string_util.hpp" + +#include + +#include +#include +#include +#include + +template class MapMatchingPlugin : public BasePlugin +{ + constexpr static const unsigned max_number_of_candidates = 10; + + std::shared_ptr> search_engine_ptr; + + using ClassifierT = BayesClassifier; + using TraceClassification = ClassifierT::ClassificationT; + + public: + MapMatchingPlugin(DataFacadeT *facade, const int max_locations_map_matching) + : descriptor_string("match"), facade(facade), + max_locations_map_matching(max_locations_map_matching), + // the values where derived from fitting a laplace distribution + // to the values of manually classified traces + classifier(LaplaceDistribution(0.005986, 0.016646), + LaplaceDistribution(0.054385, 0.458432), + 0.696774) // valid apriori probability + { + search_engine_ptr = std::make_shared>(facade); + } + + virtual ~MapMatchingPlugin() {} + + const std::string GetDescriptor() const final { return descriptor_string; } + + TraceClassification + classify(const float trace_length, const float matched_length, const int removed_points) const + { + const double distance_feature = -std::log(trace_length) + std::log(matched_length); + + // matched to the same point + if (!std::isfinite(distance_feature)) + { + return std::make_pair(ClassifierT::ClassLabel::NEGATIVE, 1.0); + } + + const auto label_with_confidence = classifier.classify(distance_feature); + + return label_with_confidence; + } + + bool getCandiates(const std::vector &input_coords, + std::vector &sub_trace_lengths, + osrm::matching::CandidateLists &candidates_lists) + { + double last_distance = + coordinate_calculation::great_circle_distance(input_coords[0], input_coords[1]); + sub_trace_lengths.resize(input_coords.size()); + sub_trace_lengths[0] = 0; + for (const auto current_coordinate : osrm::irange(0, input_coords.size())) + { + bool allow_uturn = false; + if (0 < current_coordinate) + { + last_distance = coordinate_calculation::great_circle_distance( + input_coords[current_coordinate - 1], input_coords[current_coordinate]); + sub_trace_lengths[current_coordinate] += + sub_trace_lengths[current_coordinate - 1] + last_distance; + } + + if (input_coords.size() - 1 > current_coordinate && 0 < current_coordinate) + { + double turn_angle = ComputeAngle::OfThreeFixedPointCoordinates( + input_coords[current_coordinate - 1], input_coords[current_coordinate], + input_coords[current_coordinate + 1]); + + // sharp turns indicate a possible uturn + if (turn_angle <= 90.0 || turn_angle >= 270.0) + { + allow_uturn = true; + } + } + + std::vector> candidates; + if (!facade->IncrementalFindPhantomNodeForCoordinateWithMaxDistance( + input_coords[current_coordinate], candidates, last_distance / 2.0, 5, + max_number_of_candidates)) + { + return false; + } + + if (allow_uturn) + { + candidates_lists.push_back(candidates); + } + else + { + const auto compact_size = candidates.size(); + for (const auto i : osrm::irange(0, compact_size)) + { + // Split edge if it is bidirectional and append reverse direction to end of list + if (candidates[i].first.forward_node_id != SPECIAL_NODEID && + candidates[i].first.reverse_node_id != SPECIAL_NODEID) + { + PhantomNode reverse_node(candidates[i].first); + reverse_node.forward_node_id = SPECIAL_NODEID; + candidates.push_back(std::make_pair(reverse_node, candidates[i].second)); + + candidates[i].first.reverse_node_id = SPECIAL_NODEID; + } + } + candidates_lists.push_back(candidates); + } + } + + return true; + } + + osrm::json::Object submatchingToJSON(const osrm::matching::SubMatching &sub, + const RouteParameters &route_parameters, + const InternalRouteResult &raw_route) + { + osrm::json::Object subtrace; + + if (route_parameters.classify) + { + subtrace.values["confidence"] = sub.confidence; + } + + if (route_parameters.geometry) + { + DescriptionFactory factory; + FixedPointCoordinate current_coordinate; + factory.SetStartSegment(raw_route.segment_end_coordinates.front().source_phantom, + raw_route.source_traversed_in_reverse.front()); + for (const auto i : + osrm::irange(0, raw_route.unpacked_path_segments.size())) + { + for (const PathData &path_data : raw_route.unpacked_path_segments[i]) + { + current_coordinate = facade->GetCoordinateOfNode(path_data.node); + factory.AppendSegment(current_coordinate, path_data); + } + factory.SetEndSegment(raw_route.segment_end_coordinates[i].target_phantom, + raw_route.target_traversed_in_reverse[i], + raw_route.is_via_leg(i)); + } + // we need this because we don't run DP + for (auto &segment : factory.path_description) + { + segment.necessary = true; + } + subtrace.values["geometry"] = + factory.AppendGeometryString(route_parameters.compression); + } + + subtrace.values["indices"] = osrm::json::make_array(sub.indices); + + osrm::json::Array points; + for (const auto &node : sub.nodes) + { + points.values.emplace_back( + osrm::json::make_array(node.location.lat / COORDINATE_PRECISION, + node.location.lon / COORDINATE_PRECISION)); + } + subtrace.values["matched_points"] = points; + + return subtrace; + } + + int HandleRequest(const RouteParameters &route_parameters, + osrm::json::Object &json_result) final + { + // check number of parameters + if (!check_all_coordinates(route_parameters.coordinates)) + { + return 400; + } + + std::vector sub_trace_lengths; + osrm::matching::CandidateLists candidates_lists; + const auto &input_coords = route_parameters.coordinates; + const auto &input_timestamps = route_parameters.timestamps; + if (input_timestamps.size() > 0 && input_coords.size() != input_timestamps.size()) + { + return 400; + } + + // enforce maximum number of locations for performance reasons + if (max_locations_map_matching > 0 && + static_cast(input_coords.size()) < max_locations_map_matching) + { + return 400; + } + + const bool found_candidates = + getCandiates(input_coords, sub_trace_lengths, candidates_lists); + if (!found_candidates) + { + return 400; + } + + // setup logging if enabled + if (osrm::json::Logger::get()) + osrm::json::Logger::get()->initialize("matching"); + + // call the actual map matching + osrm::matching::SubMatchingList sub_matchings; + search_engine_ptr->map_matching(candidates_lists, input_coords, input_timestamps, + route_parameters.matching_beta, + route_parameters.gps_precision, sub_matchings); + + if (sub_matchings.empty()) + { + return 400; + } + + osrm::json::Array matchings; + for (auto &sub : sub_matchings) + { + // classify result + if (route_parameters.classify) + { + double trace_length = + sub_trace_lengths[sub.indices.back()] - sub_trace_lengths[sub.indices.front()]; + TraceClassification classification = + classify(trace_length, sub.length, + (sub.indices.back() - sub.indices.front() + 1) - sub.nodes.size()); + if (classification.first == ClassifierT::ClassLabel::POSITIVE) + { + sub.confidence = classification.second; + } + else + { + sub.confidence = 1 - classification.second; + } + } + + BOOST_ASSERT(sub.nodes.size() > 1); + + // FIXME we only run this to obtain the geometry + // The clean way would be to get this directly from the map matching plugin + InternalRouteResult raw_route; + PhantomNodes current_phantom_node_pair; + for (unsigned i = 0; i < sub.nodes.size() - 1; ++i) + { + current_phantom_node_pair.source_phantom = sub.nodes[i]; + current_phantom_node_pair.target_phantom = sub.nodes[i + 1]; + raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair); + } + search_engine_ptr->shortest_path( + raw_route.segment_end_coordinates, + std::vector(raw_route.segment_end_coordinates.size(), true), raw_route); + + matchings.values.emplace_back(submatchingToJSON(sub, route_parameters, raw_route)); + } + + if (osrm::json::Logger::get()) + osrm::json::Logger::get()->render("matching", json_result); + json_result.values["matchings"] = matchings; + + return 200; + } + + private: + std::string descriptor_string; + DataFacadeT *facade; + int max_locations_map_matching; + ClassifierT classifier; +}; + +#endif // MATCH_HPP diff --git a/3party/osrm/osrm-backend/Plugins/NearestPlugin.h b/3party/osrm/osrm-backend/plugins/nearest.hpp old mode 100644 new mode 100755 similarity index 69% rename from 3party/osrm/osrm-backend/Plugins/NearestPlugin.h rename to 3party/osrm/osrm-backend/plugins/nearest.hpp index e4fec91c19..bf4cff3a1d --- a/3party/osrm/osrm-backend/Plugins/NearestPlugin.h +++ b/3party/osrm/osrm-backend/plugins/nearest.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,13 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef NEAREST_PLUGIN_H -#define NEAREST_PLUGIN_H +#ifndef NEAREST_HPP +#define NEAREST_HPP -#include "BasePlugin.h" -#include "../DataStructures/JSONContainer.h" -#include "../DataStructures/PhantomNodes.h" -#include "../DataStructures/Range.h" +#include "plugin_base.hpp" + +#include "../data_structures/phantom_node.hpp" +#include "../util/integer_range.hpp" +#include "../util/json_renderer.hpp" + +#include #include @@ -44,68 +47,66 @@ template class NearestPlugin final : public BasePlugin public: explicit NearestPlugin(DataFacadeT *facade) : facade(facade), descriptor_string("nearest") {} - const std::string GetDescriptor() const final { return descriptor_string; } + const std::string GetDescriptor() const override final { return descriptor_string; } - void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final + int HandleRequest(const RouteParameters &route_parameters, + osrm::json::Object &json_result) override final { // check number of parameters - if (route_parameters.coordinates.empty() || !route_parameters.coordinates.front().isValid()) + if (route_parameters.coordinates.empty() || + !route_parameters.coordinates.front().is_valid()) { - reply = http::Reply::StockReply(http::Reply::badRequest); - return; + return 400; } auto number_of_results = static_cast(route_parameters.num_results); std::vector phantom_node_vector; facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates.front(), phantom_node_vector, - route_parameters.zoom_level, static_cast(number_of_results)); - JSON::Object json_result; - if (phantom_node_vector.empty() || !phantom_node_vector.front().isValid()) + if (phantom_node_vector.empty() || !phantom_node_vector.front().is_valid()) { json_result.values["status"] = 207; } else { - reply.status = http::Reply::ok; + // reply.status = http::Reply::ok; json_result.values["status"] = 0; if (number_of_results > 1) { - JSON::Array results; + osrm::json::Array results; auto vector_length = phantom_node_vector.size(); - for (const auto i : osrm::irange(0, std::min(number_of_results, vector_length))) + for (const auto i : + osrm::irange(0, std::min(number_of_results, vector_length))) { - JSON::Array json_coordinate; - JSON::Object result; + osrm::json::Array json_coordinate; + osrm::json::Object result; json_coordinate.values.push_back(phantom_node_vector.at(i).location.lat / COORDINATE_PRECISION); json_coordinate.values.push_back(phantom_node_vector.at(i).location.lon / COORDINATE_PRECISION); result.values["mapped coordinate"] = json_coordinate; - std::string temp_string; - facade->GetName(phantom_node_vector.front().name_id, temp_string); - result.values["name"] = temp_string; + result.values["name"] = + facade->get_name_for_id(phantom_node_vector.at(i).name_id); results.values.push_back(result); } json_result.values["results"] = results; } else { - JSON::Array json_coordinate; + osrm::json::Array json_coordinate; json_coordinate.values.push_back(phantom_node_vector.front().location.lat / COORDINATE_PRECISION); json_coordinate.values.push_back(phantom_node_vector.front().location.lon / COORDINATE_PRECISION); json_result.values["mapped_coordinate"] = json_coordinate; - std::string temp_string; - facade->GetName(phantom_node_vector.front().name_id, temp_string); - json_result.values["name"] = temp_string; + json_result.values["name"] = + facade->get_name_for_id(phantom_node_vector.front().name_id); } } - JSON::render(reply.content, json_result); + return 200; } private: @@ -113,4 +114,4 @@ template class NearestPlugin final : public BasePlugin std::string descriptor_string; }; -#endif /* NEAREST_PLUGIN_H */ +#endif /* NEAREST_HPP */ diff --git a/3party/osrm/osrm-backend/Plugins/BasePlugin.h b/3party/osrm/osrm-backend/plugins/plugin_base.hpp old mode 100644 new mode 100755 similarity index 62% rename from 3party/osrm/osrm-backend/Plugins/BasePlugin.h rename to 3party/osrm/osrm-backend/plugins/plugin_base.hpp index 11c6940bba..acc820432f --- a/3party/osrm/osrm-backend/Plugins/BasePlugin.h +++ b/3party/osrm/osrm-backend/plugins/plugin_base.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,15 +25,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef BASEPLUGIN_H_ -#define BASEPLUGIN_H_ +#ifndef BASE_PLUGIN_HPP +#define BASE_PLUGIN_HPP -#include "../Util/StringUtil.h" - -#include -#include -#include +#include +#include +#include +#include #include #include @@ -44,7 +43,20 @@ class BasePlugin // Maybe someone can explain the pure virtual destructor thing to me (dennis) virtual ~BasePlugin() {} virtual const std::string GetDescriptor() const = 0; - virtual void HandleRequest(const RouteParameters &routeParameters, http::Reply &reply) = 0; + virtual int HandleRequest(const RouteParameters &, osrm::json::Object &) = 0; + virtual bool + check_all_coordinates(const std::vector &coordinates) const final + { + if (2 > coordinates.size() || std::any_of(std::begin(coordinates), std::end(coordinates), + [](const FixedPointCoordinate &coordinate) + { + return !coordinate.is_valid(); + })) + { + return false; + } + return true; + } }; -#endif /* BASEPLUGIN_H_ */ +#endif /* BASE_PLUGIN_HPP */ diff --git a/3party/osrm/osrm-backend/Plugins/TimestampPlugin.h b/3party/osrm/osrm-backend/plugins/timestamp.hpp old mode 100644 new mode 100755 similarity index 81% rename from 3party/osrm/osrm-backend/Plugins/TimestampPlugin.h rename to 3party/osrm/osrm-backend/plugins/timestamp.hpp index 0047db199b..8a5d208b79 --- a/3party/osrm/osrm-backend/Plugins/TimestampPlugin.h +++ b/3party/osrm/osrm-backend/plugins/timestamp.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -28,8 +28,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef TIMESTAMP_PLUGIN_H #define TIMESTAMP_PLUGIN_H -#include "../DataStructures/JSONContainer.h" -#include "BasePlugin.h" +#include "plugin_base.hpp" + +#include "../util/json_renderer.hpp" + +#include #include @@ -40,15 +43,14 @@ template class TimestampPlugin final : public BasePlugin : facade(facade), descriptor_string("timestamp") { } - const std::string GetDescriptor() const final { return descriptor_string; } - void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final + const std::string GetDescriptor() const override final { return descriptor_string; } + int HandleRequest(const RouteParameters &route_parameters, + osrm::json::Object &json_result) override final { - reply.status = http::Reply::ok; - JSON::Object json_result; json_result.values["status"] = 0; const std::string timestamp = facade->GetTimestamp(); json_result.values["timestamp"] = timestamp; - JSON::render(reply.content, json_result); + return 200; } private: diff --git a/3party/osrm/osrm-backend/plugins/viaroute.hpp b/3party/osrm/osrm-backend/plugins/viaroute.hpp new file mode 100755 index 0000000000..8eccc5af49 --- /dev/null +++ b/3party/osrm/osrm-backend/plugins/viaroute.hpp @@ -0,0 +1,192 @@ +/* + +Copyright (c) 2015, 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 VIA_ROUTE_HPP +#define VIA_ROUTE_HPP + +#include "plugin_base.hpp" + +#include "../algorithms/object_encoder.hpp" +#include "../data_structures/search_engine.hpp" +#include "../descriptors/descriptor_base.hpp" +#include "../descriptors/gpx_descriptor.hpp" +#include "../descriptors/json_descriptor.hpp" +#include "../util/integer_range.hpp" +#include "../util/json_renderer.hpp" +#include "../util/make_unique.hpp" +#include "../util/simple_logger.hpp" + +#include + +#include + +#include +#include +#include +#include + +template class ViaRoutePlugin final : public BasePlugin +{ + private: + DescriptorTable descriptor_table; + std::string descriptor_string; + std::unique_ptr> search_engine_ptr; + DataFacadeT *facade; + + public: + explicit ViaRoutePlugin(DataFacadeT *facade) : descriptor_string("viaroute"), facade(facade) + { + search_engine_ptr = osrm::make_unique>(facade); + + descriptor_table.emplace("json", 0); + descriptor_table.emplace("gpx", 1); + // descriptor_table.emplace("geojson", 2); + } + + virtual ~ViaRoutePlugin() {} + + const std::string GetDescriptor() const override final { return descriptor_string; } + + int HandleRequest(const RouteParameters &route_parameters, + osrm::json::Object &json_result) override final + { + if (!check_all_coordinates(route_parameters.coordinates)) + { + return 400; + } + + std::vector phantom_node_pair_list(route_parameters.coordinates.size()); + const bool checksum_OK = (route_parameters.check_sum == facade->GetCheckSum()); + + for (const auto i : osrm::irange(0, route_parameters.coordinates.size())) + { + if (checksum_OK && i < route_parameters.hints.size() && + !route_parameters.hints[i].empty()) + { + ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], + phantom_node_pair_list[i]); + if (phantom_node_pair_list[i].first.is_valid(facade->GetNumberOfNodes())) + { + continue; + } + } + std::vector phantom_node_vector; + if (facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates[i], + phantom_node_vector, 1)) + { + BOOST_ASSERT(!phantom_node_vector.empty()); + phantom_node_pair_list[i].first = phantom_node_vector.front(); + if (phantom_node_vector.size() > 1) + { + phantom_node_pair_list[i].second = phantom_node_vector.back(); + } + } + } + + auto check_component_id_is_tiny = [](const phantom_node_pair &phantom_pair) + { + return phantom_pair.first.component_id != 0; + }; + + const bool every_phantom_is_in_tiny_cc = + std::all_of(std::begin(phantom_node_pair_list), std::end(phantom_node_pair_list), + check_component_id_is_tiny); + + // are all phantoms from a tiny cc? + const auto component_id = phantom_node_pair_list.front().first.component_id; + + auto check_component_id_is_equal = [component_id](const phantom_node_pair &phantom_pair) + { + return component_id == phantom_pair.first.component_id; + }; + + const bool every_phantom_has_equal_id = + std::all_of(std::begin(phantom_node_pair_list), std::end(phantom_node_pair_list), + check_component_id_is_equal); + + auto swap_phantom_from_big_cc_into_front = [](phantom_node_pair &phantom_pair) + { + if (0 != phantom_pair.first.component_id) + { + using namespace std; + swap(phantom_pair.first, phantom_pair.second); + } + }; + + // this case is true if we take phantoms from the big CC + if (!every_phantom_is_in_tiny_cc || !every_phantom_has_equal_id) + { + std::for_each(std::begin(phantom_node_pair_list), std::end(phantom_node_pair_list), + swap_phantom_from_big_cc_into_front); + } + + InternalRouteResult raw_route; + auto build_phantom_pairs = + [&raw_route](const phantom_node_pair &first_pair, const phantom_node_pair &second_pair) + { + raw_route.segment_end_coordinates.emplace_back( + PhantomNodes{first_pair.first, second_pair.first}); + }; + osrm::for_each_pair(phantom_node_pair_list, build_phantom_pairs); + + if (route_parameters.alternate_route && 1 == raw_route.segment_end_coordinates.size()) + { + search_engine_ptr->alternative_path(raw_route.segment_end_coordinates.front(), + raw_route); + } + else + { + search_engine_ptr->shortest_path(raw_route.segment_end_coordinates, + route_parameters.uturns, raw_route); + } + + if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length) + { + SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found"; + } + + std::unique_ptr> descriptor; + switch (descriptor_table.get_id(route_parameters.output_format)) + { + case 1: + descriptor = osrm::make_unique>(facade); + break; + // case 2: + // descriptor = osrm::make_unique>(); + // break; + default: + descriptor = osrm::make_unique>(facade); + break; + } + + descriptor->SetConfig(route_parameters); + descriptor->Run(raw_route, json_result); + return 200; + } +}; + +#endif // VIA_ROUTE_HPP diff --git a/3party/osrm/osrm-backend/prepare.cpp b/3party/osrm/osrm-backend/prepare.cpp old mode 100644 new mode 100755 index 3cf397d0fe..af10df0358 --- a/3party/osrm/osrm-backend/prepare.cpp +++ b/3party/osrm/osrm-backend/prepare.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2013, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,9 +25,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "Contractor/Prepare.h" +#include "contractor/processing_chain.hpp" +#include "util/simple_logger.hpp" -#include +#include + +#include +#include int main(int argc, char *argv[]) { diff --git a/3party/osrm/osrm-backend/profile.lua b/3party/osrm/osrm-backend/profile.lua old mode 100644 new mode 100755 index ad58cd86ef..813afd19c4 --- a/3party/osrm/osrm-backend/profile.lua +++ b/3party/osrm/osrm-backend/profile.lua @@ -1,9 +1,9 @@ -- Begin of globals --require("lib/access") --function temporarily inlined -barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["checkpoint"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["no"] = true, ["entrance"] = true } +barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["checkpoint"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["lift_gate"] = true, ["no"] = true, ["entrance"] = true } access_tag_whitelist = { ["yes"] = true, ["motorcar"] = true, ["motor_vehicle"] = true, ["vehicle"] = true, ["permissive"] = true, ["designated"] = true } -access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestry"] = true, ["emergency"] = true } +access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestry"] = true, ["emergency"] = true, ["psv"] = true } access_tag_restricted = { ["destination"] = true, ["delivery"] = true } access_tags = { "motorcar", "motor_vehicle", "vehicle" } access_tags_hierachy = { "motorcar", "motor_vehicle", "vehicle", "access" } @@ -28,6 +28,7 @@ speed_profile = { ["service"] = 15, -- ["track"] = 5, ["ferry"] = 5, + ["movable"] = 5, ["shuttle_train"] = 10, ["default"] = 10 } @@ -103,6 +104,9 @@ maxspeed_table_default = { -- List only exceptions maxspeed_table = { + ["ch:rural"] = 80, + ["ch:trunk"] = 100, + ["ch:motorway"] = 120, ["de:living_street"] = 7, ["ru:living_street"] = 20, ["ru:urban"] = 60, @@ -124,11 +128,11 @@ maxspeed_table = { } traffic_signal_penalty = 2 +use_turn_restrictions = true local take_minimum_of_speeds = false local obey_oneway = true local obey_bollards = true -local use_turn_restrictions = true local ignore_areas = true -- future feature local u_turn_penalty = 20 @@ -141,16 +145,16 @@ local speed_reduction = 0.8 --modes local mode_normal = 1 local mode_ferry = 2 +local mode_movable_bridge = 3 - -local function find_access_tag(source,access_tags_hierachy) +local function find_access_tag(source, access_tags_hierachy) for i,v in ipairs(access_tags_hierachy) do - local has_tag = source.tags:Holds(v) - if has_tag then - return source.tags:Find(v) + local access_tag = source:get_value_by_key(v) + if access_tag and "" ~= access_tag then + return access_tag end end - return nil + return "" end function get_exceptions(vector) @@ -191,69 +195,64 @@ end -- return penalty -- end -function node_function (node) +function node_function (node, result) + -- parse access and barrier tags local access = find_access_tag(node, access_tags_hierachy) - - --flag node if it carries a traffic light - if node.tags:Holds("highway") then - if node.tags:Find("highway") == "traffic_signals" then - node.traffic_light = true; + if access ~= "" then + if access_tag_blacklist[access] then + result.barrier = true + end + else + local barrier = node:get_value_by_key("barrier") + if barrier and "" ~= barrier then + if not barrier_whitelist[barrier] then + result.barrier = true + end end end - -- parse access and barrier tags - if access and access ~= "" then - if access_tag_blacklist[access] then - node.bollard = true - end - elseif node.tags:Holds("barrier") then - local barrier = node.tags:Find("barrier") - if barrier_whitelist[barrier] then - return - else - node.bollard = true - end + -- check if node is a traffic light + local tag = node:get_value_by_key("highway") + if tag and "traffic_signals" == tag then + result.traffic_lights = true; end end -function way_function (way) +function way_function (way, result) + local highway = way:get_value_by_key("highway") + local route = way:get_value_by_key("route") + local bridge = way:get_value_by_key("bridge") - local is_highway = way.tags:Holds("highway") - local is_route = way.tags:Holds("route") - - if not (is_highway or is_route) then + if not ((highway and highway ~= "") or (route and route ~= "") or (bridge and bridge ~= "")) then return end -- we dont route over areas - local is_area = way.tags:Holds("area") - if ignore_areas and is_area then - local area = way.tags:Find("area") - if "yes" == area then - return - end - end - - -- check if oneway tag is unsupported - local oneway = way.tags:Find("oneway") - if "reversible" == oneway then + local area = way:get_value_by_key("area") + if ignore_areas and area and "yes" == area then return end - local is_impassable = way.tags:Holds("impassable") - if is_impassable then - local impassable = way.tags:Find("impassable") - if "yes" == impassable then - return - end + -- check if oneway tag is unsupported + local oneway = way:get_value_by_key("oneway") + if oneway and "reversible" == oneway then + return end - local is_status = way.tags:Holds("status") - if is_status then - local status = way.tags:Find("status") - if "impassable" == status then - return - end + local impassable = way:get_value_by_key("impassable") + if impassable and "yes" == impassable then + return + end + + local status = way:get_value_by_key("status") + if status and "impassable" == status then + return + end + + local width = math.huge + local width_string = way:get_value_by_key("width") + if width_string and tonumber(width_string:match("%d*")) then + width = tonumber(width_string:match("%d*")) end -- Check if we are allowed to access the way @@ -262,22 +261,33 @@ function way_function (way) return end - -- Second, parse the way according to these properties - local highway = way.tags:Find("highway") - local route = way.tags:Find("route") - - -- Handling ferries and piers + -- handling ferries and piers local route_speed = speed_profile[route] - if(route_speed and route_speed > 0) then + if (route_speed and route_speed > 0) then highway = route; - local duration = way.tags:Find("duration") - if durationIsValid(duration) then - way.duration = max( parseDuration(duration), 1 ); + local duration = way:get_value_by_key("duration") + if duration and durationIsValid(duration) then + result.duration = max( parseDuration(duration), 1 ); end - way.forward_mode = mode_ferry - way.backward_mode = mode_ferry - way.forward_speed = route_speed - way.backward_speed = route_speed + result.forward_mode = mode_ferry + result.backward_mode = mode_ferry + result.forward_speed = route_speed + result.backward_speed = route_speed + end + + -- handling movable bridges + local bridge_speed = speed_profile[bridge] + local capacity_car = way:get_value_by_key("capacity:car") + if (bridge_speed and bridge_speed > 0) and (capacity_car ~= 0) then + highway = bridge; + local duration = way:get_value_by_key("duration") + if duration and durationIsValid(duration) then + result.duration = max( parseDuration(duration), 1 ); + end + result.forward_mode = mode_movable_bridge + result.backward_mode = mode_movable_bridge + result.forward_speed = bridge_speed + result.backward_speed = bridge_speed end -- leave early of this way is not accessible @@ -285,122 +295,136 @@ function way_function (way) return end - if way.forward_speed == -1 then + if result.forward_speed == -1 then local highway_speed = speed_profile[highway] - local max_speed = parse_maxspeed( way.tags:Find("maxspeed") ) + local max_speed = parse_maxspeed( way:get_value_by_key("maxspeed") ) -- Set the avg speed on the way if it is accessible by road class if highway_speed then - if max_speed > highway_speed then - way.forward_speed = max_speed - way.backward_speed = max_speed + if max_speed and max_speed > highway_speed then + result.forward_speed = max_speed + result.backward_speed = max_speed -- max_speed = math.huge else - way.forward_speed = highway_speed - way.backward_speed = highway_speed + result.forward_speed = highway_speed + result.backward_speed = highway_speed end else -- Set the avg speed on ways that are marked accessible if access_tag_whitelist[access] then - way.forward_speed = speed_profile["default"] - way.backward_speed = speed_profile["default"] + result.forward_speed = speed_profile["default"] + result.backward_speed = speed_profile["default"] end end if 0 == max_speed then max_speed = math.huge end - way.forward_speed = min(way.forward_speed, max_speed) - way.backward_speed = min(way.backward_speed, max_speed) + result.forward_speed = min(result.forward_speed, max_speed) + result.backward_speed = min(result.backward_speed, max_speed) end - if -1 == way.forward_speed and -1 == way.backward_speed then + if -1 == result.forward_speed and -1 == result.backward_speed then return end -- reduce speed on bad surfaces - local surface = way.tags:Find("surface") - local tracktype = way.tags:Find("tracktype") - local smoothness = way.tags:Find("smoothness") + local surface = way:get_value_by_key("surface") + local tracktype = way:get_value_by_key("tracktype") + local smoothness = way:get_value_by_key("smoothness") if surface and surface_speeds[surface] then - way.forward_speed = math.min(surface_speeds[surface], way.forward_speed) - way.backward_speed = math.min(surface_speeds[surface], way.backward_speed) + result.forward_speed = math.min(surface_speeds[surface], result.forward_speed) + result.backward_speed = math.min(surface_speeds[surface], result.backward_speed) end if tracktype and tracktype_speeds[tracktype] then - way.forward_speed = math.min(tracktype_speeds[tracktype], way.forward_speed) - way.backward_speed = math.min(tracktype_speeds[tracktype], way.backward_speed) + result.forward_speed = math.min(tracktype_speeds[tracktype], result.forward_speed) + result.backward_speed = math.min(tracktype_speeds[tracktype], result.backward_speed) end if smoothness and smoothness_speeds[smoothness] then - way.forward_speed = math.min(smoothness_speeds[smoothness], way.forward_speed) - way.backward_speed = math.min(smoothness_speeds[smoothness], way.backward_speed) + result.forward_speed = math.min(smoothness_speeds[smoothness], result.forward_speed) + result.backward_speed = math.min(smoothness_speeds[smoothness], result.backward_speed) end -- parse the remaining tags - local name = way.tags:Find("name") - local ref = way.tags:Find("ref") - local junction = way.tags:Find("junction") - -- local barrier = way.tags:Find("barrier") - -- local cycleway = way.tags:Find("cycleway") - local service = way.tags:Find("service") + local name = way:get_value_by_key("name") + local ref = way:get_value_by_key("ref") + local junction = way:get_value_by_key("junction") + -- local barrier = way:get_value_by_key("barrier", "") + -- local cycleway = way:get_value_by_key("cycleway", "") + local service = way:get_value_by_key("service") -- Set the name that will be used for instructions - if "" ~= ref then - way.name = ref - elseif "" ~= name then - way.name = name + if ref and "" ~= ref then + result.name = ref + elseif name and "" ~= name then + result.name = name -- else - -- way.name = highway -- if no name exists, use way type + -- result.name = highway -- if no name exists, use way type end - if "roundabout" == junction then - way.roundabout = true; + if junction and "roundabout" == junction then + result.roundabout = true; end -- Set access restriction flag if access is allowed under certain restrictions only if access ~= "" and access_tag_restricted[access] then - way.is_access_restricted = true + result.is_access_restricted = true end -- Set access restriction flag if service is allowed under certain restrictions only - if service ~= "" and service_tag_restricted[service] then - way.is_access_restricted = true + if service and service ~= "" and service_tag_restricted[service] then + result.is_access_restricted = true end -- Set direction according to tags on way - if obey_oneway then + if obey_oneway then if oneway == "-1" then - way.forward_mode = 0 + result.forward_mode = 0 elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" or (highway == "motorway_link" and oneway ~="no") or (highway == "motorway" and oneway ~= "no") then - way.backward_mode = 0 + result.backward_mode = 0 end end -- Override speed settings if explicit forward/backward maxspeeds are given - local maxspeed_forward = parse_maxspeed(way.tags:Find( "maxspeed:forward")) - local maxspeed_backward = parse_maxspeed(way.tags:Find( "maxspeed:backward")) - if maxspeed_forward > 0 then - if 0 ~= way.forward_mode and 0 ~= way.backward_mode then - way.backward_speed = way.forward_speed + local maxspeed_forward = parse_maxspeed(way:get_value_by_key( "maxspeed:forward")) + local maxspeed_backward = parse_maxspeed(way:get_value_by_key( "maxspeed:backward")) + if maxspeed_forward and maxspeed_forward > 0 then + if 0 ~= result.forward_mode and 0 ~= result.backward_mode then + result.backward_speed = result.forward_speed end - way.forward_speed = maxspeed_forward + result.forward_speed = maxspeed_forward end - if maxspeed_backward > 0 then - way.backward_speed = maxspeed_backward + if maxspeed_backward and maxspeed_backward > 0 then + result.backward_speed = maxspeed_backward end -- Override general direction settings of there is a specific one for our mode of travel if ignore_in_grid[highway] then - way.ignore_in_grid = true + result.ignore_in_grid = true end + -- scale speeds to get better avg driving times - way.forward_speed = way.forward_speed * speed_reduction - if way.backward_speed > 0 then - way.backward_speed = way.backward_speed*speed_reduction + if result.forward_speed > 0 then + local scaled_speed = result.forward_speed*speed_reduction + 11; + local penalized_speed = math.huge + if width <= 3 then + penalized_speed = result.forward_speed / 2; + end + result.forward_speed = math.min(penalized_speed, scaled_speed) + end + + if result.backward_speed > 0 then + local scaled_speed = result.backward_speed*speed_reduction + 11; + local penalized_speed = math.huge + if width <= 3 then + penalized_speed = result.backward_speed / 2; + end + result.backward_speed = math.min(penalized_speed, scaled_speed) end end diff --git a/3party/osrm/osrm-backend/profiles/bicycle.lua b/3party/osrm/osrm-backend/profiles/bicycle.lua old mode 100644 new mode 100755 index 13bfd280db..497321ccf3 --- a/3party/osrm/osrm-backend/profiles/bicycle.lua +++ b/3party/osrm/osrm-backend/profiles/bicycle.lua @@ -66,6 +66,10 @@ route_speeds = { ["ferry"] = 5 } +bridge_speeds = { + ["movable"] = 5 +} + surface_speeds = { ["asphalt"] = default_speed, ["cobblestone:flattened"] = 10, @@ -102,7 +106,7 @@ mode_normal = 1 mode_pushing = 2 mode_ferry = 3 mode_train = 4 - +mode_movable_bridge = 5 local function parse_maxspeed(source) if not source then @@ -125,48 +129,48 @@ function get_exceptions(vector) end end -function node_function (node) - local barrier = node.tags:Find ("barrier") +function node_function (node, result) + local barrier = node:get_value_by_key("barrier") local access = Access.find_access_tag(node, access_tags_hierachy) - local traffic_signal = node.tags:Find("highway") + local traffic_signal = node:get_value_by_key("highway") -- flag node if it carries a traffic light - if traffic_signal == "traffic_signals" then - node.traffic_light = true + if traffic_signal and traffic_signal == "traffic_signals" then + result.traffic_lights = true end -- parse access and barrier tags if access and access ~= "" then if access_tag_blacklist[access] then - node.bollard = true + result.barrier = true else - node.bollard = false + result.barrier = false end elseif barrier and barrier ~= "" then if barrier_whitelist[barrier] then - node.bollard = false + result.barrier = false else - node.bollard = true + result.barrier = true end end - - -- return 1 end -function way_function (way) +function way_function (way, result) -- initial routability check, filters out buildings, boundaries, etc - local highway = way.tags:Find("highway") - local route = way.tags:Find("route") - local man_made = way.tags:Find("man_made") - local railway = way.tags:Find("railway") - local amenity = way.tags:Find("amenity") - local public_transport = way.tags:Find("public_transport") + local highway = way:get_value_by_key("highway") + local route = way:get_value_by_key("route") + local man_made = way:get_value_by_key("man_made") + local railway = way:get_value_by_key("railway") + local amenity = way:get_value_by_key("amenity") + local public_transport = way:get_value_by_key("public_transport") + local bridge = way:get_value_by_key("bridge") if (not highway or highway == '') and (not route or route == '') and (not railway or railway=='') and (not amenity or amenity=='') and (not man_made or man_made=='') and - (not public_transport or public_transport=='') + (not public_transport or public_transport=='') and + (not bridge or bridge=='') then return end @@ -178,117 +182,127 @@ function way_function (way) -- access local access = Access.find_access_tag(way, access_tags_hierachy) - if access_tag_blacklist[access] then + if access and access_tag_blacklist[access] then return end -- other tags - local name = way.tags:Find("name") - local ref = way.tags:Find("ref") - local junction = way.tags:Find("junction") - local maxspeed = parse_maxspeed(way.tags:Find ( "maxspeed") ) - local maxspeed_forward = parse_maxspeed(way.tags:Find( "maxspeed:forward")) - local maxspeed_backward = parse_maxspeed(way.tags:Find( "maxspeed:backward")) - local barrier = way.tags:Find("barrier") - local oneway = way.tags:Find("oneway") - local onewayClass = way.tags:Find("oneway:bicycle") - local cycleway = way.tags:Find("cycleway") - local cycleway_left = way.tags:Find("cycleway:left") - local cycleway_right = way.tags:Find("cycleway:right") - local duration = way.tags:Find("duration") - local service = way.tags:Find("service") - local area = way.tags:Find("area") - local foot = way.tags:Find("foot") - local surface = way.tags:Find("surface") - local bicycle = way.tags:Find("bicycle") + local name = way:get_value_by_key("name") + local ref = way:get_value_by_key("ref") + local junction = way:get_value_by_key("junction") + local maxspeed = parse_maxspeed(way:get_value_by_key ( "maxspeed") ) + local maxspeed_forward = parse_maxspeed(way:get_value_by_key( "maxspeed:forward")) + local maxspeed_backward = parse_maxspeed(way:get_value_by_key( "maxspeed:backward")) + local barrier = way:get_value_by_key("barrier") + local oneway = way:get_value_by_key("oneway") + local onewayClass = way:get_value_by_key("oneway:bicycle") + local cycleway = way:get_value_by_key("cycleway") + local cycleway_left = way:get_value_by_key("cycleway:left") + local cycleway_right = way:get_value_by_key("cycleway:right") + local duration = way:get_value_by_key("duration") + local service = way:get_value_by_key("service") + local area = way:get_value_by_key("area") + local foot = way:get_value_by_key("foot") + local surface = way:get_value_by_key("surface") + local bicycle = way:get_value_by_key("bicycle") -- name - if "" ~= ref and "" ~= name then - way.name = name .. ' / ' .. ref - elseif "" ~= ref then - way.name = ref - elseif "" ~= name then - way.name = name - else + if ref and "" ~= ref and name and "" ~= name then + result.name = name .. ' / ' .. ref + elseif ref and "" ~= ref then + result.name = ref + elseif name and "" ~= name then + result.name = name + elseif highway then -- if no name exists, use way type -- this encoding scheme is excepted to be a temporary solution - way.name = "{highway:"..highway.."}" + result.name = "{highway:"..highway.."}" end -- roundabout handling - if "roundabout" == junction then - way.roundabout = true; + if junction and "roundabout" == junction then + result.roundabout = true; end -- speed - if route_speeds[route] then + local bridge_speed = bridge_speeds[bridge] + if (bridge_speed and bridge_speed > 0) then + highway = bridge; + if duration and durationIsValid(duration) then + result.duration = math.max( parseDuration(duration), 1 ); + end + result.forward_mode = mode_movable_bridge + result.backward_mode = mode_movable_bridge + result.forward_speed = bridge_speed + result.backward_speed = bridge_speed + elseif route_speeds[route] then -- ferries (doesn't cover routes tagged using relations) - way.forward_mode = mode_ferry - way.backward_mode = mode_ferry - way.ignore_in_grid = true - if durationIsValid(duration) then - way.duration = math.max( 1, parseDuration(duration) ) + result.forward_mode = mode_ferry + result.backward_mode = mode_ferry + result.ignore_in_grid = true + if duration and durationIsValid(duration) then + result.duration = math.max( 1, parseDuration(duration) ) else - way.forward_speed = route_speeds[route] - way.backward_speed = route_speeds[route] + result.forward_speed = route_speeds[route] + result.backward_speed = route_speeds[route] end elseif railway and platform_speeds[railway] then -- railway platforms (old tagging scheme) - way.forward_speed = platform_speeds[railway] - way.backward_speed = platform_speeds[railway] + result.forward_speed = platform_speeds[railway] + result.backward_speed = platform_speeds[railway] elseif platform_speeds[public_transport] then -- public_transport platforms (new tagging platform) - way.forward_speed = platform_speeds[public_transport] - way.backward_speed = platform_speeds[public_transport] + result.forward_speed = platform_speeds[public_transport] + result.backward_speed = platform_speeds[public_transport] elseif railway and railway_speeds[railway] then - way.forward_mode = mode_train - way.backward_mode = mode_train + result.forward_mode = mode_train + result.backward_mode = mode_train -- railways if access and access_tag_whitelist[access] then - way.forward_speed = railway_speeds[railway] - way.backward_speed = railway_speeds[railway] + result.forward_speed = railway_speeds[railway] + result.backward_speed = railway_speeds[railway] end elseif amenity and amenity_speeds[amenity] then -- parking areas - way.forward_speed = amenity_speeds[amenity] - way.backward_speed = amenity_speeds[amenity] + result.forward_speed = amenity_speeds[amenity] + result.backward_speed = amenity_speeds[amenity] elseif bicycle_speeds[highway] then -- regular ways - way.forward_speed = bicycle_speeds[highway] - way.backward_speed = bicycle_speeds[highway] + result.forward_speed = bicycle_speeds[highway] + result.backward_speed = bicycle_speeds[highway] elseif access and access_tag_whitelist[access] then -- unknown way, but valid access tag - way.forward_speed = default_speed - way.backward_speed = default_speed + result.forward_speed = default_speed + result.backward_speed = default_speed else -- biking not allowed, maybe we can push our bike? -- essentially requires pedestrian profiling, for example foot=no mean we can't push a bike if foot ~= 'no' and junction ~= "roundabout" then if pedestrian_speeds[highway] then -- pedestrian-only ways and areas - way.forward_speed = pedestrian_speeds[highway] - way.backward_speed = pedestrian_speeds[highway] - way.forward_mode = mode_pushing - way.backward_mode = mode_pushing + result.forward_speed = pedestrian_speeds[highway] + result.backward_speed = pedestrian_speeds[highway] + result.forward_mode = mode_pushing + result.backward_mode = mode_pushing elseif man_made and man_made_speeds[man_made] then -- man made structures - way.forward_speed = man_made_speeds[man_made] - way.backward_speed = man_made_speeds[man_made] - way.forward_mode = mode_pushing - way.backward_mode = mode_pushing + result.forward_speed = man_made_speeds[man_made] + result.backward_speed = man_made_speeds[man_made] + result.forward_mode = mode_pushing + result.backward_mode = mode_pushing elseif foot == 'yes' then - way.forward_speed = walking_speed - way.backward_speed = walking_speed - way.forward_mode = mode_pushing - way.backward_mode = mode_pushing + result.forward_speed = walking_speed + result.backward_speed = walking_speed + result.forward_mode = mode_pushing + result.backward_mode = mode_pushing elseif foot_forward == 'yes' then - way.forward_speed = walking_speed - way.forward_mode = mode_pushing - way.backward_mode = 0 + result.forward_speed = walking_speed + result.forward_mode = mode_pushing + result.backward_mode = 0 elseif foot_backward == 'yes' then - way.forward_speed = walking_speed - way.forward_mode = 0 - way.backward_mode = mode_pushing + result.forward_speed = walking_speed + result.forward_mode = 0 + result.backward_mode = mode_pushing end end end @@ -300,84 +314,84 @@ function way_function (way) end if onewayClass == "yes" or onewayClass == "1" or onewayClass == "true" then - way.backward_mode = 0 + result.backward_mode = 0 elseif onewayClass == "no" or onewayClass == "0" or onewayClass == "false" then -- prevent implied oneway elseif onewayClass == "-1" then - way.forward_mode = 0 + result.forward_mode = 0 elseif oneway == "no" or oneway == "0" or oneway == "false" then -- prevent implied oneway elseif cycleway and string.find(cycleway, "opposite") == 1 then if impliedOneway then - way.forward_mode = 0 - way.backward_mode = mode_normal - way.backward_speed = bicycle_speeds["cycleway"] + result.forward_mode = 0 + result.backward_mode = mode_normal + result.backward_speed = bicycle_speeds["cycleway"] end elseif cycleway_left and cycleway_tags[cycleway_left] and cycleway_right and cycleway_tags[cycleway_right] then -- prevent implied elseif cycleway_left and cycleway_tags[cycleway_left] then if impliedOneway then - way.forward_mode = 0 - way.backward_mode = mode_normal - way.backward_speed = bicycle_speeds["cycleway"] + result.forward_mode = 0 + result.backward_mode = mode_normal + result.backward_speed = bicycle_speeds["cycleway"] end elseif cycleway_right and cycleway_tags[cycleway_right] then if impliedOneway then - way.forward_mode = mode_normal - way.backward_speed = bicycle_speeds["cycleway"] - way.backward_mode = 0 + result.forward_mode = mode_normal + result.backward_speed = bicycle_speeds["cycleway"] + result.backward_mode = 0 end elseif oneway == "-1" then - way.forward_mode = 0 + result.forward_mode = 0 elseif oneway == "yes" or oneway == "1" or oneway == "true" or impliedOneway then - way.backward_mode = 0 + result.backward_mode = 0 end -- pushing bikes if bicycle_speeds[highway] or pedestrian_speeds[highway] then if foot ~= "no" and junction ~= "roundabout" then - if way.backward_mode == 0 then - way.backward_speed = walking_speed - way.backward_mode = mode_pushing - elseif way.forward_mode == 0 then - way.forward_speed = walking_speed - way.forward_mode = mode_pushing + if result.backward_mode == 0 then + result.backward_speed = walking_speed + result.backward_mode = mode_pushing + elseif result.forward_mode == 0 then + result.forward_speed = walking_speed + result.forward_mode = mode_pushing end end end -- cycleways if cycleway and cycleway_tags[cycleway] then - way.forward_speed = bicycle_speeds["cycleway"] + result.forward_speed = bicycle_speeds["cycleway"] elseif cycleway_left and cycleway_tags[cycleway_left] then - way.forward_speed = bicycle_speeds["cycleway"] + result.forward_speed = bicycle_speeds["cycleway"] elseif cycleway_right and cycleway_tags[cycleway_right] then - way.forward_speed = bicycle_speeds["cycleway"] + result.forward_speed = bicycle_speeds["cycleway"] end -- dismount if bicycle == "dismount" then - way.forward_mode = mode_pushing - way.backward_mode = mode_pushing - way.forward_speed = walking_speed - way.backward_speed = walking_speed + result.forward_mode = mode_pushing + result.backward_mode = mode_pushing + result.forward_speed = walking_speed + result.backward_speed = walking_speed end -- surfaces if surface then surface_speed = surface_speeds[surface] if surface_speed then - if way.forward_speed > 0 then - way.forward_speed = surface_speed + if result.forward_speed > 0 then + result.forward_speed = surface_speed end - if way.backward_speed > 0 then - way.backward_speed = surface_speed + if result.backward_speed > 0 then + result.backward_speed = surface_speed end end end -- maxspeed - MaxSpeed.limit( way, maxspeed, maxspeed_forward, maxspeed_backward ) + MaxSpeed.limit( result, maxspeed, maxspeed_forward, maxspeed_backward ) end function turn_function (angle) diff --git a/3party/osrm/osrm-backend/profiles/car.lua b/3party/osrm/osrm-backend/profiles/car.lua old mode 100644 new mode 100755 index ad58cd86ef..813afd19c4 --- a/3party/osrm/osrm-backend/profiles/car.lua +++ b/3party/osrm/osrm-backend/profiles/car.lua @@ -1,9 +1,9 @@ -- Begin of globals --require("lib/access") --function temporarily inlined -barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["checkpoint"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["no"] = true, ["entrance"] = true } +barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["checkpoint"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["lift_gate"] = true, ["no"] = true, ["entrance"] = true } access_tag_whitelist = { ["yes"] = true, ["motorcar"] = true, ["motor_vehicle"] = true, ["vehicle"] = true, ["permissive"] = true, ["designated"] = true } -access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestry"] = true, ["emergency"] = true } +access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestry"] = true, ["emergency"] = true, ["psv"] = true } access_tag_restricted = { ["destination"] = true, ["delivery"] = true } access_tags = { "motorcar", "motor_vehicle", "vehicle" } access_tags_hierachy = { "motorcar", "motor_vehicle", "vehicle", "access" } @@ -28,6 +28,7 @@ speed_profile = { ["service"] = 15, -- ["track"] = 5, ["ferry"] = 5, + ["movable"] = 5, ["shuttle_train"] = 10, ["default"] = 10 } @@ -103,6 +104,9 @@ maxspeed_table_default = { -- List only exceptions maxspeed_table = { + ["ch:rural"] = 80, + ["ch:trunk"] = 100, + ["ch:motorway"] = 120, ["de:living_street"] = 7, ["ru:living_street"] = 20, ["ru:urban"] = 60, @@ -124,11 +128,11 @@ maxspeed_table = { } traffic_signal_penalty = 2 +use_turn_restrictions = true local take_minimum_of_speeds = false local obey_oneway = true local obey_bollards = true -local use_turn_restrictions = true local ignore_areas = true -- future feature local u_turn_penalty = 20 @@ -141,16 +145,16 @@ local speed_reduction = 0.8 --modes local mode_normal = 1 local mode_ferry = 2 +local mode_movable_bridge = 3 - -local function find_access_tag(source,access_tags_hierachy) +local function find_access_tag(source, access_tags_hierachy) for i,v in ipairs(access_tags_hierachy) do - local has_tag = source.tags:Holds(v) - if has_tag then - return source.tags:Find(v) + local access_tag = source:get_value_by_key(v) + if access_tag and "" ~= access_tag then + return access_tag end end - return nil + return "" end function get_exceptions(vector) @@ -191,69 +195,64 @@ end -- return penalty -- end -function node_function (node) +function node_function (node, result) + -- parse access and barrier tags local access = find_access_tag(node, access_tags_hierachy) - - --flag node if it carries a traffic light - if node.tags:Holds("highway") then - if node.tags:Find("highway") == "traffic_signals" then - node.traffic_light = true; + if access ~= "" then + if access_tag_blacklist[access] then + result.barrier = true + end + else + local barrier = node:get_value_by_key("barrier") + if barrier and "" ~= barrier then + if not barrier_whitelist[barrier] then + result.barrier = true + end end end - -- parse access and barrier tags - if access and access ~= "" then - if access_tag_blacklist[access] then - node.bollard = true - end - elseif node.tags:Holds("barrier") then - local barrier = node.tags:Find("barrier") - if barrier_whitelist[barrier] then - return - else - node.bollard = true - end + -- check if node is a traffic light + local tag = node:get_value_by_key("highway") + if tag and "traffic_signals" == tag then + result.traffic_lights = true; end end -function way_function (way) +function way_function (way, result) + local highway = way:get_value_by_key("highway") + local route = way:get_value_by_key("route") + local bridge = way:get_value_by_key("bridge") - local is_highway = way.tags:Holds("highway") - local is_route = way.tags:Holds("route") - - if not (is_highway or is_route) then + if not ((highway and highway ~= "") or (route and route ~= "") or (bridge and bridge ~= "")) then return end -- we dont route over areas - local is_area = way.tags:Holds("area") - if ignore_areas and is_area then - local area = way.tags:Find("area") - if "yes" == area then - return - end - end - - -- check if oneway tag is unsupported - local oneway = way.tags:Find("oneway") - if "reversible" == oneway then + local area = way:get_value_by_key("area") + if ignore_areas and area and "yes" == area then return end - local is_impassable = way.tags:Holds("impassable") - if is_impassable then - local impassable = way.tags:Find("impassable") - if "yes" == impassable then - return - end + -- check if oneway tag is unsupported + local oneway = way:get_value_by_key("oneway") + if oneway and "reversible" == oneway then + return end - local is_status = way.tags:Holds("status") - if is_status then - local status = way.tags:Find("status") - if "impassable" == status then - return - end + local impassable = way:get_value_by_key("impassable") + if impassable and "yes" == impassable then + return + end + + local status = way:get_value_by_key("status") + if status and "impassable" == status then + return + end + + local width = math.huge + local width_string = way:get_value_by_key("width") + if width_string and tonumber(width_string:match("%d*")) then + width = tonumber(width_string:match("%d*")) end -- Check if we are allowed to access the way @@ -262,22 +261,33 @@ function way_function (way) return end - -- Second, parse the way according to these properties - local highway = way.tags:Find("highway") - local route = way.tags:Find("route") - - -- Handling ferries and piers + -- handling ferries and piers local route_speed = speed_profile[route] - if(route_speed and route_speed > 0) then + if (route_speed and route_speed > 0) then highway = route; - local duration = way.tags:Find("duration") - if durationIsValid(duration) then - way.duration = max( parseDuration(duration), 1 ); + local duration = way:get_value_by_key("duration") + if duration and durationIsValid(duration) then + result.duration = max( parseDuration(duration), 1 ); end - way.forward_mode = mode_ferry - way.backward_mode = mode_ferry - way.forward_speed = route_speed - way.backward_speed = route_speed + result.forward_mode = mode_ferry + result.backward_mode = mode_ferry + result.forward_speed = route_speed + result.backward_speed = route_speed + end + + -- handling movable bridges + local bridge_speed = speed_profile[bridge] + local capacity_car = way:get_value_by_key("capacity:car") + if (bridge_speed and bridge_speed > 0) and (capacity_car ~= 0) then + highway = bridge; + local duration = way:get_value_by_key("duration") + if duration and durationIsValid(duration) then + result.duration = max( parseDuration(duration), 1 ); + end + result.forward_mode = mode_movable_bridge + result.backward_mode = mode_movable_bridge + result.forward_speed = bridge_speed + result.backward_speed = bridge_speed end -- leave early of this way is not accessible @@ -285,122 +295,136 @@ function way_function (way) return end - if way.forward_speed == -1 then + if result.forward_speed == -1 then local highway_speed = speed_profile[highway] - local max_speed = parse_maxspeed( way.tags:Find("maxspeed") ) + local max_speed = parse_maxspeed( way:get_value_by_key("maxspeed") ) -- Set the avg speed on the way if it is accessible by road class if highway_speed then - if max_speed > highway_speed then - way.forward_speed = max_speed - way.backward_speed = max_speed + if max_speed and max_speed > highway_speed then + result.forward_speed = max_speed + result.backward_speed = max_speed -- max_speed = math.huge else - way.forward_speed = highway_speed - way.backward_speed = highway_speed + result.forward_speed = highway_speed + result.backward_speed = highway_speed end else -- Set the avg speed on ways that are marked accessible if access_tag_whitelist[access] then - way.forward_speed = speed_profile["default"] - way.backward_speed = speed_profile["default"] + result.forward_speed = speed_profile["default"] + result.backward_speed = speed_profile["default"] end end if 0 == max_speed then max_speed = math.huge end - way.forward_speed = min(way.forward_speed, max_speed) - way.backward_speed = min(way.backward_speed, max_speed) + result.forward_speed = min(result.forward_speed, max_speed) + result.backward_speed = min(result.backward_speed, max_speed) end - if -1 == way.forward_speed and -1 == way.backward_speed then + if -1 == result.forward_speed and -1 == result.backward_speed then return end -- reduce speed on bad surfaces - local surface = way.tags:Find("surface") - local tracktype = way.tags:Find("tracktype") - local smoothness = way.tags:Find("smoothness") + local surface = way:get_value_by_key("surface") + local tracktype = way:get_value_by_key("tracktype") + local smoothness = way:get_value_by_key("smoothness") if surface and surface_speeds[surface] then - way.forward_speed = math.min(surface_speeds[surface], way.forward_speed) - way.backward_speed = math.min(surface_speeds[surface], way.backward_speed) + result.forward_speed = math.min(surface_speeds[surface], result.forward_speed) + result.backward_speed = math.min(surface_speeds[surface], result.backward_speed) end if tracktype and tracktype_speeds[tracktype] then - way.forward_speed = math.min(tracktype_speeds[tracktype], way.forward_speed) - way.backward_speed = math.min(tracktype_speeds[tracktype], way.backward_speed) + result.forward_speed = math.min(tracktype_speeds[tracktype], result.forward_speed) + result.backward_speed = math.min(tracktype_speeds[tracktype], result.backward_speed) end if smoothness and smoothness_speeds[smoothness] then - way.forward_speed = math.min(smoothness_speeds[smoothness], way.forward_speed) - way.backward_speed = math.min(smoothness_speeds[smoothness], way.backward_speed) + result.forward_speed = math.min(smoothness_speeds[smoothness], result.forward_speed) + result.backward_speed = math.min(smoothness_speeds[smoothness], result.backward_speed) end -- parse the remaining tags - local name = way.tags:Find("name") - local ref = way.tags:Find("ref") - local junction = way.tags:Find("junction") - -- local barrier = way.tags:Find("barrier") - -- local cycleway = way.tags:Find("cycleway") - local service = way.tags:Find("service") + local name = way:get_value_by_key("name") + local ref = way:get_value_by_key("ref") + local junction = way:get_value_by_key("junction") + -- local barrier = way:get_value_by_key("barrier", "") + -- local cycleway = way:get_value_by_key("cycleway", "") + local service = way:get_value_by_key("service") -- Set the name that will be used for instructions - if "" ~= ref then - way.name = ref - elseif "" ~= name then - way.name = name + if ref and "" ~= ref then + result.name = ref + elseif name and "" ~= name then + result.name = name -- else - -- way.name = highway -- if no name exists, use way type + -- result.name = highway -- if no name exists, use way type end - if "roundabout" == junction then - way.roundabout = true; + if junction and "roundabout" == junction then + result.roundabout = true; end -- Set access restriction flag if access is allowed under certain restrictions only if access ~= "" and access_tag_restricted[access] then - way.is_access_restricted = true + result.is_access_restricted = true end -- Set access restriction flag if service is allowed under certain restrictions only - if service ~= "" and service_tag_restricted[service] then - way.is_access_restricted = true + if service and service ~= "" and service_tag_restricted[service] then + result.is_access_restricted = true end -- Set direction according to tags on way - if obey_oneway then + if obey_oneway then if oneway == "-1" then - way.forward_mode = 0 + result.forward_mode = 0 elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" or (highway == "motorway_link" and oneway ~="no") or (highway == "motorway" and oneway ~= "no") then - way.backward_mode = 0 + result.backward_mode = 0 end end -- Override speed settings if explicit forward/backward maxspeeds are given - local maxspeed_forward = parse_maxspeed(way.tags:Find( "maxspeed:forward")) - local maxspeed_backward = parse_maxspeed(way.tags:Find( "maxspeed:backward")) - if maxspeed_forward > 0 then - if 0 ~= way.forward_mode and 0 ~= way.backward_mode then - way.backward_speed = way.forward_speed + local maxspeed_forward = parse_maxspeed(way:get_value_by_key( "maxspeed:forward")) + local maxspeed_backward = parse_maxspeed(way:get_value_by_key( "maxspeed:backward")) + if maxspeed_forward and maxspeed_forward > 0 then + if 0 ~= result.forward_mode and 0 ~= result.backward_mode then + result.backward_speed = result.forward_speed end - way.forward_speed = maxspeed_forward + result.forward_speed = maxspeed_forward end - if maxspeed_backward > 0 then - way.backward_speed = maxspeed_backward + if maxspeed_backward and maxspeed_backward > 0 then + result.backward_speed = maxspeed_backward end -- Override general direction settings of there is a specific one for our mode of travel if ignore_in_grid[highway] then - way.ignore_in_grid = true + result.ignore_in_grid = true end + -- scale speeds to get better avg driving times - way.forward_speed = way.forward_speed * speed_reduction - if way.backward_speed > 0 then - way.backward_speed = way.backward_speed*speed_reduction + if result.forward_speed > 0 then + local scaled_speed = result.forward_speed*speed_reduction + 11; + local penalized_speed = math.huge + if width <= 3 then + penalized_speed = result.forward_speed / 2; + end + result.forward_speed = math.min(penalized_speed, scaled_speed) + end + + if result.backward_speed > 0 then + local scaled_speed = result.backward_speed*speed_reduction + 11; + local penalized_speed = math.huge + if width <= 3 then + penalized_speed = result.backward_speed / 2; + end + result.backward_speed = math.min(penalized_speed, scaled_speed) end end diff --git a/3party/osrm/osrm-backend/profiles/examples/postgis.lua b/3party/osrm/osrm-backend/profiles/examples/postgis.lua old mode 100644 new mode 100755 index b02a43d8a5..6e32e4c7f0 --- a/3party/osrm/osrm-backend/profiles/examples/postgis.lua +++ b/3party/osrm/osrm-backend/profiles/examples/postgis.lua @@ -53,8 +53,8 @@ function way_function (way) end -- Query PostGIS for industrial areas close to the way, then group by way and sum the areas. - -- We take the square root of the area to get a estimate of the length of the side of the area, - -- and thus a rough guess of how far we might be travelling along the area. + -- We take the square root of the area to get a estimate of the length of the side of the area, + -- and thus a rough guess of how far we might be travelling along the area. local sql_query = " " .. "SELECT SUM(SQRT(area.area)) AS val " .. @@ -67,16 +67,16 @@ function way_function (way) local row = cursor:fetch( {}, "a" ) -- fetch first (and only) row way.forward_speed = 20.0 -- default speed if row then - local val = tonumber(row.val) -- read 'val' from row + local val = tonumber(row.val) -- read 'val' from row if val > 10 then - way.forward_speed = way.forward_speed / math.log10( val ) -- reduce speed by amount of industry close by + way.forward_speed = way.forward_speed / math.log10( val ) -- reduce speed by amount of industry close by end end cursor:close() -- done with this query -- set other required info for this way way.name = way.tags:Find("name") - way.direction = Way.bidirectional + way.direction = Way.bidirectional way.type = 1 return 1 end diff --git a/3party/osrm/osrm-backend/profiles/foot.lua b/3party/osrm/osrm-backend/profiles/foot.lua old mode 100644 new mode 100755 index 7c366bf119..5a370971a5 --- a/3party/osrm/osrm-backend/profiles/foot.lua +++ b/3party/osrm/osrm-backend/profiles/foot.lua @@ -73,42 +73,42 @@ function get_exceptions(vector) end end -function node_function (node) - local barrier = node.tags:Find ("barrier") +function node_function (node, result) + local barrier = node:get_value_by_key("barrier") local access = Access.find_access_tag(node, access_tags_hierachy) - local traffic_signal = node.tags:Find("highway") + local traffic_signal = node:get_value_by_key("highway") -- flag node if it carries a traffic light - if traffic_signal == "traffic_signals" then - node.traffic_light = true + if traffic_signal and traffic_signal == "traffic_signals" then + result.traffic_light = true end -- parse access and barrier tags if access and access ~= "" then if access_tag_blacklist[access] then - node.bollard = true + result.barrier = true else - node.bollard = false + result.barrier = false end elseif barrier and barrier ~= "" then if barrier_whitelist[barrier] then - node.bollard = false + result.barrier = false else - node.bollard = true + result.barrier = true end end return 1 end -function way_function (way) +function way_function (way, result) -- initial routability check, filters out buildings, boundaries, etc - local highway = way.tags:Find("highway") - local route = way.tags:Find("route") - local man_made = way.tags:Find("man_made") - local railway = way.tags:Find("railway") - local amenity = way.tags:Find("amenity") - local public_transport = way.tags:Find("public_transport") + local highway = way:get_value_by_key("highway") + local route = way:get_value_by_key("route") + local man_made = way:get_value_by_key("man_made") + local railway = way:get_value_by_key("railway") + local amenity = way:get_value_by_key("amenity") + local public_transport = way:get_value_by_key("public_transport") if (not highway or highway == '') and (not route or route == '') and (not railway or railway=='') and @@ -130,82 +130,82 @@ function way_function (way) return end - local name = way.tags:Find("name") - local ref = way.tags:Find("ref") - local junction = way.tags:Find("junction") - local onewayClass = way.tags:Find("oneway:foot") - local duration = way.tags:Find("duration") - local service = way.tags:Find("service") - local area = way.tags:Find("area") - local foot = way.tags:Find("foot") - local surface = way.tags:Find("surface") + local name = way:get_value_by_key("name") + local ref = way:get_value_by_key("ref") + local junction = way:get_value_by_key("junction") + local onewayClass = way:get_value_by_key("oneway:foot") + local duration = way:get_value_by_key("duration") + local service = way:get_value_by_key("service") + local area = way:get_value_by_key("area") + local foot = way:get_value_by_key("foot") + local surface = way:get_value_by_key("surface") - -- name - if "" ~= ref and "" ~= name then - way.name = name .. ' / ' .. ref - elseif "" ~= ref then - way.name = ref - elseif "" ~= name then - way.name = name - else - way.name = "{highway:"..highway.."}" -- if no name exists, use way type + -- name + if ref and "" ~= ref and name and "" ~= name then + result.name = name .. ' / ' .. ref + elseif ref and "" ~= ref then + result.name = ref + elseif name and "" ~= name then + result.name = name + elseif highway then + result.name = "{highway:"..highway.."}" -- if no name exists, use way type -- this encoding scheme is excepted to be a temporary solution end -- roundabouts if "roundabout" == junction then - way.roundabout = true; + result.roundabout = true; end -- speed if route_speeds[route] then -- ferries (doesn't cover routes tagged using relations) - way.ignore_in_grid = true - if durationIsValid(duration) then - way.duration = math.max( 1, parseDuration(duration) ) + result.ignore_in_grid = true + if duration and durationIsValid(duration) then + result.duration = math.max( 1, parseDuration(duration) ) else - way.forward_speed = route_speeds[route] - way.backward_speed = route_speeds[route] + result.forward_speed = route_speeds[route] + result.backward_speed = route_speeds[route] end - way.forward_mode = mode_ferry - way.backward_mode = mode_ferry + result.forward_mode = mode_ferry + result.backward_mode = mode_ferry elseif railway and platform_speeds[railway] then -- railway platforms (old tagging scheme) - way.forward_speed = platform_speeds[railway] - way.backward_speed = platform_speeds[railway] + result.forward_speed = platform_speeds[railway] + result.backward_speed = platform_speeds[railway] elseif platform_speeds[public_transport] then -- public_transport platforms (new tagging platform) - way.forward_speed = platform_speeds[public_transport] - way.backward_speed = platform_speeds[public_transport] + result.forward_speed = platform_speeds[public_transport] + result.backward_speed = platform_speeds[public_transport] elseif amenity and amenity_speeds[amenity] then -- parking areas - way.forward_speed = amenity_speeds[amenity] - way.backward_speed = amenity_speeds[amenity] + result.forward_speed = amenity_speeds[amenity] + result.backward_speed = amenity_speeds[amenity] elseif speeds[highway] then -- regular ways - way.forward_speed = speeds[highway] - way.backward_speed = speeds[highway] + result.forward_speed = speeds[highway] + result.backward_speed = speeds[highway] elseif access and access_tag_whitelist[access] then -- unknown way, but valid access tag - way.forward_speed = walking_speed - way.backward_speed = walking_speed + result.forward_speed = walking_speed + result.backward_speed = walking_speed end -- oneway if onewayClass == "yes" or onewayClass == "1" or onewayClass == "true" then - way.backward_mode = 0 + result.backward_mode = 0 elseif onewayClass == "no" or onewayClass == "0" or onewayClass == "false" then -- nothing to do elseif onewayClass == "-1" then - way.forward_mode = 0 + result.forward_mode = 0 end -- surfaces if surface then surface_speed = surface_speeds[surface] if surface_speed then - way.forward_speed = math.min(way.forward_speed, surface_speed) - way.backward_speed = math.min(way.backward_speed, surface_speed) + result.forward_speed = math.min(result.forward_speed, surface_speed) + result.backward_speed = math.min(result.backward_speed, surface_speed) end end end diff --git a/3party/osrm/osrm-backend/profiles/lib/access.lua b/3party/osrm/osrm-backend/profiles/lib/access.lua old mode 100644 new mode 100755 index 094db62907..76d2e2c897 --- a/3party/osrm/osrm-backend/profiles/lib/access.lua +++ b/3party/osrm/osrm-backend/profiles/lib/access.lua @@ -4,10 +4,10 @@ module "Access" function find_access_tag(source,access_tags_hierachy) for i,v in ipairs(access_tags_hierachy) do - local tag = source.tags:Find(v) - if tag ~= '' then + local tag = source:get_value_by_key(v) + if tag and tag ~= '' then return tag end end return nil -end \ No newline at end of file +end diff --git a/3party/osrm/osrm-backend/profiles/lib/maxspeed.lua b/3party/osrm/osrm-backend/profiles/lib/maxspeed.lua old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/profiles/testbot.lua b/3party/osrm/osrm-backend/profiles/testbot.lua old mode 100644 new mode 100755 index a0b06f56d2..7bd1416352 --- a/3party/osrm/osrm-backend/profiles/testbot.lua +++ b/3party/osrm/osrm-backend/profiles/testbot.lua @@ -45,46 +45,47 @@ function limit_speed(speed, limits) return speed end -function node_function (node) - local traffic_signal = node.tags:Find("highway") +function node_function (node, result) + local traffic_signal = node:get_value_by_key("highway") - if traffic_signal == "traffic_signals" then - node.traffic_light = true; + if traffic_signal and traffic_signal == "traffic_signals" then + result.traffic_lights = true; -- TODO: a way to set the penalty value end - return 1 end -function way_function (way) - local highway = way.tags:Find("highway") - local name = way.tags:Find("name") - local oneway = way.tags:Find("oneway") - local route = way.tags:Find("route") - local duration = way.tags:Find("duration") - local maxspeed = tonumber(way.tags:Find ( "maxspeed")) - local maxspeed_forward = tonumber(way.tags:Find( "maxspeed:forward")) - local maxspeed_backward = tonumber(way.tags:Find( "maxspeed:backward")) - local junction = way.tags:Find("junction") +function way_function (way, result) + local highway = way:get_value_by_key("highway") + local name = way:get_value_by_key("name") + local oneway = way:get_value_by_key("oneway") + local route = way:get_value_by_key("route") + local duration = way:get_value_by_key("duration") + local maxspeed = tonumber(way:get_value_by_key ( "maxspeed")) + local maxspeed_forward = tonumber(way:get_value_by_key( "maxspeed:forward")) + local maxspeed_backward = tonumber(way:get_value_by_key( "maxspeed:backward")) + local junction = way:get_value_by_key("junction") - way.name = name + if name then + result.name = name + end - if route ~= nil and durationIsValid(duration) then - way.duration = math.max( 1, parseDuration(duration) ) - way.forward_mode = 2 - way.backward_mode = 2 + if duration and durationIsValid(duration) then + result.duration = math.max( 1, parseDuration(duration) ) + result.forward_mode = 2 + result.backward_mode = 2 else local speed_forw = speed_profile[highway] or speed_profile['default'] local speed_back = speed_forw if highway == "river" then local temp_speed = speed_forw; - way.forward_mode = 3 - way.backward_mode = 4 + result.forward_mode = 3 + result.backward_mode = 4 speed_forw = temp_speed*1.5 speed_back = temp_speed/1.5 elseif highway == "steps" then - way.forward_mode = 5 - way.backward_mode = 6 + result.forward_mode = 5 + result.backward_mode = 6 end if maxspeed_forward ~= nil and maxspeed_forward > 0 then @@ -103,19 +104,19 @@ function way_function (way) end end - way.forward_speed = speed_forw - way.backward_speed = speed_back + result.forward_speed = speed_forw + result.backward_speed = speed_back end if oneway == "no" or oneway == "0" or oneway == "false" then -- nothing to do elseif oneway == "-1" then - way.forward_mode = 0 + result.forward_mode = 0 elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" then - way.backward_mode = 0 + result.backward_mode = 0 end if junction == 'roundabout' then - way.roundabout = true + result.roundabout = true end end diff --git a/3party/osrm/osrm-backend/profiles/turnbot.lua b/3party/osrm/osrm-backend/profiles/turnbot.lua old mode 100644 new mode 100755 index 4427ab7ddb..1a96966f13 --- a/3party/osrm/osrm-backend/profiles/turnbot.lua +++ b/3party/osrm/osrm-backend/profiles/turnbot.lua @@ -4,5 +4,5 @@ require 'testbot' function turn_function (angle) - return 200*math.abs(angle)/180 -- penalty + return 200*math.abs(angle)/180 -- penalty end diff --git a/3party/osrm/osrm-backend/routed.cpp b/3party/osrm/osrm-backend/routed.cpp old mode 100644 new mode 100755 index a7ba54ab5f..8b0e2e88bf --- a/3party/osrm/osrm-backend/routed.cpp +++ b/3party/osrm/osrm-backend/routed.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,12 +25,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "Library/OSRM.h" -#include "Server/Server.h" -#include "Util/GitDescription.h" -#include "Util/ProgramOptions.h" -#include "Util/simple_logger.hpp" -#include "Util/FingerPrint.h" +#include "library/osrm.hpp" +#include "server/server.hpp" +#include "util/git_sha.hpp" +#include "util/routed_options.hpp" +#include "util/simple_logger.hpp" #ifdef __linux__ #include @@ -41,7 +40,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include #include #include #include @@ -71,20 +69,16 @@ int main(int argc, const char *argv[]) { LogPolicy::GetInstance().Unmute(); - bool use_shared_memory = false, trial_run = false; + bool trial_run = false; std::string ip_address; int ip_port, requested_thread_num; - ServerPaths server_paths; + libosrm_config lib_config; - const unsigned init_result = GenerateServerProgramOptions(argc, - argv, - server_paths, - ip_address, - ip_port, - requested_thread_num, - use_shared_memory, - trial_run); + const unsigned init_result = GenerateServerProgramOptions( + argc, argv, lib_config.server_paths, ip_address, ip_port, requested_thread_num, + lib_config.use_shared_memory, trial_run, lib_config.max_locations_distance_table, + lib_config.max_locations_map_matching); if (init_result == INIT_OK_DO_NOT_START_ENGINE) { return 0; @@ -103,7 +97,7 @@ int main(int argc, const char *argv[]) #endif SimpleLogger().Write() << "starting up engines, " << g_GIT_DESCRIPTION; - if (use_shared_memory) + if (lib_config.use_shared_memory) { SimpleLogger().Write(logDEBUG) << "Loading from shared memory"; } @@ -119,9 +113,8 @@ int main(int argc, const char *argv[]) pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); #endif - OSRM osrm_lib(server_paths, use_shared_memory); - auto routing_server = - Server::CreateServer(ip_address, ip_port, requested_thread_num); + OSRM osrm_lib(lib_config); + auto routing_server = Server::CreateServer(ip_address, ip_port, requested_thread_num); routing_server->GetRequestHandlerPtr().RegisterRoutingMachine(&osrm_lib); @@ -131,7 +124,11 @@ int main(int argc, const char *argv[]) } else { - std::packaged_task server_task([&]()->int{ routing_server->Run(); return 0; }); + std::packaged_task server_task([&]() -> int + { + routing_server->Run(); + return 0; + }); auto future = server_task.get_future(); std::thread server_thread(std::move(server_task)); @@ -160,7 +157,7 @@ int main(int argc, const char *argv[]) if (status == std::future_status::ready) { - server_thread.join(); + server_thread.join(); } else { diff --git a/3party/osrm/osrm-backend/RoutingAlgorithms/AlternativePathRouting.h b/3party/osrm/osrm-backend/routing_algorithms/alternative_path.hpp old mode 100644 new mode 100755 similarity index 80% rename from 3party/osrm/osrm-backend/RoutingAlgorithms/AlternativePathRouting.h rename to 3party/osrm/osrm-backend/routing_algorithms/alternative_path.hpp index 83875f3d04..1dcc02096f --- a/3party/osrm/osrm-backend/RoutingAlgorithms/AlternativePathRouting.h +++ b/3party/osrm/osrm-backend/routing_algorithms/alternative_path.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,13 +25,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ALTERNATIVE_PATH_ROUTING_H -#define ALTERNATIVE_PATH_ROUTING_H +#ifndef ALTERNATIVE_PATH_ROUTING_HPP +#define ALTERNATIVE_PATH_ROUTING_HPP -#include "BasicRoutingInterface.h" -#include "../DataStructures/Range.h" -#include "../DataStructures/SearchEngineData.h" -#include "../Util/container.hpp" +#include "routing_base.hpp" +#include "../data_structures/search_engine_data.hpp" +#include "../util/integer_range.hpp" +#include "../util/container.hpp" #include @@ -44,9 +44,11 @@ const double VIAPATH_ALPHA = 0.10; const double VIAPATH_EPSILON = 0.15; // alternative at most 15% longer const double VIAPATH_GAMMA = 0.75; // alternative shares at most 75% with the shortest. -template class AlternativeRouting final : private BasicRoutingInterface +template +class AlternativeRouting final + : private BasicRoutingInterface> { - using super = BasicRoutingInterface; + using super = BasicRoutingInterface>; using EdgeData = typename DataFacadeT::EdgeData; using QueryHeap = SearchEngineData::QueryHeap; using SearchSpaceEdge = std::pair; @@ -78,7 +80,7 @@ template class AlternativeRouting final : private BasicRouti virtual ~AlternativeRouting() {} - void operator()(const PhantomNodes &phantom_node_pair, RawRouteData &raw_route_data) + void operator()(const PhantomNodes &phantom_node_pair, InternalRouteResult &raw_route_data) { std::vector alternative_path; std::vector via_node_candidate_list; @@ -93,17 +95,16 @@ template class AlternativeRouting final : private BasicRouti engine_working_data.InitializeOrClearThirdThreadLocalStorage( super::facade->GetNumberOfNodes()); - QueryHeap &forward_heap1 = *(engine_working_data.forwardHeap); - QueryHeap &reverse_heap1 = *(engine_working_data.backwardHeap); - QueryHeap &forward_heap2 = *(engine_working_data.forwardHeap2); - QueryHeap &reverse_heap2 = *(engine_working_data.backwardHeap2); + QueryHeap &forward_heap1 = *(engine_working_data.forward_heap_1); + QueryHeap &reverse_heap1 = *(engine_working_data.reverse_heap_1); + QueryHeap &forward_heap2 = *(engine_working_data.forward_heap_2); + QueryHeap &reverse_heap2 = *(engine_working_data.reverse_heap_2); int upper_bound_to_shortest_path_distance = INVALID_EDGE_WEIGHT; NodeID middle_node = SPECIAL_NODEID; - EdgeWeight min_edge_offset = - std::min(0, -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset()); - min_edge_offset = std::min(min_edge_offset, - -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); + const EdgeWeight min_edge_offset = + std::min(phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), + phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); if (phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID) { @@ -148,22 +149,16 @@ template class AlternativeRouting final : private BasicRouti { if (0 < forward_heap1.Size()) { - AlternativeRoutingStep(forward_heap1, - reverse_heap1, - &middle_node, + AlternativeRoutingStep(forward_heap1, reverse_heap1, &middle_node, &upper_bound_to_shortest_path_distance, - via_node_candidate_list, - forward_search_space, + via_node_candidate_list, forward_search_space, min_edge_offset); } if (0 < reverse_heap1.Size()) { - AlternativeRoutingStep(reverse_heap1, - forward_heap1, - &middle_node, + AlternativeRoutingStep(forward_heap1, reverse_heap1, &middle_node, &upper_bound_to_shortest_path_distance, - via_node_candidate_list, - reverse_search_space, + via_node_candidate_list, reverse_search_space, min_edge_offset); } } @@ -274,19 +269,16 @@ template class AlternativeRouting final : private BasicRouti std::vector &packed_shortest_path = packed_forward_path; std::reverse(packed_shortest_path.begin(), packed_shortest_path.end()); packed_shortest_path.emplace_back(middle_node); - packed_shortest_path.insert( - packed_shortest_path.end(), packed_reverse_path.begin(), packed_reverse_path.end()); + packed_shortest_path.insert(packed_shortest_path.end(), packed_reverse_path.begin(), + packed_reverse_path.end()); std::vector ranked_candidates_list; // prioritizing via nodes for deep inspection for (const NodeID node : preselected_node_list) { int length_of_via_path = 0, sharing_of_via_path = 0; - ComputeLengthAndSharingOfViaPath(node, - &length_of_via_path, - &sharing_of_via_path, - packed_shortest_path, - min_edge_offset); + ComputeLengthAndSharingOfViaPath(node, &length_of_via_path, &sharing_of_via_path, + packed_shortest_path, min_edge_offset); const int maximum_allowed_sharing = static_cast(upper_bound_to_shortest_path_distance * VIAPATH_GAMMA); if (sharing_of_via_path <= maximum_allowed_sharing && @@ -302,16 +294,10 @@ template class AlternativeRouting final : private BasicRouti NodeID s_v_middle = SPECIAL_NODEID, v_t_middle = SPECIAL_NODEID; for (const RankedCandidateNode &candidate : ranked_candidates_list) { - if (ViaNodeCandidatePassesTTest(forward_heap1, - reverse_heap1, - forward_heap2, - reverse_heap2, - candidate, - upper_bound_to_shortest_path_distance, - &length_of_via_path, - &s_v_middle, - &v_t_middle, - min_edge_offset)) + if (ViaNodeCandidatePassesTTest( + forward_heap1, reverse_heap1, forward_heap2, reverse_heap2, candidate, + upper_bound_to_shortest_path_distance, &length_of_via_path, &s_v_middle, + &v_t_middle, min_edge_offset)) { // select first admissable selected_via_node = candidate.node; @@ -343,13 +329,8 @@ template class AlternativeRouting final : private BasicRouti { std::vector packed_alternate_path; // retrieve alternate path - RetrievePackedAlternatePath(forward_heap1, - reverse_heap1, - forward_heap2, - reverse_heap2, - s_v_middle, - v_t_middle, - packed_alternate_path); + RetrievePackedAlternatePath(forward_heap1, reverse_heap1, forward_heap2, reverse_heap2, + s_v_middle, v_t_middle, packed_alternate_path); raw_route_data.alt_source_traversed_in_reverse.push_back(( packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_node_id)); @@ -357,8 +338,8 @@ template class AlternativeRouting final : private BasicRouti (packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_node_id)); // unpack the alternate path - super::UnpackPath( - packed_alternate_path, phantom_node_pair, raw_route_data.unpacked_alternative); + super::UnpackPath(packed_alternate_path, phantom_node_pair, + raw_route_data.unpacked_alternative); raw_route_data.alternative_path_length = length_of_via_path; } @@ -370,13 +351,13 @@ template class AlternativeRouting final : private BasicRouti private: // unpack alternate by exploring search spaces from v - inline void RetrievePackedAlternatePath(const QueryHeap &forward_heap1, - const QueryHeap &reverse_heap1, - const QueryHeap &forward_heap2, - const QueryHeap &reverse_heap2, - const NodeID s_v_middle, - const NodeID v_t_middle, - std::vector &packed_path) const + void RetrievePackedAlternatePath(const QueryHeap &forward_heap1, + const QueryHeap &reverse_heap1, + const QueryHeap &forward_heap2, + const QueryHeap &reverse_heap2, + const NodeID s_v_middle, + const NodeID v_t_middle, + std::vector &packed_path) const { // fetch packed path [s,v) std::vector packed_v_t_path; @@ -384,8 +365,8 @@ template class AlternativeRouting final : private BasicRouti packed_path.pop_back(); // remove middle node. It's in both half-paths // fetch patched path [v,t] - super::RetrievePackedPathFromHeap( - forward_heap2, reverse_heap1, v_t_middle, packed_v_t_path); + super::RetrievePackedPathFromHeap(forward_heap2, reverse_heap1, v_t_middle, + packed_v_t_path); packed_path.insert(packed_path.end(), packed_v_t_path.begin(), packed_v_t_path.end()); } @@ -394,19 +375,19 @@ template class AlternativeRouting final : private BasicRouti // compute and unpack and by exploring search spaces // from v and intersecting against queues. only half-searches have to be // done at this stage - inline void ComputeLengthAndSharingOfViaPath(const NodeID via_node, - int *real_length_of_via_path, - int *sharing_of_via_path, - const std::vector &packed_shortest_path, - const EdgeWeight min_edge_offset) + void ComputeLengthAndSharingOfViaPath(const NodeID via_node, + int *real_length_of_via_path, + int *sharing_of_via_path, + const std::vector &packed_shortest_path, + const EdgeWeight min_edge_offset) { engine_working_data.InitializeOrClearSecondThreadLocalStorage( super::facade->GetNumberOfNodes()); - QueryHeap &existing_forward_heap = *engine_working_data.forwardHeap; - QueryHeap &existing_reverse_heap = *engine_working_data.backwardHeap; - QueryHeap &new_forward_heap = *engine_working_data.forwardHeap2; - QueryHeap &new_reverse_heap = *engine_working_data.backwardHeap2; + QueryHeap &existing_forward_heap = *engine_working_data.forward_heap_1; + QueryHeap &existing_reverse_heap = *engine_working_data.reverse_heap_1; + QueryHeap &new_forward_heap = *engine_working_data.forward_heap_2; + QueryHeap &new_reverse_heap = *engine_working_data.reverse_heap_2; std::vector packed_s_v_path; std::vector packed_v_t_path; @@ -420,12 +401,8 @@ template class AlternativeRouting final : private BasicRouti // compute path by reusing forward search from s while (!new_reverse_heap.Empty()) { - super::RoutingStep(new_reverse_heap, - existing_forward_heap, - &s_v_middle, - &upper_bound_s_v_path_length, - min_edge_offset, - false); + super::RoutingStep(new_reverse_heap, existing_forward_heap, &s_v_middle, + &upper_bound_s_v_path_length, min_edge_offset, false); } // compute path by reusing backward search from node t NodeID v_t_middle = SPECIAL_NODEID; @@ -433,12 +410,8 @@ template class AlternativeRouting final : private BasicRouti new_forward_heap.Insert(via_node, 0, via_node); while (!new_forward_heap.Empty()) { - super::RoutingStep(new_forward_heap, - existing_reverse_heap, - &v_t_middle, - &upper_bound_of_v_t_path_length, - min_edge_offset, - true); + super::RoutingStep(new_forward_heap, existing_reverse_heap, &v_t_middle, + &upper_bound_of_v_t_path_length, min_edge_offset, true); } *real_length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length; @@ -448,10 +421,10 @@ template class AlternativeRouting final : private BasicRouti } // retrieve packed paths - super::RetrievePackedPathFromHeap( - existing_forward_heap, new_reverse_heap, s_v_middle, packed_s_v_path); - super::RetrievePackedPathFromHeap( - new_forward_heap, existing_reverse_heap, v_t_middle, packed_v_t_path); + super::RetrievePackedPathFromHeap(existing_forward_heap, new_reverse_heap, s_v_middle, + packed_s_v_path); + super::RetrievePackedPathFromHeap(new_forward_heap, existing_reverse_heap, v_t_middle, + packed_v_t_path); // partial unpacking, compute sharing // First partially unpack s-->v until paths deviate, note length of common path. @@ -484,12 +457,11 @@ template class AlternativeRouting final : private BasicRouti const int64_t packed_path_length = std::min(partially_unpacked_via_path.size(), partially_unpacked_shortest_path.size()) - 1; - for (int64_t current_node = 0; - (current_node < packed_path_length) && - (partially_unpacked_via_path[current_node] == - partially_unpacked_shortest_path[current_node] && - partially_unpacked_via_path[current_node + 1] == - partially_unpacked_shortest_path[current_node + 1]); + for (int64_t current_node = 0; (current_node < packed_path_length) && + (partially_unpacked_via_path[current_node] == + partially_unpacked_shortest_path[current_node] && + partially_unpacked_via_path[current_node + 1] == + partially_unpacked_shortest_path[current_node + 1]); ++current_node) { EdgeID selected_edge = @@ -517,8 +489,7 @@ template class AlternativeRouting final : private BasicRouti if (packed_v_t_path[via_path_index] == packed_shortest_path[shortest_path_index]) { super::UnpackEdge(packed_v_t_path[via_path_index - 1], - packed_v_t_path[via_path_index], - partially_unpacked_via_path); + packed_v_t_path[via_path_index], partially_unpacked_via_path); super::UnpackEdge(packed_shortest_path[shortest_path_index - 1], packed_shortest_path[shortest_path_index], partially_unpacked_shortest_path); @@ -551,7 +522,7 @@ template class AlternativeRouting final : private BasicRouti // variable } - // inline int approximateAmountOfSharing( + // int approximateAmountOfSharing( // const NodeID alternate_path_middle_node_id, // QueryHeap & forward_heap, // QueryHeap & reverse_heap, @@ -598,14 +569,17 @@ template class AlternativeRouting final : private BasicRouti // todo: reorder parameters template - inline void AlternativeRoutingStep(QueryHeap &forward_heap, - QueryHeap &reverse_heap, - NodeID *middle_node, - int *upper_bound_to_shortest_path_distance, - std::vector &search_space_intersection, - std::vector &search_space, - const EdgeWeight min_edge_offset) const + void AlternativeRoutingStep(QueryHeap &heap1, + QueryHeap &heap2, + NodeID *middle_node, + int *upper_bound_to_shortest_path_distance, + std::vector &search_space_intersection, + std::vector &search_space, + const EdgeWeight min_edge_offset) const { + QueryHeap &forward_heap = (is_forward_directed ? heap1 : heap2); + QueryHeap &reverse_heap = (is_forward_directed ? heap2 : heap1); + const NodeID node = forward_heap.DeleteMin(); const int distance = forward_heap.GetKey(node); // const NodeID parentnode = forward_heap.GetData(node).parent; @@ -674,16 +648,16 @@ template class AlternativeRouting final : private BasicRouti } // conduct T-Test - inline bool ViaNodeCandidatePassesTTest(QueryHeap &existing_forward_heap, - QueryHeap &existing_reverse_heap, - QueryHeap &new_forward_heap, - QueryHeap &new_reverse_heap, - const RankedCandidateNode &candidate, - const int length_of_shortest_path, - int *length_of_via_path, - NodeID *s_v_middle, - NodeID *v_t_middle, - const EdgeWeight min_edge_offset) const + bool ViaNodeCandidatePassesTTest(QueryHeap &existing_forward_heap, + QueryHeap &existing_reverse_heap, + QueryHeap &new_forward_heap, + QueryHeap &new_reverse_heap, + const RankedCandidateNode &candidate, + const int length_of_shortest_path, + int *length_of_via_path, + NodeID *s_v_middle, + NodeID *v_t_middle, + const EdgeWeight min_edge_offset) const { new_forward_heap.Clear(); new_reverse_heap.Clear(); @@ -696,12 +670,8 @@ template class AlternativeRouting final : private BasicRouti new_reverse_heap.Insert(candidate.node, 0, candidate.node); while (new_reverse_heap.Size() > 0) { - super::RoutingStep(new_reverse_heap, - existing_forward_heap, - s_v_middle, - &upper_bound_s_v_path_length, - min_edge_offset, - false); + super::RoutingStep(new_reverse_heap, existing_forward_heap, s_v_middle, + &upper_bound_s_v_path_length, min_edge_offset, false); } if (INVALID_EDGE_WEIGHT == upper_bound_s_v_path_length) @@ -715,12 +685,8 @@ template class AlternativeRouting final : private BasicRouti new_forward_heap.Insert(candidate.node, 0, candidate.node); while (new_forward_heap.Size() > 0) { - super::RoutingStep(new_forward_heap, - existing_reverse_heap, - v_t_middle, - &upper_bound_of_v_t_path_length, - min_edge_offset, - true); + super::RoutingStep(new_forward_heap, existing_reverse_heap, v_t_middle, + &upper_bound_of_v_t_path_length, min_edge_offset, true); } if (INVALID_EDGE_WEIGHT == upper_bound_of_v_t_path_length) @@ -731,11 +697,11 @@ template class AlternativeRouting final : private BasicRouti *length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length; // retrieve packed paths - super::RetrievePackedPathFromHeap( - existing_forward_heap, new_reverse_heap, *s_v_middle, packed_s_v_path); + super::RetrievePackedPathFromHeap(existing_forward_heap, new_reverse_heap, *s_v_middle, + packed_s_v_path); - super::RetrievePackedPathFromHeap( - new_forward_heap, existing_reverse_heap, *v_t_middle, packed_v_t_path); + super::RetrievePackedPathFromHeap(new_forward_heap, existing_reverse_heap, *v_t_middle, + packed_v_t_path); NodeID s_P = *s_v_middle, t_P = *v_t_middle; if (SPECIAL_NODEID == s_P) @@ -815,8 +781,7 @@ template class AlternativeRouting final : private BasicRouti // Traverse path s-->v BOOST_ASSERT(!packed_v_t_path.empty()); for (unsigned i = 0, packed_path_length = static_cast(packed_v_t_path.size() - 1); - (i < packed_path_length) && unpack_stack.empty(); - ++i) + (i < packed_path_length) && unpack_stack.empty(); ++i) { const EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_v_t_path[i], packed_v_t_path[i + 1]); @@ -876,8 +841,8 @@ template class AlternativeRouting final : private BasicRouti engine_working_data.InitializeOrClearThirdThreadLocalStorage( super::facade->GetNumberOfNodes()); - QueryHeap &forward_heap3 = *engine_working_data.forwardHeap3; - QueryHeap &reverse_heap3 = *engine_working_data.backwardHeap3; + QueryHeap &forward_heap3 = *engine_working_data.forward_heap_3; + QueryHeap &reverse_heap3 = *engine_working_data.reverse_heap_3; int upper_bound = INVALID_EDGE_WEIGHT; NodeID middle = SPECIAL_NODEID; @@ -888,17 +853,17 @@ template class AlternativeRouting final : private BasicRouti { if (!forward_heap3.Empty()) { - super::RoutingStep( - forward_heap3, reverse_heap3, &middle, &upper_bound, min_edge_offset, true); + super::RoutingStep(forward_heap3, reverse_heap3, &middle, &upper_bound, + min_edge_offset, true); } if (!reverse_heap3.Empty()) { - super::RoutingStep( - reverse_heap3, forward_heap3, &middle, &upper_bound, min_edge_offset, false); + super::RoutingStep(reverse_heap3, forward_heap3, &middle, &upper_bound, + min_edge_offset, false); } } return (upper_bound <= t_test_path_length); } }; -#endif /* ALTERNATIVE_PATH_ROUTING_H */ +#endif /* ALTERNATIVE_PATH_ROUTING_HPP */ diff --git a/3party/osrm/osrm-backend/RoutingAlgorithms/ManyToManyRouting.h b/3party/osrm/osrm-backend/routing_algorithms/many_to_many.hpp old mode 100644 new mode 100755 similarity index 89% rename from 3party/osrm/osrm-backend/RoutingAlgorithms/ManyToManyRouting.h rename to 3party/osrm/osrm-backend/routing_algorithms/many_to_many.hpp index ab73150738..2388804718 --- a/3party/osrm/osrm-backend/RoutingAlgorithms/ManyToManyRouting.h +++ b/3party/osrm/osrm-backend/routing_algorithms/many_to_many.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2014, Project OSRM, Dennis Luxen, others +Copyright (c) 2014, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,11 +25,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MANY_TO_MANY_ROUTING_H -#define MANY_TO_MANY_ROUTING_H +#ifndef MANY_TO_MANY_ROUTING_HPP +#define MANY_TO_MANY_ROUTING_HPP -#include "BasicRoutingInterface.h" -#include "../DataStructures/SearchEngineData.h" +#include "routing_base.hpp" +#include "../data_structures/search_engine_data.hpp" #include "../typedefs.h" #include @@ -39,9 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -template class ManyToManyRouting final : public BasicRoutingInterface +template +class ManyToManyRouting final + : public BasicRoutingInterface> { - using super = BasicRoutingInterface; + using super = BasicRoutingInterface>; using QueryHeap = SearchEngineData::QueryHeap; SearchEngineData &engine_working_data; @@ -64,10 +66,10 @@ template class ManyToManyRouting final : public BasicRouting ~ManyToManyRouting() {} - std::shared_ptr> operator()(const PhantomNodeArray &phantom_nodes_array) - const + std::shared_ptr> + operator()(const PhantomNodeArray &phantom_nodes_array) const { - const unsigned number_of_locations = static_cast(phantom_nodes_array.size()); + const auto number_of_locations = phantom_nodes_array.size(); std::shared_ptr> result_table = std::make_shared>(number_of_locations * number_of_locations, std::numeric_limits::max()); @@ -75,7 +77,7 @@ template class ManyToManyRouting final : public BasicRouting engine_working_data.InitializeOrClearFirstThreadLocalStorage( super::facade->GetNumberOfNodes()); - QueryHeap &query_heap = *(engine_working_data.forwardHeap); + QueryHeap &query_heap = *(engine_working_data.forward_heap_1); SearchSpaceWithBuckets search_space_with_buckets; @@ -134,11 +136,8 @@ template class ManyToManyRouting final : public BasicRouting // explore search space while (!query_heap.Empty()) { - ForwardRoutingStep(source_id, - number_of_locations, - query_heap, - search_space_with_buckets, - result_table); + ForwardRoutingStep(source_id, number_of_locations, query_heap, + search_space_with_buckets, result_table); } ++source_id; @@ -209,7 +208,7 @@ template class ManyToManyRouting final : public BasicRouting { for (auto edge : super::facade->GetAdjacentEdgeRange(node)) { - const auto &data = super::facade->GetEdgeData(edge, node); + const auto &data = super::facade->GetEdgeData(edge); const bool direction_flag = (forward_direction ? data.forward : data.backward); if (direction_flag) { @@ -237,12 +236,12 @@ template class ManyToManyRouting final : public BasicRouting // Stalling template - inline bool StallAtNode(const NodeID node, const EdgeWeight distance, QueryHeap &query_heap) - const + inline bool + StallAtNode(const NodeID node, const EdgeWeight distance, QueryHeap &query_heap) const { for (auto edge : super::facade->GetAdjacentEdgeRange(node)) { - const auto &data = super::facade->GetEdgeData(edge, node); + const auto &data = super::facade->GetEdgeData(edge); const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward); if (reverse_flag) { diff --git a/3party/osrm/osrm-backend/routing_algorithms/map_matching.hpp b/3party/osrm/osrm-backend/routing_algorithms/map_matching.hpp new file mode 100755 index 0000000000..737494b64d --- /dev/null +++ b/3party/osrm/osrm-backend/routing_algorithms/map_matching.hpp @@ -0,0 +1,344 @@ +/* + +Copyright (c) 2015, 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 MAP_MATCHING_HPP +#define MAP_MATCHING_HPP + +#include "routing_base.hpp" + +#include "../data_structures/coordinate_calculation.hpp" +#include "../data_structures/hidden_markov_model.hpp" +#include "../util/json_logger.hpp" +#include "../util/matching_debug_info.hpp" + +#include + +#include +#include +#include + +namespace osrm +{ +namespace matching +{ + +struct SubMatching +{ + std::vector nodes; + std::vector indices; + double length; + double confidence; +}; + +using CandidateList = std::vector>; +using CandidateLists = std::vector; +using HMM = HiddenMarkovModel; +using SubMatchingList = std::vector; + +constexpr static const unsigned MAX_BROKEN_STATES = 6; +constexpr static const unsigned MAX_BROKEN_TIME = 60; + +constexpr static const unsigned MAX_DISTANCE_DELTA = 200; +constexpr static const unsigned SUSPICIOUS_DISTANCE_DELTA = 100; + +constexpr static const double default_beta = 5.0; +constexpr static const double default_sigma_z = 4.07; +} +} + +// implements a hidden markov model map matching algorithm +template +class MapMatching final : public BasicRoutingInterface> +{ + using super = BasicRoutingInterface>; + using QueryHeap = SearchEngineData::QueryHeap; + SearchEngineData &engine_working_data; + + public: + MapMatching(DataFacadeT *facade, SearchEngineData &engine_working_data) + : super(facade), engine_working_data(engine_working_data) + { + } + + void operator()(const osrm::matching::CandidateLists &candidates_list, + const std::vector &trace_coordinates, + const std::vector &trace_timestamps, + const double matching_beta, + const double gps_precision, + osrm::matching::SubMatchingList &sub_matchings) const + { + BOOST_ASSERT(!candidates_list.empty() && !trace_coordinates.empty()); + + // TODO replace default values with table lookup based on sampling frequency + EmissionLogProbability emission_log_probability( + gps_precision > 0. ? gps_precision : osrm::matching::default_sigma_z); + TransitionLogProbability transition_log_probability( + matching_beta > 0. ? matching_beta : osrm::matching::default_beta); + + osrm::matching::HMM model(candidates_list, emission_log_probability); + + std::size_t initial_timestamp = model.initialize(0); + if (initial_timestamp == osrm::matching::INVALID_STATE) + { + return; + } + + MatchingDebugInfo matching_debug(osrm::json::Logger::get()); + matching_debug.initialize(candidates_list); + + std::size_t breakage_begin = osrm::matching::INVALID_STATE; + std::vector split_points; + std::vector prev_unbroken_timestamps; + prev_unbroken_timestamps.reserve(candidates_list.size()); + prev_unbroken_timestamps.push_back(initial_timestamp); + for (auto t = initial_timestamp + 1; t < candidates_list.size(); ++t) + { + // breakage recover has removed all previous good points + bool trace_split = prev_unbroken_timestamps.empty(); + + // use temporal information if available to determine a split + if (!trace_timestamps.empty()) + { + trace_split = + trace_split || + (trace_timestamps[t] - trace_timestamps[prev_unbroken_timestamps.back()] > + osrm::matching::MAX_BROKEN_TIME); + } + else + { + trace_split = trace_split || (t - prev_unbroken_timestamps.back() > + osrm::matching::MAX_BROKEN_STATES); + } + + if (trace_split) + { + std::size_t split_index = t; + if (breakage_begin != osrm::matching::INVALID_STATE) + { + split_index = breakage_begin; + breakage_begin = osrm::matching::INVALID_STATE; + } + split_points.push_back(split_index); + + // note: this preserves everything before split_index + model.clear(split_index); + std::size_t new_start = model.initialize(split_index); + // no new start was found -> stop viterbi calculation + if (new_start == osrm::matching::INVALID_STATE) + { + break; + } + + prev_unbroken_timestamps.clear(); + prev_unbroken_timestamps.push_back(new_start); + // Important: We potentially go back here! + // However since t > new_start >= breakge_begin + // we can only reset trace_coordindates.size() times. + t = new_start + 1; + } + + BOOST_ASSERT(!prev_unbroken_timestamps.empty()); + const std::size_t prev_unbroken_timestamp = prev_unbroken_timestamps.back(); + + const auto &prev_viterbi = model.viterbi[prev_unbroken_timestamp]; + const auto &prev_pruned = model.pruned[prev_unbroken_timestamp]; + const auto &prev_unbroken_timestamps_list = candidates_list[prev_unbroken_timestamp]; + const auto &prev_coordinate = trace_coordinates[prev_unbroken_timestamp]; + + auto ¤t_viterbi = model.viterbi[t]; + auto ¤t_pruned = model.pruned[t]; + auto ¤t_suspicious = model.suspicious[t]; + auto ¤t_parents = model.parents[t]; + auto ¤t_lengths = model.path_lengths[t]; + const auto ¤t_timestamps_list = candidates_list[t]; + const auto ¤t_coordinate = trace_coordinates[t]; + + engine_working_data.InitializeOrClearFirstThreadLocalStorage( + super::facade->GetNumberOfNodes()); + engine_working_data.InitializeOrClearSecondThreadLocalStorage( + super::facade->GetNumberOfNodes()); + + QueryHeap &forward_heap = *(engine_working_data.forward_heap_1); + QueryHeap &reverse_heap = *(engine_working_data.reverse_heap_1); + + // compute d_t for this timestamp and the next one + for (const auto s : osrm::irange(0u, prev_viterbi.size())) + { + if (prev_pruned[s]) + { + continue; + } + + for (const auto s_prime : osrm::irange(0u, current_viterbi.size())) + { + // how likely is candidate s_prime at time t to be emitted? + const double emission_pr = + emission_log_probability(candidates_list[t][s_prime].second); + double new_value = prev_viterbi[s] + emission_pr; + if (current_viterbi[s_prime] > new_value) + { + continue; + } + + forward_heap.Clear(); + reverse_heap.Clear(); + + // get distance diff between loc1/2 and locs/s_prime + const auto network_distance = super::get_network_distance( + forward_heap, reverse_heap, prev_unbroken_timestamps_list[s].first, + current_timestamps_list[s_prime].first); + const auto great_circle_distance = + coordinate_calculation::great_circle_distance(prev_coordinate, + current_coordinate); + + const auto d_t = std::abs(network_distance - great_circle_distance); + + // very low probability transition -> prune + if (d_t > osrm::matching::MAX_DISTANCE_DELTA) + { + continue; + } + + const double transition_pr = transition_log_probability(d_t); + new_value += transition_pr; + + matching_debug.add_transition_info(prev_unbroken_timestamp, t, s, s_prime, + prev_viterbi[s], emission_pr, transition_pr, + network_distance, great_circle_distance); + + if (new_value > current_viterbi[s_prime]) + { + current_viterbi[s_prime] = new_value; + current_parents[s_prime] = std::make_pair(prev_unbroken_timestamp, s); + current_lengths[s_prime] = network_distance; + current_pruned[s_prime] = false; + current_suspicious[s_prime] = d_t > osrm::matching::SUSPICIOUS_DISTANCE_DELTA; + model.breakage[t] = false; + } + } + } + + if (model.breakage[t]) + { + // save start of breakage -> we need this as split point + if (t < breakage_begin) + { + breakage_begin = t; + } + + BOOST_ASSERT(prev_unbroken_timestamps.size() > 0); + // remove both ends of the breakage + prev_unbroken_timestamps.pop_back(); + } + else + { + prev_unbroken_timestamps.push_back(t); + } + } + + matching_debug.set_viterbi(model.viterbi, model.pruned, model.suspicious); + + if (!prev_unbroken_timestamps.empty()) + { + split_points.push_back(prev_unbroken_timestamps.back() + 1); + } + + std::size_t sub_matching_begin = initial_timestamp; + for (const auto sub_matching_end : split_points) + { + osrm::matching::SubMatching matching; + + // find real end of trace + // not sure if this is really needed + std::size_t parent_timestamp_index = sub_matching_end - 1; + while (parent_timestamp_index >= sub_matching_begin && + model.breakage[parent_timestamp_index]) + { + --parent_timestamp_index; + } + + // matchings that only consist of one candidate are invalid + if (parent_timestamp_index - sub_matching_begin + 1 < 2) + { + sub_matching_begin = sub_matching_end; + continue; + } + + // loop through the columns, and only compare the last entry + const auto max_element_iter = + std::max_element(model.viterbi[parent_timestamp_index].begin(), + model.viterbi[parent_timestamp_index].end()); + + std::size_t parent_candidate_index = + std::distance(model.viterbi[parent_timestamp_index].begin(), max_element_iter); + + std::deque> reconstructed_indices; + while (parent_timestamp_index > sub_matching_begin) + { + if (model.breakage[parent_timestamp_index]) + { + continue; + } + + reconstructed_indices.emplace_front(parent_timestamp_index, parent_candidate_index); + const auto &next = model.parents[parent_timestamp_index][parent_candidate_index]; + parent_timestamp_index = next.first; + parent_candidate_index = next.second; + } + reconstructed_indices.emplace_front(parent_timestamp_index, parent_candidate_index); + if (reconstructed_indices.size() < 2) + { + sub_matching_begin = sub_matching_end; + continue; + } + + matching.length = 0.0f; + matching.nodes.resize(reconstructed_indices.size()); + matching.indices.resize(reconstructed_indices.size()); + for (const auto i : osrm::irange(0u, reconstructed_indices.size())) + { + const auto timestamp_index = reconstructed_indices[i].first; + const auto location_index = reconstructed_indices[i].second; + + matching.indices[i] = timestamp_index; + matching.nodes[i] = candidates_list[timestamp_index][location_index].first; + matching.length += model.path_lengths[timestamp_index][location_index]; + + matching_debug.add_chosen(timestamp_index, location_index); + } + + sub_matchings.push_back(matching); + sub_matching_begin = sub_matching_end; + } + matching_debug.add_breakage(model.breakage); + } +}; + +//[1] "Hidden Markov Map Matching Through Noise and Sparseness"; P. Newson and J. Krumm; 2009; ACM +// GIS + +#endif /* MAP_MATCHING_HPP */ diff --git a/3party/osrm/osrm-backend/routing_algorithms/routing_base.hpp b/3party/osrm/osrm-backend/routing_algorithms/routing_base.hpp new file mode 100755 index 0000000000..52c16a77ee --- /dev/null +++ b/3party/osrm/osrm-backend/routing_algorithms/routing_base.hpp @@ -0,0 +1,494 @@ +/* + +Copyright (c) 2015, 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 ROUTING_BASE_HPP +#define ROUTING_BASE_HPP + +#include "../data_structures/coordinate_calculation.hpp" +#include "../data_structures/internal_route_result.hpp" +#include "../data_structures/search_engine_data.hpp" +#include "../data_structures/turn_instructions.hpp" +// #include "../util/simple_logger.hpp" + +#include + +#include + +SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_1; +SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_1; +SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_2; +SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_2; +SearchEngineData::SearchEngineHeapPtr SearchEngineData::forward_heap_3; +SearchEngineData::SearchEngineHeapPtr SearchEngineData::reverse_heap_3; + +template class BasicRoutingInterface +{ + private: + using EdgeData = typename DataFacadeT::EdgeData; + + protected: + DataFacadeT *facade; + + public: + BasicRoutingInterface() = delete; + BasicRoutingInterface(const BasicRoutingInterface &) = delete; + explicit BasicRoutingInterface(DataFacadeT *facade) : facade(facade) {} + ~BasicRoutingInterface() {} + + void RoutingStep(SearchEngineData::QueryHeap &forward_heap, + SearchEngineData::QueryHeap &reverse_heap, + NodeID *middle_node_id, + int *upper_bound, + const int min_edge_offset, + const bool forward_direction) const + { + const NodeID node = forward_heap.DeleteMin(); + const int distance = forward_heap.GetKey(node); + + // const NodeID parentnode = forward_heap.GetData(node).parent; + // SimpleLogger().Write() << (forward_direction ? "[fwd] " : "[rev] ") << "settled edge (" + // << parentnode << "," << node << "), dist: " << distance; + + if (reverse_heap.WasInserted(node)) + { + const int new_distance = reverse_heap.GetKey(node) + distance; + if (new_distance < *upper_bound) + { + if (new_distance >= 0) + { + *middle_node_id = node; + *upper_bound = new_distance; + // SimpleLogger().Write() << "accepted middle node " << node << " at + // distance " << new_distance; + // } else { + // SimpleLogger().Write() << "discared middle node " << node << " at + // distance " << new_distance; + } + } + } + + if (distance + min_edge_offset > *upper_bound) + { + // SimpleLogger().Write() << "min_edge_offset: " << min_edge_offset; + forward_heap.DeleteAll(); + return; + } + + // Stalling + for (const auto edge : facade->GetAdjacentEdgeRange(node)) + { + const EdgeData &data = facade->GetEdgeData(edge); + const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward); + if (reverse_flag) + { + const NodeID to = facade->GetTarget(edge); + const int edge_weight = data.distance; + + BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid"); + + if (forward_heap.WasInserted(to)) + { + if (forward_heap.GetKey(to) + edge_weight < distance) + { + return; + } + } + } + } + + for (const auto edge : facade->GetAdjacentEdgeRange(node)) + { + const EdgeData &data = facade->GetEdgeData(edge); + bool forward_directionFlag = (forward_direction ? data.forward : data.backward); + if (forward_directionFlag) + { + + const NodeID to = facade->GetTarget(edge); + const int edge_weight = data.distance; + + BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid"); + const int to_distance = distance + edge_weight; + + // New Node discovered -> Add to Heap + Node Info Storage + if (!forward_heap.WasInserted(to)) + { + forward_heap.Insert(to, to_distance, node); + } + // Found a shorter Path -> Update distance + else if (to_distance < forward_heap.GetKey(to)) + { + // new parent + forward_heap.GetData(to).parent = node; + forward_heap.DecreaseKey(to, to_distance); + } + } + } + } + + void UnpackPath(const std::vector &packed_path, + const PhantomNodes &phantom_node_pair, + std::vector &unpacked_path) const + { + const bool start_traversed_in_reverse = + (packed_path.front() != phantom_node_pair.source_phantom.forward_node_id); + const bool target_traversed_in_reverse = + (packed_path.back() != phantom_node_pair.target_phantom.forward_node_id); + + const unsigned packed_path_size = static_cast(packed_path.size()); + std::stack> recursion_stack; + + // We have to push the path in reverse order onto the stack because it's LIFO. + for (unsigned i = packed_path_size - 1; i > 0; --i) + { + recursion_stack.emplace(packed_path[i - 1], packed_path[i]); + } + + std::pair edge; + while (!recursion_stack.empty()) + { + /* + Graphical representation of variables: + + edge.first edge.second + *------------------>* + edge_id + */ + edge = recursion_stack.top(); + recursion_stack.pop(); + + // facade->FindEdge does not suffice here in case of shortcuts. + // The above explanation unclear? Think! + EdgeID smaller_edge_id = SPECIAL_EDGEID; + int edge_weight = std::numeric_limits::max(); + for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first)) + { + const int weight = facade->GetEdgeData(edge_id).distance; + if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) && + facade->GetEdgeData(edge_id).forward) + { + smaller_edge_id = edge_id; + edge_weight = weight; + } + } + + /* + Graphical representation of variables: + + edge.first edge.second + *<------------------* + edge_id + */ + if (SPECIAL_EDGEID == smaller_edge_id) + { + 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) + { + smaller_edge_id = edge_id; + edge_weight = weight; + } + } + } + BOOST_ASSERT_MSG(edge_weight != INVALID_EDGE_WEIGHT, "edge id invalid"); + + const EdgeData &ed = facade->GetEdgeData(smaller_edge_id); + if (ed.shortcut) + { // unpack + const NodeID middle_node_id = ed.id; + // again, we need to this in reversed order + recursion_stack.emplace(middle_node_id, edge.second); + recursion_stack.emplace(edge.first, middle_node_id); + } + 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 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 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, + TurnInstruction::NoTurn, + 0, + phantom_node_pair.target_phantom.forward_travel_mode}); + } + } + + // there is no equivalent to a node-based node in an edge-expanded graph. + // two equivalent routes may start (or end) at different node-based edges + // as they are added with the offset how much "distance" on the edge + // has already been traversed. Depending on offset one needs to remove + // the last node. + if (unpacked_path.size() > 1) + { + const std::size_t last_index = unpacked_path.size() - 1; + const std::size_t second_to_last_index = last_index - 1; + + // looks like a trivially true check but tests for underflow + BOOST_ASSERT(last_index > second_to_last_index); + + if (unpacked_path[last_index].node == unpacked_path[second_to_last_index].node) + { + unpacked_path.pop_back(); + } + BOOST_ASSERT(!unpacked_path.empty()); + } + } + + void UnpackEdge(const NodeID s, const NodeID t, std::vector &unpacked_path) const + { + std::stack> recursion_stack; + recursion_stack.emplace(s, t); + + std::pair edge; + while (!recursion_stack.empty()) + { + edge = recursion_stack.top(); + recursion_stack.pop(); + + EdgeID smaller_edge_id = SPECIAL_EDGEID; + int edge_weight = std::numeric_limits::max(); + for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first)) + { + const int weight = facade->GetEdgeData(edge_id).distance; + if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) && + facade->GetEdgeData(edge_id).forward) + { + smaller_edge_id = edge_id; + edge_weight = weight; + } + } + + if (SPECIAL_EDGEID == smaller_edge_id) + { + 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) + { + smaller_edge_id = edge_id; + edge_weight = weight; + } + } + } + BOOST_ASSERT_MSG(edge_weight != std::numeric_limits::max(), + "edge weight invalid"); + + const EdgeData &ed = facade->GetEdgeData(smaller_edge_id); + if (ed.shortcut) + { // unpack + const NodeID middle_node_id = ed.id; + // again, we need to this in reversed order + recursion_stack.emplace(middle_node_id, edge.second); + recursion_stack.emplace(edge.first, middle_node_id); + } + else + { + BOOST_ASSERT_MSG(!ed.shortcut, "edge must be shortcut"); + unpacked_path.emplace_back(edge.first); + } + } + unpacked_path.emplace_back(t); + } + + void RetrievePackedPathFromHeap(const SearchEngineData::QueryHeap &forward_heap, + const SearchEngineData::QueryHeap &reverse_heap, + const NodeID middle_node_id, + std::vector &packed_path) const + { + RetrievePackedPathFromSingleHeap(forward_heap, middle_node_id, packed_path); + std::reverse(packed_path.begin(), packed_path.end()); + packed_path.emplace_back(middle_node_id); + RetrievePackedPathFromSingleHeap(reverse_heap, middle_node_id, packed_path); + } + + void RetrievePackedPathFromSingleHeap(const SearchEngineData::QueryHeap &search_heap, + const NodeID middle_node_id, + std::vector &packed_path) const + { + NodeID current_node_id = middle_node_id; + while (current_node_id != search_heap.GetData(current_node_id).parent) + { + current_node_id = search_heap.GetData(current_node_id).parent; + packed_path.emplace_back(current_node_id); + } + } + + double get_network_distance(SearchEngineData::QueryHeap &forward_heap, + SearchEngineData::QueryHeap &reverse_heap, + const PhantomNode &source_phantom, + const PhantomNode &target_phantom) const + { + EdgeWeight upper_bound = INVALID_EDGE_WEIGHT; + NodeID middle_node = SPECIAL_NODEID; + EdgeWeight edge_offset = std::min(0, -source_phantom.GetForwardWeightPlusOffset()); + edge_offset = std::min(edge_offset, -source_phantom.GetReverseWeightPlusOffset()); + + if (source_phantom.forward_node_id != SPECIAL_NODEID) + { + forward_heap.Insert(source_phantom.forward_node_id, + -source_phantom.GetForwardWeightPlusOffset(), + source_phantom.forward_node_id); + } + if (source_phantom.reverse_node_id != SPECIAL_NODEID) + { + forward_heap.Insert(source_phantom.reverse_node_id, + -source_phantom.GetReverseWeightPlusOffset(), + source_phantom.reverse_node_id); + } + + if (target_phantom.forward_node_id != SPECIAL_NODEID) + { + reverse_heap.Insert(target_phantom.forward_node_id, + target_phantom.GetForwardWeightPlusOffset(), + target_phantom.forward_node_id); + } + if (target_phantom.reverse_node_id != SPECIAL_NODEID) + { + reverse_heap.Insert(target_phantom.reverse_node_id, + target_phantom.GetReverseWeightPlusOffset(), + target_phantom.reverse_node_id); + } + + // search from s and t till new_min/(1+epsilon) > length_of_shortest_path + while (0 < (forward_heap.Size() + reverse_heap.Size())) + { + if (0 < forward_heap.Size()) + { + RoutingStep(forward_heap, reverse_heap, &middle_node, &upper_bound, edge_offset, + true); + } + if (0 < reverse_heap.Size()) + { + RoutingStep(reverse_heap, forward_heap, &middle_node, &upper_bound, edge_offset, + false); + } + } + + double distance = std::numeric_limits::max(); + if (upper_bound != INVALID_EDGE_WEIGHT) + { + std::vector packed_leg; + RetrievePackedPathFromHeap(forward_heap, reverse_heap, middle_node, packed_leg); + std::vector unpacked_path; + PhantomNodes nodes; + nodes.source_phantom = source_phantom; + nodes.target_phantom = target_phantom; + UnpackPath(packed_leg, nodes, unpacked_path); + + FixedPointCoordinate previous_coordinate = source_phantom.location; + FixedPointCoordinate current_coordinate; + distance = 0; + for (const auto &p : unpacked_path) + { + current_coordinate = facade->GetCoordinateOfNode(p.node); + distance += coordinate_calculation::great_circle_distance(previous_coordinate, + current_coordinate); + previous_coordinate = current_coordinate; + } + distance += coordinate_calculation::great_circle_distance(previous_coordinate, + target_phantom.location); + } + return distance; + } +}; + +#endif // ROUTING_BASE_HPP diff --git a/3party/osrm/osrm-backend/RoutingAlgorithms/ShortestPathRouting.h b/3party/osrm/osrm-backend/routing_algorithms/shortest_path.hpp old mode 100644 new mode 100755 similarity index 73% rename from 3party/osrm/osrm-backend/RoutingAlgorithms/ShortestPathRouting.h rename to 3party/osrm/osrm-backend/routing_algorithms/shortest_path.hpp index 4670eedf57..3dedc2b76a --- a/3party/osrm/osrm-backend/RoutingAlgorithms/ShortestPathRouting.h +++ b/3party/osrm/osrm-backend/routing_algorithms/shortest_path.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,19 +25,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SHORTEST_PATH_ROUTING_H -#define SHORTEST_PATH_ROUTING_H +#ifndef SHORTEST_PATH_HPP +#define SHORTEST_PATH_HPP #include -#include "BasicRoutingInterface.h" -#include "../DataStructures/Range.h" -#include "../DataStructures/SearchEngineData.h" +#include "routing_base.hpp" +#include "../data_structures/search_engine_data.hpp" +#include "../util/integer_range.hpp" #include "../typedefs.h" -template class ShortestPathRouting final : public BasicRoutingInterface +template +class ShortestPathRouting final + : public BasicRoutingInterface> { - using super = BasicRoutingInterface; + using super = BasicRoutingInterface>; using QueryHeap = SearchEngineData::QueryHeap; SearchEngineData &engine_working_data; @@ -51,7 +53,7 @@ template class ShortestPathRouting final : public BasicRouti void operator()(const std::vector &phantom_nodes_vector, const std::vector &uturn_indicators, - RawRouteData &raw_route_data) const + InternalRouteResult &raw_route_data) const { int distance1 = 0; int distance2 = 0; @@ -69,10 +71,10 @@ template class ShortestPathRouting final : public BasicRouti engine_working_data.InitializeOrClearThirdThreadLocalStorage( super::facade->GetNumberOfNodes()); - QueryHeap &forward_heap1 = *(engine_working_data.forwardHeap); - QueryHeap &reverse_heap1 = *(engine_working_data.backwardHeap); - QueryHeap &forward_heap2 = *(engine_working_data.forwardHeap2); - QueryHeap &reverse_heap2 = *(engine_working_data.backwardHeap2); + QueryHeap &forward_heap1 = *(engine_working_data.forward_heap_1); + QueryHeap &reverse_heap1 = *(engine_working_data.reverse_heap_1); + QueryHeap &forward_heap2 = *(engine_working_data.forward_heap_2); + QueryHeap &reverse_heap2 = *(engine_working_data.reverse_heap_2); std::size_t current_leg = 0; // Get distance to next pair of target nodes. @@ -88,8 +90,11 @@ template class ShortestPathRouting final : public BasicRouti middle1 = SPECIAL_NODEID; middle2 = SPECIAL_NODEID; - const bool allow_u_turn = current_leg > 0 && uturn_indicators.size() > current_leg && uturn_indicators[current_leg-1]; - EdgeWeight min_edge_offset = 0; + const bool allow_u_turn = current_leg > 0 && uturn_indicators.size() > current_leg && + uturn_indicators[current_leg - 1]; + const EdgeWeight min_edge_offset = + std::min(phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), + phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); // insert new starting nodes into forward heap, adjusted by previous distances. if ((allow_u_turn || search_from_1st_node) && @@ -97,35 +102,32 @@ template class ShortestPathRouting final : public BasicRouti { forward_heap1.Insert( phantom_node_pair.source_phantom.forward_node_id, - (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), + -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), phantom_node_pair.source_phantom.forward_node_id); - min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset()); - // SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(); + // SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << + // phantom_node_pair.source_phantom.forward_node_id << ", w: " << -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(); forward_heap2.Insert( phantom_node_pair.source_phantom.forward_node_id, - (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), + -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), phantom_node_pair.source_phantom.forward_node_id); - min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset()); - // SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(); - + // SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << + // phantom_node_pair.source_phantom.forward_node_id << ", w: " << -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(); } if ((allow_u_turn || search_from_2nd_node) && phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID) { forward_heap1.Insert( phantom_node_pair.source_phantom.reverse_node_id, - (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), + -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), phantom_node_pair.source_phantom.reverse_node_id); - min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); - // SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.reverse_node_id << - // ", w: " << (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); + // SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << + // phantom_node_pair.source_phantom.reverse_node_id << ", w: " << -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); forward_heap2.Insert( phantom_node_pair.source_phantom.reverse_node_id, - (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), + -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), phantom_node_pair.source_phantom.reverse_node_id); - min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); - // SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.reverse_node_id << - // ", w: " << (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); + // SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << + // phantom_node_pair.source_phantom.reverse_node_id << ", w: " << -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); } // insert new backward nodes into backward heap, unadjusted. @@ -134,17 +136,17 @@ template class ShortestPathRouting final : public BasicRouti reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_node_id, phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(), phantom_node_pair.target_phantom.forward_node_id); - // SimpleLogger().Write(logDEBUG) << "rev-a insert: " << phantom_node_pair.target_phantom.forward_node_id << - // ", w: " << phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(); - } + // SimpleLogger().Write(logDEBUG) << "rev-a insert: " << + // phantom_node_pair.target_phantom.forward_node_id << ", w: " << phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(); + } if (phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID) { reverse_heap2.Insert(phantom_node_pair.target_phantom.reverse_node_id, phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(), phantom_node_pair.target_phantom.reverse_node_id); - // SimpleLogger().Write(logDEBUG) << "rev-a insert: " << phantom_node_pair.target_phantom.reverse_node_id << - // ", w: " << phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(); + // SimpleLogger().Write(logDEBUG) << "rev-a insert: " << + // phantom_node_pair.target_phantom.reverse_node_id << ", w: " << phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(); } // run two-Target Dijkstra routing step. @@ -152,13 +154,13 @@ template class ShortestPathRouting final : public BasicRouti { if (!forward_heap1.Empty()) { - super::RoutingStep( - forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, min_edge_offset, true); + super::RoutingStep(forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, + min_edge_offset, true); } if (!reverse_heap1.Empty()) { - super::RoutingStep( - reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, min_edge_offset, false); + super::RoutingStep(reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, + min_edge_offset, false); } } @@ -168,13 +170,13 @@ template class ShortestPathRouting final : public BasicRouti { if (!forward_heap2.Empty()) { - super::RoutingStep( - forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, min_edge_offset, true); + super::RoutingStep(forward_heap2, reverse_heap2, &middle2, + &local_upper_bound2, min_edge_offset, true); } if (!reverse_heap2.Empty()) { - super::RoutingStep( - reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, min_edge_offset, false); + super::RoutingStep(reverse_heap2, forward_heap2, &middle2, + &local_upper_bound2, min_edge_offset, false); } } } @@ -200,29 +202,31 @@ template class ShortestPathRouting final : public BasicRouti } // Was at most one of the two paths not found? - BOOST_ASSERT_MSG((INVALID_EDGE_WEIGHT != distance1 || INVALID_EDGE_WEIGHT != distance2), "no path found"); + BOOST_ASSERT_MSG((INVALID_EDGE_WEIGHT != distance1 || INVALID_EDGE_WEIGHT != distance2), + "no path found"); // Unpack paths if they exist std::vector temporary_packed_leg1; std::vector temporary_packed_leg2; - BOOST_ASSERT((unsigned)current_leg < packed_legs1.size()); - BOOST_ASSERT((unsigned)current_leg < packed_legs2.size()); + BOOST_ASSERT(current_leg < packed_legs1.size()); + BOOST_ASSERT(current_leg < packed_legs2.size()); if (INVALID_EDGE_WEIGHT != local_upper_bound1) { - super::RetrievePackedPathFromHeap( - forward_heap1, reverse_heap1, middle1, temporary_packed_leg1); + super::RetrievePackedPathFromHeap(forward_heap1, reverse_heap1, middle1, + temporary_packed_leg1); } if (INVALID_EDGE_WEIGHT != local_upper_bound2) { - super::RetrievePackedPathFromHeap( - forward_heap2, reverse_heap2, middle2, temporary_packed_leg2); + super::RetrievePackedPathFromHeap(forward_heap2, reverse_heap2, middle2, + temporary_packed_leg2); } // if one of the paths was not found, replace it with the other one. - if ((allow_u_turn && local_upper_bound1 > local_upper_bound2) || temporary_packed_leg1.empty()) + if ((allow_u_turn && local_upper_bound1 > local_upper_bound2) || + temporary_packed_leg1.empty()) { temporary_packed_leg1.clear(); temporary_packed_leg1.insert(temporary_packed_leg1.end(), @@ -230,7 +234,8 @@ template class ShortestPathRouting final : public BasicRouti temporary_packed_leg2.end()); local_upper_bound1 = local_upper_bound2; } - if ((allow_u_turn && local_upper_bound2 > local_upper_bound1) || temporary_packed_leg2.empty()) + if ((allow_u_turn && local_upper_bound2 > local_upper_bound1) || + temporary_packed_leg2.empty()) { temporary_packed_leg2.clear(); temporary_packed_leg2.insert(temporary_packed_leg2.end(), @@ -287,8 +292,9 @@ template class ShortestPathRouting final : public BasicRouti temporary_packed_leg2.end()); BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size()); - if (!allow_u_turn && (packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) && - phantom_node_pair.target_phantom.isBidirected()) + if (!allow_u_turn && + (packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) && + phantom_node_pair.target_phantom.is_bidirected()) { const NodeID last_node_id = packed_legs2[current_leg].back(); search_from_1st_node &= @@ -298,8 +304,8 @@ template class ShortestPathRouting final : public BasicRouti BOOST_ASSERT(search_from_1st_node != search_from_2nd_node); } - distance1 = local_upper_bound1; - distance2 = local_upper_bound2; + distance1 += local_upper_bound1; + distance2 += local_upper_bound2; ++current_leg; } @@ -324,12 +330,14 @@ template class ShortestPathRouting final : public BasicRouti raw_route_data.unpacked_path_segments[index]); raw_route_data.source_traversed_in_reverse.push_back( - (packed_legs1[index].front() != phantom_nodes_vector[index].source_phantom.forward_node_id)); + (packed_legs1[index].front() != + phantom_nodes_vector[index].source_phantom.forward_node_id)); raw_route_data.target_traversed_in_reverse.push_back( - (packed_legs1[index].back() != phantom_nodes_vector[index].target_phantom.forward_node_id)); + (packed_legs1[index].back() != + phantom_nodes_vector[index].target_phantom.forward_node_id)); } raw_route_data.shortest_path_length = std::min(distance1, distance2); } }; -#endif /* SHORTEST_PATH_ROUTING_H */ +#endif /* SHORTEST_PATH_HPP */ diff --git a/3party/osrm/osrm-backend/server/api_grammar.hpp b/3party/osrm/osrm-backend/server/api_grammar.hpp new file mode 100755 index 0000000000..a629cfbf7b --- /dev/null +++ b/3party/osrm/osrm-backend/server/api_grammar.hpp @@ -0,0 +1,101 @@ +/* + +Copyright (c) 2013, 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 API_GRAMMAR_HPP +#define API_GRAMMAR_HPP + +#include +#include +#include + +namespace qi = boost::spirit::qi; + +template struct APIGrammar : qi::grammar +{ + explicit APIGrammar(HandlerT *h) : APIGrammar::base_type(api_call), handler(h) + { + api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> + *(query) >> -(uturns); + query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | timestamp | u | cmp | + language | instruction | geometry | alt_route | old_API | num_results | + matching_beta | gps_precision | classify)); + + zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> + qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)]; + output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> + string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)]; + jsonp = (-qi::lit('&')) >> qi::lit("jsonp") >> '=' >> + stringwithPercent[boost::bind(&HandlerT::setJSONpParameter, handler, ::_1)]; + checksum = (-qi::lit('&')) >> qi::lit("checksum") >> '=' >> + qi::uint_[boost::bind(&HandlerT::setChecksum, handler, ::_1)]; + instruction = (-qi::lit('&')) >> qi::lit("instructions") >> '=' >> + qi::bool_[boost::bind(&HandlerT::setInstructionFlag, handler, ::_1)]; + geometry = (-qi::lit('&')) >> qi::lit("geometry") >> '=' >> + qi::bool_[boost::bind(&HandlerT::setGeometryFlag, handler, ::_1)]; + cmp = (-qi::lit('&')) >> qi::lit("compression") >> '=' >> + qi::bool_[boost::bind(&HandlerT::setCompressionFlag, handler, ::_1)]; + location = (-qi::lit('&')) >> qi::lit("loc") >> '=' >> + (qi::double_ >> qi::lit(',') >> + qi::double_)[boost::bind(&HandlerT::addCoordinate, handler, ::_1)]; + hint = (-qi::lit('&')) >> qi::lit("hint") >> '=' >> + stringwithDot[boost::bind(&HandlerT::addHint, handler, ::_1)]; + timestamp = (-qi::lit('&')) >> qi::lit("t") >> '=' >> + qi::uint_[boost::bind(&HandlerT::addTimestamp, handler, ::_1)]; + u = (-qi::lit('&')) >> qi::lit("u") >> '=' >> + qi::bool_[boost::bind(&HandlerT::setUTurn, handler, ::_1)]; + uturns = (-qi::lit('&')) >> qi::lit("uturns") >> '=' >> + qi::bool_[boost::bind(&HandlerT::setAllUTurns, handler, ::_1)]; + language = (-qi::lit('&')) >> qi::lit("hl") >> '=' >> + string[boost::bind(&HandlerT::setLanguage, handler, ::_1)]; + alt_route = (-qi::lit('&')) >> qi::lit("alt") >> '=' >> + qi::bool_[boost::bind(&HandlerT::setAlternateRouteFlag, handler, ::_1)]; + old_API = (-qi::lit('&')) >> qi::lit("geomformat") >> '=' >> + string[boost::bind(&HandlerT::setDeprecatedAPIFlag, handler, ::_1)]; + num_results = (-qi::lit('&')) >> qi::lit("num_results") >> '=' >> + qi::short_[boost::bind(&HandlerT::setNumberOfResults, handler, ::_1)]; + matching_beta = (-qi::lit('&')) >> qi::lit("matching_beta") >> '=' >> + qi::short_[boost::bind(&HandlerT::setMatchingBeta, handler, ::_1)]; + gps_precision = (-qi::lit('&')) >> qi::lit("gps_precision") >> '=' >> + qi::short_[boost::bind(&HandlerT::setGPSPrecision, handler, ::_1)]; + classify = (-qi::lit('&')) >> qi::lit("classify") >> '=' >> + qi::bool_[boost::bind(&HandlerT::setClassify, handler, ::_1)]; + + string = +(qi::char_("a-zA-Z")); + stringwithDot = +(qi::char_("a-zA-Z0-9_.-")); + stringwithPercent = +(qi::char_("a-zA-Z0-9_.-") | qi::char_('[') | qi::char_(']') | + (qi::char_('%') >> qi::char_("0-9A-Z") >> qi::char_("0-9A-Z"))); + } + + qi::rule api_call, query; + qi::rule service, zoom, output, string, jsonp, checksum, location, + hint, timestamp, stringwithDot, stringwithPercent, language, instruction, geometry, cmp, alt_route, u, + uturns, old_API, num_results, matching_beta, gps_precision, classify; + + HandlerT *handler; +}; + +#endif /* API_GRAMMAR_HPP */ diff --git a/3party/osrm/osrm-backend/Server/Connection.cpp b/3party/osrm/osrm-backend/server/connection.cpp old mode 100644 new mode 100755 similarity index 60% rename from 3party/osrm/osrm-backend/Server/Connection.cpp rename to 3party/osrm/osrm-backend/server/connection.cpp index 674fe62a5b..41b653e824 --- a/3party/osrm/osrm-backend/Server/Connection.cpp +++ b/3party/osrm/osrm-backend/server/connection.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "Connection.h" -#include "RequestHandler.h" -#include "RequestParser.h" +#include "connection.hpp" +#include "request_handler.hpp" +#include "request_parser.hpp" #include #include @@ -52,8 +52,7 @@ void Connection::start() { TCP_socket.async_read_some( boost::asio::buffer(incoming_data_buffer), - strand.wrap(boost::bind(&Connection::handle_read, - this->shared_from_this(), + strand.wrap(boost::bind(&Connection::handle_read, this->shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred))); } @@ -66,19 +65,17 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t } // no error detected, let's parse the request - CompressionType compression_type(noCompression); - boost::tribool result; - boost::tie(result, boost::tuples::ignore) = - request_parser.Parse(request, - incoming_data_buffer.data(), - incoming_data_buffer.data() + bytes_transferred, - &compression_type); + compression_type compression_type(no_compression); + osrm::tribool result; + std::tie(result, compression_type) = + request_parser.parse(current_request, incoming_data_buffer.data(), + incoming_data_buffer.data() + bytes_transferred); // the request has been parsed - if (result) + if (result == osrm::tribool::yes) { - request.endpoint = TCP_socket.remote_endpoint().address(); - request_handler.handle_request(request, reply); + current_request.endpoint = TCP_socket.remote_endpoint().address(); + request_handler.handle_request(current_request, current_reply); // Header compression_header; std::vector compressed_output; @@ -87,52 +84,51 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t // compress the result w/ gzip/deflate if requested switch (compression_type) { - case deflateRFC1951: + case deflate_rfc1951: // use deflate for compression - reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "deflate"}); - CompressBufferCollection(reply.content, compression_type, compressed_output); - reply.SetSize(static_cast(compressed_output.size())); - output_buffer = reply.HeaderstoBuffers(); + current_reply.headers.insert(current_reply.headers.begin(), + {"Content-Encoding", "deflate"}); + compressed_output = compress_buffers(current_reply.content, compression_type); + current_reply.set_size(static_cast(compressed_output.size())); + output_buffer = current_reply.headers_to_buffers(); output_buffer.push_back(boost::asio::buffer(compressed_output)); break; - case gzipRFC1952: + case gzip_rfc1952: // use gzip for compression - reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "gzip"}); - CompressBufferCollection(reply.content, compression_type, compressed_output); - reply.SetSize(static_cast(compressed_output.size())); - output_buffer = reply.HeaderstoBuffers(); + current_reply.headers.insert(current_reply.headers.begin(), + {"Content-Encoding", "gzip"}); + compressed_output = compress_buffers(current_reply.content, compression_type); + current_reply.set_size(static_cast(compressed_output.size())); + output_buffer = current_reply.headers_to_buffers(); output_buffer.push_back(boost::asio::buffer(compressed_output)); break; - case noCompression: + case no_compression: // don't use any compression - reply.SetUncompressedSize(); - output_buffer = reply.ToBuffers(); + current_reply.set_uncompressed_size(); + output_buffer = current_reply.to_buffers(); break; } // write result to stream - boost::asio::async_write(TCP_socket, - output_buffer, - strand.wrap(boost::bind(&Connection::handle_write, - this->shared_from_this(), - boost::asio::placeholders::error))); + boost::asio::async_write( + TCP_socket, output_buffer, + strand.wrap(boost::bind(&Connection::handle_write, this->shared_from_this(), + boost::asio::placeholders::error))); } - else if (!result) + else if (result == osrm::tribool::no) { // request is not parseable - reply = Reply::StockReply(Reply::badRequest); + current_reply = reply::stock_reply(reply::bad_request); - boost::asio::async_write(TCP_socket, - reply.ToBuffers(), - strand.wrap(boost::bind(&Connection::handle_write, - this->shared_from_this(), - boost::asio::placeholders::error))); + boost::asio::async_write( + TCP_socket, current_reply.to_buffers(), + strand.wrap(boost::bind(&Connection::handle_write, this->shared_from_this(), + boost::asio::placeholders::error))); } else { // we don't have a result yet, so continue reading TCP_socket.async_read_some( boost::asio::buffer(incoming_data_buffer), - strand.wrap(boost::bind(&Connection::handle_read, - this->shared_from_this(), + strand.wrap(boost::bind(&Connection::handle_read, this->shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred))); } @@ -149,26 +145,27 @@ void Connection::handle_write(const boost::system::error_code &error) } } -void Connection::CompressBufferCollection(std::vector uncompressed_data, - CompressionType compression_type, - std::vector &compressed_data) +std::vector Connection::compress_buffers(const std::vector &uncompressed_data, + const compression_type compression_type) { boost::iostreams::gzip_params compression_parameters; // there's a trade-off between speed and size. speed wins compression_parameters.level = boost::iostreams::zlib::best_speed; // check which compression flavor is used - if (deflateRFC1951 == compression_type) + if (deflate_rfc1951 == compression_type) { compression_parameters.noheader = true; } - BOOST_ASSERT(compressed_data.empty()); + std::vector compressed_data; // plug data into boost's compression stream boost::iostreams::filtering_ostream gzip_stream; gzip_stream.push(boost::iostreams::gzip_compressor(compression_parameters)); gzip_stream.push(boost::iostreams::back_inserter(compressed_data)); gzip_stream.write(&uncompressed_data[0], uncompressed_data.size()); boost::iostreams::close(gzip_stream); + + return compressed_data; } } diff --git a/3party/osrm/osrm-backend/Server/Connection.h b/3party/osrm/osrm-backend/server/connection.hpp old mode 100644 new mode 100755 similarity index 74% rename from 3party/osrm/osrm-backend/Server/Connection.h rename to 3party/osrm/osrm-backend/server/connection.hpp index bc03c15884..9228a18a00 --- a/3party/osrm/osrm-backend/Server/Connection.h +++ b/3party/osrm/osrm-backend/server/connection.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,45 +25,34 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CONNECTION_H -#define CONNECTION_H +#ifndef CONNECTION_HPP +#define CONNECTION_HPP -#include "RequestParser.h" -#include "Http/CompressionType.h" -#include "Http/Request.h" - -#include +#include "http/compression_type.hpp" +#include "http/reply.hpp" +#include "http/request.hpp" +#include "request_parser.hpp" #include #include #include #include - #include - #include - #include +#include +#include -//workaround for incomplete std::shared_ptr compatibility in old boost versions +// workaround for incomplete std::shared_ptr compatibility in old boost versions #if BOOST_VERSION < 105300 || defined BOOST_NO_CXX11_SMART_PTR -namespace boost { -template -const T* get_pointer(std::shared_ptr const& p) +namespace boost { - return p.get(); -} +template const T *get_pointer(std::shared_ptr const &p) { return p.get(); } -template -T* get_pointer(std::shared_ptr& p) -{ - return p.get(); -} +template T *get_pointer(std::shared_ptr &p) { return p.get(); } } // namespace boost #endif - - class RequestHandler; namespace http @@ -88,19 +77,18 @@ class Connection : public std::enable_shared_from_this /// Handle completion of a write operation. void handle_write(const boost::system::error_code &e); - void CompressBufferCollection(std::vector uncompressed_data, - CompressionType compression_type, - std::vector &compressed_data); + std::vector compress_buffers(const std::vector &uncompressed_data, + const compression_type compression_type); boost::asio::io_service::strand strand; boost::asio::ip::tcp::socket TCP_socket; RequestHandler &request_handler; - boost::array incoming_data_buffer; - Request request; RequestParser request_parser; - Reply reply; + boost::array incoming_data_buffer; + request current_request; + reply current_reply; }; } // namespace http -#endif // CONNECTION_H +#endif // CONNECTION_HPP diff --git a/3party/osrm/osrm-backend/Server/DataStructures/BaseDataFacade.h b/3party/osrm/osrm-backend/server/data_structures/datafacade_base.hpp old mode 100644 new mode 100755 similarity index 70% rename from 3party/osrm/osrm-backend/Server/DataStructures/BaseDataFacade.h rename to 3party/osrm/osrm-backend/server/data_structures/datafacade_base.hpp index b7a46083e3..20d0430576 --- a/3party/osrm/osrm-backend/Server/DataStructures/BaseDataFacade.h +++ b/3party/osrm/osrm-backend/server/data_structures/datafacade_base.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,31 +25,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef BASE_DATA_FACADE_H -#define BASE_DATA_FACADE_H +#ifndef DATAFACADE_BASE_HPP +#define DATAFACADE_BASE_HPP // Exposes all data access interfaces to the algorithms via base class ptr -#include "../../DataStructures/EdgeBasedNode.h" -#include "../../DataStructures/ImportNode.h" -#include "../../DataStructures/PhantomNodes.h" -#include "../../DataStructures/Range.h" -#include "../../DataStructures/TurnInstructions.h" -#include "../../Util/OSRMException.h" -#include "../../Util/StringUtil.h" +#include "../../data_structures/edge_based_node.hpp" +#include "../../data_structures/external_memory_node.hpp" +#include "../../data_structures/phantom_node.hpp" +#include "../../data_structures/turn_instructions.hpp" +#include "../../util/integer_range.hpp" +#include "../../util/osrm_exception.hpp" +#include "../../util/string_util.hpp" #include "../../typedefs.h" -#include "../../Include/osrm/Coordinate.h" +#include #include -typedef osrm::range EdgeRange; +using EdgeRange = osrm::range; template class BaseDataFacade { public: - typedef EdgeBasedNode RTreeLeaf; - typedef EdgeDataT EdgeData; + using RTreeLeaf = EdgeBasedNode; + using EdgeData = EdgeDataT; BaseDataFacade() {} virtual ~BaseDataFacade() {} @@ -62,15 +62,7 @@ template 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) const = 0; - - virtual EdgeDataT GetEdgeData(const EdgeID e, NodeID node) - { - EdgeDataT edge; - return edge; - } + virtual const EdgeDataT &GetEdgeData(const EdgeID e) const = 0; virtual EdgeID BeginEdges(const NodeID n) const = 0; @@ -104,30 +96,28 @@ template class BaseDataFacade FixedPointCoordinate &result, const unsigned zoom_level = 18) = 0; - virtual bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, - PhantomNode &resulting_phantom_node, - const unsigned zoom_level) = 0; - virtual bool IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, std::vector &resulting_phantom_node_vector, - const unsigned zoom_level, const unsigned number_of_results) = 0; + virtual bool + IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, + PhantomNode &resulting_phantom_node) = 0; + virtual bool IncrementalFindPhantomNodeForCoordinateWithMaxDistance( + const FixedPointCoordinate &input_coordinate, + std::vector> &resulting_phantom_node_vector, + const double max_distance, + const unsigned min_number_of_phantom_nodes, + const unsigned max_number_of_phantom_nodes) = 0; + virtual unsigned GetCheckSum() const = 0; virtual unsigned GetNameIndexFromEdgeID(const unsigned id) const = 0; - virtual void GetName(const unsigned name_id, std::string &result) const = 0; - - std::string GetEscapedNameForNameID(const unsigned name_id) const - { - std::string temporary_string; - GetName(name_id, temporary_string); - return EscapeJSONString(temporary_string); - } + virtual std::string get_name_for_id(const unsigned name_id) const = 0; virtual std::string GetTimestamp() const = 0; }; -#endif // BASE_DATA_FACADE_H +#endif // DATAFACADE_BASE_HPP diff --git a/3party/osrm/osrm-backend/Server/DataStructures/InternalDataFacade.h b/3party/osrm/osrm-backend/server/data_structures/internal_datafacade.hpp old mode 100644 new mode 100755 similarity index 73% rename from 3party/osrm/osrm-backend/Server/DataStructures/InternalDataFacade.h rename to 3party/osrm/osrm-backend/server/data_structures/internal_datafacade.hpp index 93c212d004..823ac3329b --- a/3party/osrm/osrm-backend/Server/DataStructures/InternalDataFacade.h +++ b/3party/osrm/osrm-backend/server/data_structures/internal_datafacade.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,35 +25,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef INTERNAL_DATA_FACADE -#define INTERNAL_DATA_FACADE +#ifndef INTERNAL_DATAFACADE_HPP +#define INTERNAL_DATAFACADE_HPP // implements all data storage when shared memory is _NOT_ used -#include "BaseDataFacade.h" +#include "datafacade_base.hpp" -#include "../../DataStructures/OriginalEdgeData.h" -#include "../../DataStructures/QueryNode.h" -#include "../../DataStructures/QueryEdge.h" -#include "../../DataStructures/SharedMemoryVectorWrapper.h" -#include "../../DataStructures/StaticGraph.h" -#include "../../DataStructures/StaticRTree.h" -#include "../../DataStructures/RangeTable.h" -#include "../../Util/BoostFileSystemFix.h" -#include "../../Util/GraphLoader.h" -#include "../../Util/ProgramOptions.h" -#include "../../Util/simple_logger.hpp" +#include "../../data_structures/original_edge_data.hpp" +#include "../../data_structures/query_node.hpp" +#include "../../data_structures/query_edge.hpp" +#include "../../data_structures/shared_memory_vector_wrapper.hpp" +#include "../../data_structures/static_graph.hpp" +#include "../../data_structures/static_rtree.hpp" +#include "../../data_structures/range_table.hpp" +#include "../../util/boost_filesystem_2_fix.hpp" +#include "../../util/graph_loader.hpp" +#include "../../util/simple_logger.hpp" -#include +#include +#include -template class InternalDataFacade : public BaseDataFacade +#include + +template class InternalDataFacade final : public BaseDataFacade { private: - typedef BaseDataFacade super; - typedef StaticGraph QueryGraph; - typedef typename QueryGraph::InputEdge InputEdge; - typedef typename super::RTreeLeaf RTreeLeaf; + using super = BaseDataFacade; + using QueryGraph = StaticGraph; + using InputEdge = typename QueryGraph::InputEdge; + using RTreeLeaf = typename super::RTreeLeaf; InternalDataFacade() {} @@ -126,14 +128,14 @@ template class InternalDataFacade : public BaseDataFacade>(number_of_coordinates); for (unsigned i = 0; i < number_of_coordinates; ++i) { - nodes_input_stream.read((char *)¤t_node, sizeof(NodeInfo)); + nodes_input_stream.read((char *)¤t_node, sizeof(QueryNode)); m_coordinate_list->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon); BOOST_ASSERT((std::abs(m_coordinate_list->at(i).lat) >> 30) == 0); BOOST_ASSERT((std::abs(m_coordinate_list->at(i).lon) >> 30) == 0); @@ -235,31 +237,31 @@ template class InternalDataFacade : public BaseDataFacade class InternalDataFacade : public BaseDataFacadeGetNumberOfNodes(); } + unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); } - unsigned GetNumberOfEdges() const final { return m_query_graph->GetNumberOfEdges(); } + unsigned GetNumberOfEdges() const override final { return m_query_graph->GetNumberOfEdges(); } - unsigned GetOutDegree(const NodeID n) const final { return m_query_graph->GetOutDegree(n); } + unsigned GetOutDegree(const NodeID n) const override final + { + return m_query_graph->GetOutDegree(n); + } - NodeID GetTarget(const EdgeID e) const final { return m_query_graph->GetTarget(e); } + NodeID GetTarget(const EdgeID e) const override final { return m_query_graph->GetTarget(e); } - // EdgeDataT &GetEdgeData(const EdgeID e) final { return m_query_graph->GetEdgeData(e); } + EdgeDataT &GetEdgeData(const EdgeID e) const override final + { + return m_query_graph->GetEdgeData(e); + } - EdgeDataT &GetEdgeData(const EdgeID e) const final { return m_query_graph->GetEdgeData(e); } + EdgeID BeginEdges(const NodeID n) const override final { return m_query_graph->BeginEdges(n); } - EdgeID BeginEdges(const NodeID n) const final { return m_query_graph->BeginEdges(n); } + EdgeID EndEdges(const NodeID n) const override final { return m_query_graph->EndEdges(n); } - EdgeID EndEdges(const NodeID n) const final { return m_query_graph->EndEdges(n); } - - EdgeRange GetAdjacentEdgeRange(const NodeID node) const final + EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final { return m_query_graph->GetAdjacentEdgeRange(node); }; // searches for a specific edge - EdgeID FindEdge(const NodeID from, const NodeID to) const final + EdgeID FindEdge(const NodeID from, const NodeID to) const override final { return m_query_graph->FindEdge(from, to); } - EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const final + EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const override final { return m_query_graph->FindEdgeInEitherDirection(from, to); } - EdgeID FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const final + EdgeID + FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const override final { return m_query_graph->FindEdgeIndicateIfReverse(from, to, result); } // node and edge information access - FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const final + FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const override final { return m_coordinate_list->at(id); }; - bool EdgeIsCompressed(const unsigned id) const { return m_edge_is_compressed.at(id); } + bool EdgeIsCompressed(const unsigned id) const override final + { + return m_edge_is_compressed.at(id); + } - TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const final + TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final { return m_turn_instruction_list.at(id); } - TravelMode GetTravelModeForEdgeID(const unsigned id) const + TravelMode GetTravelModeForEdgeID(const unsigned id) const override final { - return m_travel_mode_list.at(id); + return m_travel_mode_list.at(id); } bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate, FixedPointCoordinate &result, - const unsigned zoom_level = 18) final + const unsigned zoom_level = 18) override final { if (!m_static_rtree.get()) { LoadRTree(); } - return m_static_rtree->LocateClosestEndPointForCoordinate( - input_coordinate, result, zoom_level); + return m_static_rtree->LocateClosestEndPointForCoordinate(input_coordinate, result, + zoom_level); } - bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, - PhantomNode &resulting_phantom_node, - const unsigned zoom_level) final + bool IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, + PhantomNode &resulting_phantom_node) override final { - if (!m_static_rtree.get()) + std::vector resulting_phantom_node_vector; + auto result = IncrementalFindPhantomNodeForCoordinate(input_coordinate, + resulting_phantom_node_vector, 1); + if (result) { - LoadRTree(); + BOOST_ASSERT(!resulting_phantom_node_vector.empty()); + resulting_phantom_node = resulting_phantom_node_vector.front(); } - return m_static_rtree->FindPhantomNodeForCoordinate( - input_coordinate, resulting_phantom_node, zoom_level); + return result; } bool IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, std::vector &resulting_phantom_node_vector, - const unsigned zoom_level, - const unsigned number_of_results) final + const unsigned number_of_results) override final { if (!m_static_rtree.get()) { @@ -402,52 +413,69 @@ template class InternalDataFacade : public BaseDataFacadeIncrementalFindPhantomNodeForCoordinate( - input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results); + input_coordinate, resulting_phantom_node_vector, number_of_results); } - unsigned GetCheckSum() const final { return m_check_sum; } + bool IncrementalFindPhantomNodeForCoordinateWithMaxDistance( + const FixedPointCoordinate &input_coordinate, + std::vector> &resulting_phantom_node_vector, + const double max_distance, + const unsigned min_number_of_phantom_nodes, + const unsigned max_number_of_phantom_nodes) override final + { + if (!m_static_rtree.get()) + { + LoadRTree(); + } - unsigned GetNameIndexFromEdgeID(const unsigned id) const final + return m_static_rtree->IncrementalFindPhantomNodeForCoordinateWithDistance( + input_coordinate, resulting_phantom_node_vector, max_distance, + min_number_of_phantom_nodes, max_number_of_phantom_nodes); + } + + unsigned GetCheckSum() const override final { return m_check_sum; } + + unsigned GetNameIndexFromEdgeID(const unsigned id) const override final { return m_name_ID_list.at(id); - }; + } - void GetName(const unsigned name_id, std::string &result) const final + std::string get_name_for_id(const unsigned name_id) const override final { - if (UINT_MAX == name_id) + if (std::numeric_limits::max() == name_id) { - result = ""; - return; + return ""; } auto range = m_name_table.GetRange(name_id); - result.clear(); + std::string result; + result.reserve(range.size()); if (range.begin() != range.end()) { result.resize(range.back() - range.front() + 1); std::copy(m_names_char_list.begin() + range.front(), - m_names_char_list.begin() + range.back() + 1, - result.begin()); + m_names_char_list.begin() + range.back() + 1, result.begin()); } + return result; } - virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const final + virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const override final { return m_via_node_list.at(id); } virtual void GetUncompressedGeometry(const unsigned id, - std::vector &result_nodes) const final + std::vector &result_nodes) const override final { const unsigned begin = m_geometry_indices.at(id); const unsigned end = m_geometry_indices.at(id + 1); result_nodes.clear(); - result_nodes.insert( - result_nodes.begin(), m_geometry_list.begin() + begin, m_geometry_list.begin() + end); + result_nodes.insert(result_nodes.begin(), m_geometry_list.begin() + begin, + m_geometry_list.begin() + end); } - std::string GetTimestamp() const final { return m_timestamp; } + std::string GetTimestamp() const override final { return m_timestamp; } }; -#endif // INTERNAL_DATA_FACADE +#endif // INTERNAL_DATAFACADE_HPP diff --git a/3party/osrm/osrm-backend/Server/DataStructures/SharedBarriers.h b/3party/osrm/osrm-backend/server/data_structures/shared_barriers.hpp old mode 100644 new mode 100755 similarity index 94% rename from 3party/osrm/osrm-backend/Server/DataStructures/SharedBarriers.h rename to 3party/osrm/osrm-backend/server/data_structures/shared_barriers.hpp index 36ba08b1f7..e6f1234ca8 --- a/3party/osrm/osrm-backend/Server/DataStructures/SharedBarriers.h +++ b/3party/osrm/osrm-backend/server/data_structures/shared_barriers.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SHARED_BARRIER_H -#define SHARED_BARRIER_H +#ifndef SHARED_BARRIERS_HPP +#define SHARED_BARRIERS_HPP #include #include @@ -57,4 +57,4 @@ struct SharedBarriers int number_of_queries; }; -#endif // SHARED_BARRIER_H +#endif // SHARED_BARRIERS_HPP diff --git a/3party/osrm/osrm-backend/Server/DataStructures/SharedDataFacade.h b/3party/osrm/osrm-backend/server/data_structures/shared_datafacade.hpp old mode 100644 new mode 100755 similarity index 71% rename from 3party/osrm/osrm-backend/Server/DataStructures/SharedDataFacade.h rename to 3party/osrm/osrm-backend/server/data_structures/shared_datafacade.hpp index 835a50f273..b156423160 --- a/3party/osrm/osrm-backend/Server/DataStructures/SharedDataFacade.h +++ b/3party/osrm/osrm-backend/server/data_structures/shared_datafacade.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,37 +25,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SHARED_DATA_FACADE_H -#define SHARED_DATA_FACADE_H +#ifndef SHARED_DATAFACADE_HPP +#define SHARED_DATAFACADE_HPP // implements all data storage when shared memory _IS_ used -#include "BaseDataFacade.h" -#include "SharedDataType.h" +#include "datafacade_base.hpp" +#include "shared_datatype.hpp" -#include "../../DataStructures/RangeTable.h" -#include "../../DataStructures/StaticGraph.h" -#include "../../DataStructures/StaticRTree.h" -#include "../../Util/BoostFileSystemFix.h" -#include "../../Util/ProgramOptions.h" -#include "../../Util/make_unique.hpp" -#include "../../Util/simple_logger.hpp" +#include "../../data_structures/range_table.hpp" +#include "../../data_structures/static_graph.hpp" +#include "../../data_structures/static_rtree.hpp" +#include "../../util/boost_filesystem_2_fix.hpp" +#include "../../util/make_unique.hpp" +#include "../../util/simple_logger.hpp" #include +#include #include -template class SharedDataFacade : public BaseDataFacade +template class SharedDataFacade final : public BaseDataFacade { private: - typedef EdgeDataT EdgeData; - typedef BaseDataFacade super; - typedef StaticGraph QueryGraph; - typedef typename StaticGraph::NodeArrayEntry GraphNode; - typedef typename StaticGraph::EdgeArrayEntry GraphEdge; - typedef typename RangeTable<16, true>::BlockT NameIndexBlock; - typedef typename QueryGraph::InputEdge InputEdge; - typedef typename super::RTreeLeaf RTreeLeaf; + using EdgeData = EdgeDataT; + using super = BaseDataFacade; + using QueryGraph = StaticGraph; + using GraphNode = typename StaticGraph::NodeArrayEntry; + using GraphEdge = typename StaticGraph::EdgeArrayEntry; + using NameIndexBlock = typename RangeTable<16, true>::BlockT; + using InputEdge = typename QueryGraph::InputEdge; + using RTreeLeaf = typename super::RTreeLeaf; using SharedRTree = StaticRTree::vector, true>; using TimeStampedRTreePair = std::pair>; using RTreeNode = typename SharedRTree::TreeNode; @@ -113,12 +113,11 @@ template class SharedDataFacade : public BaseDataFacadeGetBlockPtr(shared_memory, SharedDataLayout::R_SEARCH_TREE); - m_static_rtree.reset(new TimeStampedRTreePair(CURRENT_TIMESTAMP, + m_static_rtree.reset(new TimeStampedRTreePair( + CURRENT_TIMESTAMP, osrm::make_unique( - tree_ptr, - data_layout->num_entries[SharedDataLayout::R_SEARCH_TREE], - file_index_path, - m_coordinate_list))); + tree_ptr, data_layout->num_entries[SharedDataLayout::R_SEARCH_TREE], + file_index_path, m_coordinate_list))); } void LoadGraph() @@ -144,11 +143,10 @@ template class SharedDataFacade : public BaseDataFacade::vector>( coordinate_list_ptr, data_layout->num_entries[SharedDataLayout::COORDINATE_LIST]); - TravelMode *travel_mode_list_ptr = data_layout->GetBlockPtr( - shared_memory, SharedDataLayout::TRAVEL_MODE); + TravelMode *travel_mode_list_ptr = + data_layout->GetBlockPtr(shared_memory, SharedDataLayout::TRAVEL_MODE); typename ShM::vector travel_mode_list( - travel_mode_list_ptr, - data_layout->num_entries[SharedDataLayout::TRAVEL_MODE]); + travel_mode_list_ptr, data_layout->num_entries[SharedDataLayout::TRAVEL_MODE]); m_travel_mode_list.swap(travel_mode_list); TurnInstruction *turn_instruction_list_ptr = data_layout->GetBlockPtr( @@ -259,8 +257,8 @@ template class SharedDataFacade : public BaseDataFacade class SharedDataFacade : public BaseDataFacadesize(); for (unsigned i = 0; i < m_coordinate_list->size(); ++i) { - if (!GetCoordinateOfNode(i).isValid()) + if (!GetCoordinateOfNode(i).is_valid()) { SimpleLogger().Write() << "coordinate " << i << " not valid"; } @@ -285,109 +283,117 @@ template class SharedDataFacade : public BaseDataFacadeGetNumberOfNodes(); } + unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); } - unsigned GetNumberOfEdges() const final { return m_query_graph->GetNumberOfEdges(); } + unsigned GetNumberOfEdges() const override final { return m_query_graph->GetNumberOfEdges(); } - unsigned GetOutDegree(const NodeID n) const final { return m_query_graph->GetOutDegree(n); } + unsigned GetOutDegree(const NodeID n) const override final + { + return m_query_graph->GetOutDegree(n); + } - NodeID GetTarget(const EdgeID e) const final { return m_query_graph->GetTarget(e); } + NodeID GetTarget(const EdgeID e) const override final { return m_query_graph->GetTarget(e); } - EdgeDataT &GetEdgeData(const EdgeID e) const final { return m_query_graph->GetEdgeData(e); } + EdgeDataT &GetEdgeData(const EdgeID e) const override final + { + return m_query_graph->GetEdgeData(e); + } - EdgeID BeginEdges(const NodeID n) const final { return m_query_graph->BeginEdges(n); } + EdgeID BeginEdges(const NodeID n) const override final { return m_query_graph->BeginEdges(n); } - EdgeID EndEdges(const NodeID n) const final { return m_query_graph->EndEdges(n); } + EdgeID EndEdges(const NodeID n) const override final { return m_query_graph->EndEdges(n); } - EdgeRange GetAdjacentEdgeRange(const NodeID node) const final + EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final { return m_query_graph->GetAdjacentEdgeRange(node); }; // searches for a specific edge - EdgeID FindEdge(const NodeID from, const NodeID to) const final + EdgeID FindEdge(const NodeID from, const NodeID to) const override final { return m_query_graph->FindEdge(from, to); } - EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const final + EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const override final { return m_query_graph->FindEdgeInEitherDirection(from, to); } - EdgeID FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const final + EdgeID + FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const override final { return m_query_graph->FindEdgeIndicateIfReverse(from, to, result); } // node and edge information access - FixedPointCoordinate GetCoordinateOfNode(const NodeID id) const final + FixedPointCoordinate GetCoordinateOfNode(const NodeID id) const override final { return m_coordinate_list->at(id); }; - virtual bool EdgeIsCompressed(const unsigned id) const final + virtual bool EdgeIsCompressed(const unsigned id) const override final { return m_edge_is_compressed.at(id); } virtual void GetUncompressedGeometry(const unsigned id, - std::vector &result_nodes) const final + std::vector &result_nodes) const override final { const unsigned begin = m_geometry_indices.at(id); const unsigned end = m_geometry_indices.at(id + 1); result_nodes.clear(); - result_nodes.insert( - result_nodes.begin(), m_geometry_list.begin() + begin, m_geometry_list.begin() + end); + result_nodes.insert(result_nodes.begin(), m_geometry_list.begin() + begin, + m_geometry_list.begin() + end); } - virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const final + virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const override final { return m_via_node_list.at(id); } - TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const final + TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final { return m_turn_instruction_list.at(id); } - TravelMode GetTravelModeForEdgeID(const unsigned id) const + TravelMode GetTravelModeForEdgeID(const unsigned id) const override final { return m_travel_mode_list.at(id); } bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate, FixedPointCoordinate &result, - const unsigned zoom_level = 18) final + const unsigned zoom_level = 18) override final { if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first) { LoadRTree(); } - return m_static_rtree->second->LocateClosestEndPointForCoordinate( - input_coordinate, result, zoom_level); + return m_static_rtree->second->LocateClosestEndPointForCoordinate(input_coordinate, result, + zoom_level); } - bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, - PhantomNode &resulting_phantom_node, - const unsigned zoom_level) final + bool IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, + PhantomNode &resulting_phantom_node) override final { - if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first) + std::vector resulting_phantom_node_vector; + auto result = IncrementalFindPhantomNodeForCoordinate(input_coordinate, + resulting_phantom_node_vector, 1); + if (result) { - LoadRTree(); + BOOST_ASSERT(!resulting_phantom_node_vector.empty()); + resulting_phantom_node = resulting_phantom_node_vector.front(); } - return m_static_rtree->second->FindPhantomNodeForCoordinate( - input_coordinate, resulting_phantom_node, zoom_level); + return result; } bool IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate, std::vector &resulting_phantom_node_vector, - const unsigned zoom_level, - const unsigned number_of_results) final + const unsigned number_of_results) override final { if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first) { @@ -395,36 +401,53 @@ template class SharedDataFacade : public BaseDataFacadesecond->IncrementalFindPhantomNodeForCoordinate( - input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results); + input_coordinate, resulting_phantom_node_vector, number_of_results); } - unsigned GetCheckSum() const final { return m_check_sum; } + bool IncrementalFindPhantomNodeForCoordinateWithMaxDistance( + const FixedPointCoordinate &input_coordinate, + std::vector> &resulting_phantom_node_vector, + const double max_distance, + const unsigned min_number_of_phantom_nodes, + const unsigned max_number_of_phantom_nodes) override final + { + if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first) + { + LoadRTree(); + } - unsigned GetNameIndexFromEdgeID(const unsigned id) const final + return m_static_rtree->second->IncrementalFindPhantomNodeForCoordinateWithDistance( + input_coordinate, resulting_phantom_node_vector, max_distance, + min_number_of_phantom_nodes, max_number_of_phantom_nodes); + } + + unsigned GetCheckSum() const override final { return m_check_sum; } + + unsigned GetNameIndexFromEdgeID(const unsigned id) const override final { return m_name_ID_list.at(id); }; - void GetName(const unsigned name_id, std::string &result) const final + std::string get_name_for_id(const unsigned name_id) const override final { - if (UINT_MAX == name_id) + if (std::numeric_limits::max() == name_id) { - result = ""; - return; + return ""; } auto range = m_name_table->GetRange(name_id); - result.clear(); + std::string result; + result.reserve(range.size()); if (range.begin() != range.end()) { result.resize(range.back() - range.front() + 1); std::copy(m_names_char_list.begin() + range.front(), - m_names_char_list.begin() + range.back() + 1, - result.begin()); + m_names_char_list.begin() + range.back() + 1, result.begin()); } + return result; } - std::string GetTimestamp() const final { return m_timestamp; } + std::string GetTimestamp() const override final { return m_timestamp; } }; -#endif // SHARED_DATA_FACADE_H +#endif // SHARED_DATAFACADE_HPP diff --git a/3party/osrm/osrm-backend/Server/DataStructures/SharedDataType.h b/3party/osrm/osrm-backend/server/data_structures/shared_datatype.hpp old mode 100644 new mode 100755 similarity index 50% rename from 3party/osrm/osrm-backend/Server/DataStructures/SharedDataType.h rename to 3party/osrm/osrm-backend/server/data_structures/shared_datatype.hpp index 5f07f131fc..326157389b --- a/3party/osrm/osrm-backend/Server/DataStructures/SharedDataType.h +++ b/3party/osrm/osrm-backend/server/data_structures/shared_datatype.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,22 +25,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SHARED_DATA_TYPE_H_ -#define SHARED_DATA_TYPE_H_ +#ifndef SHARED_DATA_TYPE_HPP +#define SHARED_DATA_TYPE_HPP -#include "../../Util/OSRMException.h" -#include "../../Util/simple_logger.hpp" +#include "../../util/osrm_exception.hpp" +#include "../../util/simple_logger.hpp" #include #include +namespace +{ // Added at the start and end of each block as sanity check static const char CANARY[] = "OSRM"; +} struct SharedDataLayout { - enum BlockID { + enum BlockID + { NAME_OFFSETS = 0, NAME_BLOCKS, NAME_CHAR_LIST, @@ -64,54 +68,81 @@ struct SharedDataLayout std::array num_entries; std::array entry_size; - SharedDataLayout() - : num_entries() - , entry_size() - { - } + SharedDataLayout() : num_entries(), entry_size() {} void PrintInformation() const { SimpleLogger().Write(logDEBUG) << "-"; - SimpleLogger().Write(logDEBUG) << "name_offsets_size: " << num_entries[NAME_OFFSETS]; - SimpleLogger().Write(logDEBUG) << "name_blocks_size: " << num_entries[NAME_BLOCKS]; - SimpleLogger().Write(logDEBUG) << "name_char_list_size: " << num_entries[NAME_CHAR_LIST]; - SimpleLogger().Write(logDEBUG) << "name_id_list_size: " << num_entries[NAME_ID_LIST]; - SimpleLogger().Write(logDEBUG) << "via_node_list_size: " << num_entries[VIA_NODE_LIST]; - SimpleLogger().Write(logDEBUG) << "graph_node_list_size: " << num_entries[GRAPH_NODE_LIST]; - SimpleLogger().Write(logDEBUG) << "graph_edge_list_size: " << num_entries[GRAPH_EDGE_LIST]; + SimpleLogger().Write(logDEBUG) + << "name_offsets_size: " << num_entries[NAME_OFFSETS]; + SimpleLogger().Write(logDEBUG) + << "name_blocks_size: " << num_entries[NAME_BLOCKS]; + SimpleLogger().Write(logDEBUG) + << "name_char_list_size: " << num_entries[NAME_CHAR_LIST]; + SimpleLogger().Write(logDEBUG) + << "name_id_list_size: " << num_entries[NAME_ID_LIST]; + SimpleLogger().Write(logDEBUG) + << "via_node_list_size: " << num_entries[VIA_NODE_LIST]; + SimpleLogger().Write(logDEBUG) + << "graph_node_list_size: " << num_entries[GRAPH_NODE_LIST]; + SimpleLogger().Write(logDEBUG) + << "graph_edge_list_size: " << num_entries[GRAPH_EDGE_LIST]; SimpleLogger().Write(logDEBUG) << "timestamp_length: " << num_entries[TIMESTAMP]; - SimpleLogger().Write(logDEBUG) << "coordinate_list_size: " << num_entries[COORDINATE_LIST]; - SimpleLogger().Write(logDEBUG) << "turn_instruction_list_size: " << num_entries[TURN_INSTRUCTION]; - SimpleLogger().Write(logDEBUG) << "travel_mode_list_size: " << num_entries[TRAVEL_MODE]; - SimpleLogger().Write(logDEBUG) << "r_search_tree_size: " << num_entries[R_SEARCH_TREE]; - SimpleLogger().Write(logDEBUG) << "geometries_indicators: " << num_entries[GEOMETRIES_INDICATORS] - << "/" << ((num_entries[GEOMETRIES_INDICATORS] / 8) + 1); - SimpleLogger().Write(logDEBUG) << "geometries_index_list_size: " << num_entries[GEOMETRIES_INDEX]; - SimpleLogger().Write(logDEBUG) << "geometries_list_size: " << num_entries[GEOMETRIES_LIST]; - SimpleLogger().Write(logDEBUG) << "sizeof(checksum): " << entry_size[HSGR_CHECKSUM]; + SimpleLogger().Write(logDEBUG) + << "coordinate_list_size: " << num_entries[COORDINATE_LIST]; + SimpleLogger().Write(logDEBUG) + << "turn_instruction_list_size: " << num_entries[TURN_INSTRUCTION]; + SimpleLogger().Write(logDEBUG) + << "travel_mode_list_size: " << num_entries[TRAVEL_MODE]; + SimpleLogger().Write(logDEBUG) + << "r_search_tree_size: " << num_entries[R_SEARCH_TREE]; + SimpleLogger().Write(logDEBUG) + << "geometries_indicators: " << num_entries[GEOMETRIES_INDICATORS] << "/" + << ((num_entries[GEOMETRIES_INDICATORS] / 8) + 1); + SimpleLogger().Write(logDEBUG) + << "geometries_index_list_size: " << num_entries[GEOMETRIES_INDEX]; + SimpleLogger().Write(logDEBUG) + << "geometries_list_size: " << num_entries[GEOMETRIES_LIST]; + SimpleLogger().Write(logDEBUG) + << "sizeof(checksum): " << entry_size[HSGR_CHECKSUM]; - SimpleLogger().Write(logDEBUG) << "NAME_OFFSETS " << ": " << GetBlockSize(NAME_OFFSETS ); - SimpleLogger().Write(logDEBUG) << "NAME_BLOCKS " << ": " << GetBlockSize(NAME_BLOCKS ); - SimpleLogger().Write(logDEBUG) << "NAME_CHAR_LIST " << ": " << GetBlockSize(NAME_CHAR_LIST ); - SimpleLogger().Write(logDEBUG) << "NAME_ID_LIST " << ": " << GetBlockSize(NAME_ID_LIST ); - SimpleLogger().Write(logDEBUG) << "VIA_NODE_LIST " << ": " << GetBlockSize(VIA_NODE_LIST ); - SimpleLogger().Write(logDEBUG) << "GRAPH_NODE_LIST " << ": " << GetBlockSize(GRAPH_NODE_LIST ); - SimpleLogger().Write(logDEBUG) << "GRAPH_EDGE_LIST " << ": " << GetBlockSize(GRAPH_EDGE_LIST ); - SimpleLogger().Write(logDEBUG) << "COORDINATE_LIST " << ": " << GetBlockSize(COORDINATE_LIST ); - SimpleLogger().Write(logDEBUG) << "TURN_INSTRUCTION " << ": " << GetBlockSize(TURN_INSTRUCTION ); - SimpleLogger().Write(logDEBUG) << "TRAVEL_MODE " << ": " << GetBlockSize(TRAVEL_MODE ); - SimpleLogger().Write(logDEBUG) << "R_SEARCH_TREE " << ": " << GetBlockSize(R_SEARCH_TREE ); - SimpleLogger().Write(logDEBUG) << "GEOMETRIES_INDEX " << ": " << GetBlockSize(GEOMETRIES_INDEX ); - SimpleLogger().Write(logDEBUG) << "GEOMETRIES_LIST " << ": " << GetBlockSize(GEOMETRIES_LIST ); - SimpleLogger().Write(logDEBUG) << "GEOMETRIES_INDICATORS" << ": " << GetBlockSize(GEOMETRIES_INDICATORS); - SimpleLogger().Write(logDEBUG) << "HSGR_CHECKSUM " << ": " << GetBlockSize(HSGR_CHECKSUM ); - SimpleLogger().Write(logDEBUG) << "TIMESTAMP " << ": " << GetBlockSize(TIMESTAMP ); - SimpleLogger().Write(logDEBUG) << "FILE_INDEX_PATH " << ": " << GetBlockSize(FILE_INDEX_PATH ); + SimpleLogger().Write(logDEBUG) << "NAME_OFFSETS " + << ": " << GetBlockSize(NAME_OFFSETS); + SimpleLogger().Write(logDEBUG) << "NAME_BLOCKS " + << ": " << GetBlockSize(NAME_BLOCKS); + SimpleLogger().Write(logDEBUG) << "NAME_CHAR_LIST " + << ": " << GetBlockSize(NAME_CHAR_LIST); + SimpleLogger().Write(logDEBUG) << "NAME_ID_LIST " + << ": " << GetBlockSize(NAME_ID_LIST); + SimpleLogger().Write(logDEBUG) << "VIA_NODE_LIST " + << ": " << GetBlockSize(VIA_NODE_LIST); + SimpleLogger().Write(logDEBUG) << "GRAPH_NODE_LIST " + << ": " << GetBlockSize(GRAPH_NODE_LIST); + SimpleLogger().Write(logDEBUG) << "GRAPH_EDGE_LIST " + << ": " << GetBlockSize(GRAPH_EDGE_LIST); + SimpleLogger().Write(logDEBUG) << "COORDINATE_LIST " + << ": " << GetBlockSize(COORDINATE_LIST); + SimpleLogger().Write(logDEBUG) << "TURN_INSTRUCTION " + << ": " << GetBlockSize(TURN_INSTRUCTION); + SimpleLogger().Write(logDEBUG) << "TRAVEL_MODE " + << ": " << GetBlockSize(TRAVEL_MODE); + SimpleLogger().Write(logDEBUG) << "R_SEARCH_TREE " + << ": " << GetBlockSize(R_SEARCH_TREE); + SimpleLogger().Write(logDEBUG) << "GEOMETRIES_INDEX " + << ": " << GetBlockSize(GEOMETRIES_INDEX); + SimpleLogger().Write(logDEBUG) << "GEOMETRIES_LIST " + << ": " << GetBlockSize(GEOMETRIES_LIST); + SimpleLogger().Write(logDEBUG) << "GEOMETRIES_INDICATORS" + << ": " << GetBlockSize(GEOMETRIES_INDICATORS); + SimpleLogger().Write(logDEBUG) << "HSGR_CHECKSUM " + << ": " << GetBlockSize(HSGR_CHECKSUM); + SimpleLogger().Write(logDEBUG) << "TIMESTAMP " + << ": " << GetBlockSize(TIMESTAMP); + SimpleLogger().Write(logDEBUG) << "FILE_INDEX_PATH " + << ": " << GetBlockSize(FILE_INDEX_PATH); } - template - inline void SetBlockSize(BlockID bid, uint64_t entries) + template inline void SetBlockSize(BlockID bid, uint64_t entries) { num_entries[bid] = entries; entry_size[bid] = sizeof(T); @@ -122,7 +153,8 @@ struct SharedDataLayout // special encoding if (bid == GEOMETRIES_INDICATORS) { - return (num_entries[GEOMETRIES_INDICATORS]/32 + 1) * entry_size[GEOMETRIES_INDICATORS]; + return (num_entries[GEOMETRIES_INDICATORS] / 32 + 1) * + entry_size[GEOMETRIES_INDICATORS]; } return num_entries[bid] * entry_size[bid]; @@ -130,7 +162,7 @@ struct SharedDataLayout inline uint64_t GetSizeOfLayout() const { - return GetBlockOffset(NUM_BLOCKS) + NUM_BLOCKS*2*sizeof(CANARY); + return GetBlockOffset(NUM_BLOCKS) + NUM_BLOCKS * 2 * sizeof(CANARY); } inline uint64_t GetBlockOffset(BlockID bid) const @@ -138,35 +170,35 @@ struct SharedDataLayout uint64_t result = sizeof(CANARY); for (auto i = 0; i < bid; i++) { - result += GetBlockSize((BlockID) i) + 2*sizeof(CANARY); + result += GetBlockSize((BlockID)i) + 2 * sizeof(CANARY); } return result; } - template - inline T* GetBlockPtr(char* shared_memory, BlockID bid) + template + inline T *GetBlockPtr(char *shared_memory, BlockID bid) { - T* ptr = (T*)(shared_memory + GetBlockOffset(bid)); + T *ptr = (T *)(shared_memory + GetBlockOffset(bid)); if (WRITE_CANARY) { - char* start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY); - char* end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid); + char *start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY); + char *end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid); std::copy(CANARY, CANARY + sizeof(CANARY), start_canary_ptr); std::copy(CANARY, CANARY + sizeof(CANARY), end_canary_ptr); } else { - char* start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY); - char* end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid); + char *start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY); + char *end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid); bool start_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), start_canary_ptr); bool end_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), end_canary_ptr); if (!start_canary_alive) { - throw OSRMException("Start canary of block corrupted."); + throw osrm::exception("Start canary of block corrupted."); } if (!end_canary_alive) { - throw OSRMException("End canary of block corrupted."); + throw osrm::exception("End canary of block corrupted."); } } @@ -175,13 +207,15 @@ struct SharedDataLayout }; enum SharedDataType -{ CURRENT_REGIONS, - LAYOUT_1, - DATA_1, - LAYOUT_2, - DATA_2, - LAYOUT_NONE, - DATA_NONE }; +{ + CURRENT_REGIONS, + LAYOUT_1, + DATA_1, + LAYOUT_2, + DATA_2, + LAYOUT_NONE, + DATA_NONE +}; struct SharedDataTimestamp { @@ -190,4 +224,4 @@ struct SharedDataTimestamp unsigned timestamp; }; -#endif /* SHARED_DATA_TYPE_H_ */ +#endif /* SHARED_DATA_TYPE_HPP */ diff --git a/3party/osrm/osrm-backend/Server/Http/CompressionType.h b/3party/osrm/osrm-backend/server/http/compression_type.hpp old mode 100644 new mode 100755 similarity index 84% rename from 3party/osrm/osrm-backend/Server/Http/CompressionType.h rename to 3party/osrm/osrm-backend/server/http/compression_type.hpp index 74d0b629b9..f0dc692fa6 --- a/3party/osrm/osrm-backend/Server/Http/CompressionType.h +++ b/3party/osrm/osrm-backend/server/http/compression_type.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,17 +25,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef COMPRESSION_TYPE_H -#define COMPRESSION_TYPE_H +#ifndef COMPRESSION_TYPE_HPP +#define COMPRESSION_TYPE_HPP namespace http { -enum CompressionType -{ noCompression, - gzipRFC1952, - deflateRFC1951 }; +enum compression_type +{ + no_compression, + gzip_rfc1952, + deflate_rfc1951 +}; +} -} // namespace http - -#endif // COMPRESSION_TYPE_H +#endif // COMPRESSION_TYPE_HPP diff --git a/3party/osrm/osrm-backend/Include/osrm/Header.h b/3party/osrm/osrm-backend/server/http/header.hpp old mode 100644 new mode 100755 similarity index 76% rename from 3party/osrm/osrm-backend/Include/osrm/Header.h rename to 3party/osrm/osrm-backend/server/http/header.hpp index d126c4c989..08d2476b18 --- a/3party/osrm/osrm-backend/Include/osrm/Header.h +++ b/3party/osrm/osrm-backend/server/http/header.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,21 +25,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HTTP_HEADER_H -#define HTTP_HEADER_H +#ifndef HEADER_HPP +#define HEADER_HPP #include #include namespace http { -struct Header +struct header { - Header& operator=(const Header& other) = default; - Header(const std::string & name, const std::string & value) : name(name), value(value) {} - Header(Header && other) : name(std::move(other.name)), value(std::move(other.value)) {} + // explicitly use default copy c'tor as adding move c'tor + header &operator=(const header &other) = default; + header(const std::string &name, const std::string &value) : name(name), value(value) {} + header(header &&other) : name(std::move(other.name)), value(std::move(other.value)) {} - void Clear() + void clear() { name.clear(); value.clear(); @@ -50,4 +51,4 @@ struct Header }; } -#endif // HTTP_HEADER_H +#endif // HEADER_HPP diff --git a/3party/osrm/osrm-backend/Server/Http/Reply.cpp b/3party/osrm/osrm-backend/server/http/reply.cpp old mode 100644 new mode 100755 similarity index 59% rename from 3party/osrm/osrm-backend/Server/Http/Reply.cpp rename to 3party/osrm/osrm-backend/server/http/reply.cpp index e2cf0aecf8..036d1ae05f --- a/3party/osrm/osrm-backend/Server/Http/Reply.cpp +++ b/3party/osrm/osrm-backend/server/http/reply.cpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,16 +25,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include "reply.hpp" -#include "../../Util/cast.hpp" +#include "../../util/cast.hpp" namespace http { -void Reply::SetSize(const unsigned size) +const char ok_html[] = ""; +const char bad_request_html[] = "{\"status\": 400,\"status_message\":\"Bad Request\"}"; +const char internal_server_error_html[] = + "{\"status\": 500,\"status_message\":\"Internal Server Error\"}"; +const char seperators[] = {':', ' '}; +const char crlf[] = {'\r', '\n'}; +const std::string http_ok_string = "HTTP/1.0 200 OK\r\n"; +const std::string http_bad_request_string = "HTTP/1.0 400 Bad Request\r\n"; +const std::string http_internal_server_error_string = "HTTP/1.0 500 Internal Server Error\r\n"; + +void reply::set_size(const std::size_t size) { - for (Header &h : headers) + for (header &h : headers) { if ("Content-Length" == h.name) { @@ -43,14 +53,13 @@ void Reply::SetSize(const unsigned size) } } -// Sets the size of the uncompressed output. -void Reply::SetUncompressedSize() { SetSize(static_cast(content.size())); } +void reply::set_uncompressed_size() { set_size(content.size()); } -std::vector Reply::ToBuffers() +std::vector reply::to_buffers() { std::vector buffers; - buffers.push_back(ToBuffer(status)); - for (const Header &h : headers) + buffers.push_back(status_to_buffer(status)); + for (const header &h : headers) { buffers.push_back(boost::asio::buffer(h.name)); buffers.push_back(boost::asio::buffer(seperators)); @@ -62,13 +71,12 @@ std::vector Reply::ToBuffers() return buffers; } -std::vector Reply::HeaderstoBuffers() +std::vector reply::headers_to_buffers() { std::vector buffers; - buffers.push_back(ToBuffer(status)); - for (std::size_t i = 0; i < headers.size(); ++i) + buffers.push_back(status_to_buffer(status)); + for (const header ¤t_header : headers) { - Header ¤t_header = headers[i]; buffers.push_back(boost::asio::buffer(current_header.name)); buffers.push_back(boost::asio::buffer(seperators)); buffers.push_back(boost::asio::buffer(current_header.value)); @@ -78,13 +86,13 @@ std::vector Reply::HeaderstoBuffers() return buffers; } -Reply Reply::StockReply(Reply::status_type status) +reply reply::stock_reply(const reply::status_type status) { - Reply reply; + reply reply; reply.status = status; reply.content.clear(); - const std::string status_string = reply.ToString(status); + const std::string status_string = reply.status_to_string(status); reply.content.insert(reply.content.end(), status_string.begin(), status_string.end()); reply.headers.emplace_back("Access-Control-Allow-Origin", "*"); reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size())); @@ -92,31 +100,31 @@ Reply Reply::StockReply(Reply::status_type status) return reply; } -std::string Reply::ToString(Reply::status_type status) +std::string reply::status_to_string(const reply::status_type status) { - if (Reply::ok == status) + if (reply::ok == status) { - return okHTML; + return ok_html; } - if (Reply::badRequest == status) + if (reply::bad_request == status) { - return badRequestHTML; + return bad_request_html; } - return internalServerErrorHTML; + return internal_server_error_html; } -boost::asio::const_buffer Reply::ToBuffer(Reply::status_type status) +boost::asio::const_buffer reply::status_to_buffer(const reply::status_type status) { - if (Reply::ok == status) + if (reply::ok == status) { - return boost::asio::buffer(okString); + return boost::asio::buffer(http_ok_string); } - if (Reply::internalServerError == status) + if (reply::internal_server_error == status) { - return boost::asio::buffer(internalServerErrorString); + return boost::asio::buffer(http_internal_server_error_string); } - return boost::asio::buffer(badRequestString); + return boost::asio::buffer(http_bad_request_string); } -Reply::Reply() : status(ok) {} +reply::reply() : status(ok) {} } diff --git a/3party/osrm/osrm-backend/server/http/reply.hpp b/3party/osrm/osrm-backend/server/http/reply.hpp new file mode 100755 index 0000000000..733818c2c9 --- /dev/null +++ b/3party/osrm/osrm-backend/server/http/reply.hpp @@ -0,0 +1,65 @@ +/* + +Copyright (c) 2015, 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 REPLY_HPP +#define REPLY_HPP + +#include "header.hpp" + +#include + +#include + +namespace http +{ +class reply +{ + public: + enum status_type + { + ok = 200, + bad_request = 400, + internal_server_error = 500 + } status; + + std::vector
headers; + std::vector to_buffers(); + std::vector headers_to_buffers(); + std::vector content; + static reply stock_reply(const status_type status); + void set_size(const std::size_t size); + void set_uncompressed_size(); + + reply(); + + private: + std::string status_to_string(reply::status_type status); + boost::asio::const_buffer status_to_buffer(reply::status_type status); +}; +} + +#endif // REPLY_HPP diff --git a/3party/osrm/osrm-backend/Server/Http/Request.h b/3party/osrm/osrm-backend/server/http/request.hpp old mode 100644 new mode 100755 similarity index 92% rename from 3party/osrm/osrm-backend/Server/Http/Request.h rename to 3party/osrm/osrm-backend/server/http/request.hpp index 4746a5ec2a..c487fba65a --- a/3party/osrm/osrm-backend/Server/Http/Request.h +++ b/3party/osrm/osrm-backend/server/http/request.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef REQUEST_H -#define REQUEST_H +#ifndef REQUEST_HPP +#define REQUEST_HPP #include @@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace http { -struct Request +struct request { std::string uri; std::string referrer; @@ -45,4 +45,4 @@ struct Request } // namespace http -#endif // REQUEST_H +#endif // REQUEST_HPP diff --git a/3party/osrm/osrm-backend/server/request_handler.cpp b/3party/osrm/osrm-backend/server/request_handler.cpp new file mode 100755 index 0000000000..d1c6e6265c --- /dev/null +++ b/3party/osrm/osrm-backend/server/request_handler.cpp @@ -0,0 +1,175 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "request_handler.hpp" + +#include "api_grammar.hpp" +#include "http/reply.hpp" +#include "http/request.hpp" + +#include "../library/osrm.hpp" +#include "../util/json_renderer.hpp" +#include "../util/simple_logger.hpp" +#include "../util/string_util.hpp" +#include "../util/xml_renderer.hpp" +#include "../typedefs.h" + +#include +#include + +#include + +#include +#include + +RequestHandler::RequestHandler() : routing_machine(nullptr) {} + +void RequestHandler::handle_request(const http::request ¤t_request, + http::reply ¤t_reply) +{ + // parse command + try + { + std::string request_string; + URIDecode(current_request.uri, request_string); + + // deactivated as GCC apparently does not implement that, not even in 4.9 + // std::time_t t = std::time(nullptr); + // SimpleLogger().Write() << std::put_time(std::localtime(&t), "%m-%d-%Y %H:%M:%S") << + // " " << current_request.endpoint.to_string() << " " << + // current_request.referrer << ( 0 == current_request.referrer.length() ? "- " :" ") << + // current_request.agent << ( 0 == current_request.agent.length() ? "- " :" ") << + // request; + + time_t ltime; + struct tm *time_stamp; + + ltime = time(nullptr); + time_stamp = localtime(<ime); + + // log timestamp + SimpleLogger().Write() << (time_stamp->tm_mday < 10 ? "0" : "") << time_stamp->tm_mday + << "-" << (time_stamp->tm_mon + 1 < 10 ? "0" : "") + << (time_stamp->tm_mon + 1) << "-" << 1900 + time_stamp->tm_year + << " " << (time_stamp->tm_hour < 10 ? "0" : "") + << time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "") + << time_stamp->tm_min << ":" << (time_stamp->tm_sec < 10 ? "0" : "") + << time_stamp->tm_sec << " " << current_request.endpoint.to_string() + << " " << current_request.referrer + << (0 == current_request.referrer.length() ? "- " : " ") + << current_request.agent + << (0 == current_request.agent.length() ? "- " : " ") + << request_string; + + RouteParameters route_parameters; + APIGrammarParser api_parser(&route_parameters); + + auto api_iterator = request_string.begin(); + const bool result = + boost::spirit::qi::parse(api_iterator, request_string.end(), api_parser); + + osrm::json::Object json_result; + // check if the was an error with the request + if (!result || (api_iterator != request_string.end())) + { + current_reply = http::reply::stock_reply(http::reply::bad_request); + current_reply.content.clear(); + const auto position = std::distance(request_string.begin(), api_iterator); + + json_result.values["status"] = 400; + std::string message = "Query string malformed close to position "; + message += cast::integral_to_string(position); + json_result.values["status_message"] = message; + osrm::json::render(current_reply.content, json_result); + return; + } + + // parsing done, lets call the right plugin to handle the request + BOOST_ASSERT_MSG(routing_machine != nullptr, "pointer not init'ed"); + + if (!route_parameters.jsonp_parameter.empty()) + { // prepend response with jsonp parameter + const std::string json_p = (route_parameters.jsonp_parameter + "("); + current_reply.content.insert(current_reply.content.end(), json_p.begin(), json_p.end()); + } + const auto return_code = routing_machine->RunQuery(route_parameters, json_result); + if (200 != return_code) + { + current_reply = http::reply::stock_reply(http::reply::bad_request); + current_reply.content.clear(); + json_result.values["status"] = 400; + std::string message = "Bad Request"; + json_result.values["status_message"] = message; + osrm::json::render(current_reply.content, json_result); + return; + } + + current_reply.headers.emplace_back("Access-Control-Allow-Origin", "*"); + current_reply.headers.emplace_back("Access-Control-Allow-Methods", "GET"); + current_reply.headers.emplace_back("Access-Control-Allow-Headers", + "X-Requested-With, Content-Type"); + + // set headers + current_reply.headers.emplace_back("Content-Length", + cast::integral_to_string(current_reply.content.size())); + if ("gpx" == route_parameters.output_format) + { // gpx file + osrm::json::gpx_render(current_reply.content, json_result.values["route"]); + current_reply.headers.emplace_back("Content-Type", + "application/gpx+xml; charset=UTF-8"); + current_reply.headers.emplace_back("Content-Disposition", + "attachment; filename=\"route.gpx\""); + } + else if (route_parameters.jsonp_parameter.empty()) + { // json file + osrm::json::render(current_reply.content, json_result); + current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8"); + current_reply.headers.emplace_back("Content-Disposition", + "inline; filename=\"response.json\""); + } + else + { // jsonp + osrm::json::render(current_reply.content, json_result); + current_reply.headers.emplace_back("Content-Type", "text/javascript; charset=UTF-8"); + current_reply.headers.emplace_back("Content-Disposition", + "inline; filename=\"response.js\""); + } + if (!route_parameters.jsonp_parameter.empty()) + { // append brace to jsonp response + current_reply.content.push_back(')'); + } + } + catch (const std::exception &e) + { + current_reply = http::reply::stock_reply(http::reply::internal_server_error); + SimpleLogger().Write(logWARNING) << "[server error] code: " << e.what() + << ", uri: " << current_request.uri; + return; + } +} + +void RequestHandler::RegisterRoutingMachine(OSRM *osrm) { routing_machine = osrm; } diff --git a/3party/osrm/osrm-backend/Server/RequestHandler.h b/3party/osrm/osrm-backend/server/request_handler.hpp old mode 100644 new mode 100755 similarity index 86% rename from 3party/osrm/osrm-backend/Server/RequestHandler.h rename to 3party/osrm/osrm-backend/server/request_handler.hpp index 7263dad4ef..b4019db7d8 --- a/3party/osrm/osrm-backend/Server/RequestHandler.h +++ b/3party/osrm/osrm-backend/server/request_handler.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef REQUEST_HANDLER_H -#define REQUEST_HANDLER_H +#ifndef REQUEST_HANDLER_HPP +#define REQUEST_HANDLER_HPP #include @@ -36,8 +36,8 @@ class OSRM; namespace http { -class Reply; -struct Request; +class reply; +struct request; } class RequestHandler @@ -49,11 +49,11 @@ class RequestHandler RequestHandler(); RequestHandler(const RequestHandler &) = delete; - void handle_request(const http::Request &req, http::Reply &rep); + void handle_request(const http::request ¤t_request, http::reply ¤t_reply); void RegisterRoutingMachine(OSRM *osrm); private: OSRM *routing_machine; }; -#endif // REQUEST_HANDLER_H +#endif // REQUEST_HANDLER_HPP diff --git a/3party/osrm/osrm-backend/server/request_parser.cpp b/3party/osrm/osrm-backend/server/request_parser.cpp new file mode 100755 index 0000000000..584dcbeeb1 --- /dev/null +++ b/3party/osrm/osrm-backend/server/request_parser.cpp @@ -0,0 +1,323 @@ +/* + +Copyright (c) 2015, 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. + +*/ + +#include "request_parser.hpp" + +#include "http/compression_type.hpp" +#include "http/header.hpp" +#include "http/request.hpp" + +#include "../data_structures/tribool.hpp" + +#include + +#include + +namespace http +{ + +RequestParser::RequestParser() + : state(internal_state::method_start), current_header({"", ""}), + selected_compression(no_compression) +{ +} + +std::tuple +RequestParser::parse(request ¤t_request, char *begin, char *end) +{ + while (begin != end) + { + osrm::tribool result = consume(current_request, *begin++); + if (result != osrm::tribool::indeterminate) + { + return std::make_tuple(result, selected_compression); + } + } + osrm::tribool result = osrm::tribool::indeterminate; + return std::make_tuple(result, selected_compression); +} + +osrm::tribool RequestParser::consume(request ¤t_request, const char input) +{ + switch (state) + { + case internal_state::method_start: + if (!is_char(input) || is_CTL(input) || is_special(input)) + { + return osrm::tribool::no; + } + state = internal_state::method; + return osrm::tribool::indeterminate; + case internal_state::method: + if (input == ' ') + { + state = internal_state::uri; + return osrm::tribool::indeterminate; + } + if (!is_char(input) || is_CTL(input) || is_special(input)) + { + return osrm::tribool::no; + } + return osrm::tribool::indeterminate; + case internal_state::uri_start: + if (is_CTL(input)) + { + return osrm::tribool::no; + } + state = internal_state::uri; + current_request.uri.push_back(input); + return osrm::tribool::indeterminate; + case internal_state::uri: + if (input == ' ') + { + state = internal_state::http_version_h; + return osrm::tribool::indeterminate; + } + if (is_CTL(input)) + { + return osrm::tribool::no; + } + current_request.uri.push_back(input); + return osrm::tribool::indeterminate; + case internal_state::http_version_h: + if (input == 'H') + { + state = internal_state::http_version_t_1; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::http_version_t_1: + if (input == 'T') + { + state = internal_state::http_version_t_2; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::http_version_t_2: + if (input == 'T') + { + state = internal_state::http_version_p; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::http_version_p: + if (input == 'P') + { + state = internal_state::http_version_slash; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::http_version_slash: + if (input == '/') + { + state = internal_state::http_version_major_start; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::http_version_major_start: + if (is_digit(input)) + { + state = internal_state::http_version_major; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::http_version_major: + if (input == '.') + { + state = internal_state::http_version_minor_start; + return osrm::tribool::indeterminate; + } + if (is_digit(input)) + { + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::http_version_minor_start: + if (is_digit(input)) + { + state = internal_state::http_version_minor; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::http_version_minor: + if (input == '\r') + { + state = internal_state::expecting_newline_1; + return osrm::tribool::indeterminate; + } + if (is_digit(input)) + { + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::expecting_newline_1: + if (input == '\n') + { + state = internal_state::header_line_start; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::header_line_start: + if (boost::iequals(current_header.name, "Accept-Encoding")) + { + /* giving gzip precedence over deflate */ + if (boost::icontains(current_header.value, "deflate")) + { + selected_compression = deflate_rfc1951; + } + if (boost::icontains(current_header.value, "gzip")) + { + selected_compression = gzip_rfc1952; + } + } + + if (boost::iequals(current_header.name, "Referer")) + { + current_request.referrer = current_header.value; + } + + if (boost::iequals(current_header.name, "User-Agent")) + { + current_request.agent = current_header.value; + } + + if (input == '\r') + { + state = internal_state::expecting_newline_3; + return osrm::tribool::indeterminate; + } + if (!is_char(input) || is_CTL(input) || is_special(input)) + { + return osrm::tribool::no; + } + state = internal_state::header_name; + current_header.clear(); + current_header.name.push_back(input); + return osrm::tribool::indeterminate; + case internal_state::header_lws: + if (input == '\r') + { + state = internal_state::expecting_newline_2; + return osrm::tribool::indeterminate; + } + if (input == ' ' || input == '\t') + { + return osrm::tribool::indeterminate; + } + if (is_CTL(input)) + { + return osrm::tribool::no; + } + state = internal_state::header_value; + return osrm::tribool::indeterminate; + case internal_state::header_name: + if (input == ':') + { + state = internal_state::space_before_header_value; + return osrm::tribool::indeterminate; + } + if (!is_char(input) || is_CTL(input) || is_special(input)) + { + return osrm::tribool::no; + } + current_header.name.push_back(input); + return osrm::tribool::indeterminate; + case internal_state::space_before_header_value: + if (input == ' ') + { + state = internal_state::header_value; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + case internal_state::header_value: + if (input == '\r') + { + state = internal_state::expecting_newline_2; + return osrm::tribool::indeterminate; + } + if (is_CTL(input)) + { + return osrm::tribool::no; + } + current_header.value.push_back(input); + return osrm::tribool::indeterminate; + case internal_state::expecting_newline_2: + if (input == '\n') + { + state = internal_state::header_line_start; + return osrm::tribool::indeterminate; + } + return osrm::tribool::no; + default: // expecting_newline_3 + return input == '\n' ? osrm::tribool::yes : osrm::tribool::no; + } +} + +bool RequestParser::is_char(const int character) const +{ + return character >= 0 && character <= 127; +} + +bool RequestParser::is_CTL(const int character) const +{ + return (character >= 0 && character <= 31) || (character == 127); +} + +bool RequestParser::is_special(const int character) const +{ + switch (character) + { + case '(': + case ')': + case '<': + case '>': + case '@': + case ',': + case ';': + case ':': + case '\\': + case '"': + case '/': + case '[': + case ']': + case '?': + case '=': + case '{': + case '}': + case ' ': + case '\t': + return true; + default: + return false; + } +} + +bool RequestParser::is_digit(const int character) const +{ + return character >= '0' && character <= '9'; +} +} diff --git a/3party/osrm/osrm-backend/Server/RequestParser.h b/3party/osrm/osrm-backend/server/request_parser.hpp old mode 100644 new mode 100755 similarity index 51% rename from 3party/osrm/osrm-backend/Server/RequestParser.h rename to 3party/osrm/osrm-backend/server/request_parser.hpp index 4b74d83b9c..2b6bf69447 --- a/3party/osrm/osrm-backend/Server/RequestParser.h +++ b/3party/osrm/osrm-backend/server/request_parser.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,66 +25,68 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef REQUEST_PARSER_H -#define REQUEST_PARSER_H +#ifndef REQUEST_PARSER_HPP +#define REQUEST_PARSER_HPP -#include "Http/CompressionType.h" -#include +#include "http/compression_type.hpp" +#include "http/header.hpp" +#include "../data_structures/tribool.hpp" -#include -#include +#include namespace http { -struct Request; +struct request; class RequestParser { public: RequestParser(); - void Reset(); - boost::tuple - Parse(Request &req, char *begin, char *end, CompressionType *compressionType); + std::tuple + parse(request ¤t_request, char *begin, char *end); private: - boost::tribool consume(Request &req, char input, CompressionType *compressionType); + osrm::tribool consume(request ¤t_request, const char input); - inline bool isChar(int c); + bool is_char(const int character) const; - inline bool isCTL(int c); + bool is_CTL(const int character) const; - inline bool isTSpecial(int c); + bool is_special(const int character) const; - inline bool isDigit(int c); + bool is_digit(const int character) const; - enum state - { method_start, - method, - uri_start, - uri, - http_version_h, - http_version_t_1, - http_version_t_2, - http_version_p, - http_version_slash, - http_version_major_start, - http_version_major, - http_version_minor_start, - http_version_minor, - expecting_newline_1, - header_line_start, - header_lws, - header_name, - space_before_header_value, - header_value, - expecting_newline_2, - expecting_newline_3 } state_; + enum class internal_state : unsigned char + { + method_start, + method, + uri_start, + uri, + http_version_h, + http_version_t_1, + http_version_t_2, + http_version_p, + http_version_slash, + http_version_major_start, + http_version_major, + http_version_minor_start, + http_version_minor, + expecting_newline_1, + header_line_start, + header_lws, + header_name, + space_before_header_value, + header_value, + expecting_newline_2, + expecting_newline_3 + } state; - Header header; + header current_header; + compression_type selected_compression; }; } // namespace http -#endif // REQUEST_PARSER_H +#endif // REQUEST_PARSER_HPP diff --git a/3party/osrm/osrm-backend/Server/Server.h b/3party/osrm/osrm-backend/server/server.hpp old mode 100644 new mode 100755 similarity index 90% rename from 3party/osrm/osrm-backend/Server/Server.h rename to 3party/osrm/osrm-backend/server/server.hpp index 8e0b101302..0ec316379e --- a/3party/osrm/osrm-backend/Server/Server.h +++ b/3party/osrm/osrm-backend/server/server.hpp @@ -1,6 +1,6 @@ /* -Copyright (c) 2013, Project OSRM, Dennis Luxen, others +Copyright (c) 2015, Project OSRM contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -25,15 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SERVER_H -#define SERVER_H +#ifndef SERVER_HPP +#define SERVER_HPP -#include "Connection.h" -#include "RequestHandler.h" +#include "connection.hpp" +#include "request_handler.hpp" -#include "../Util/cast.hpp" -#include "../Util/make_unique.hpp" -#include "../Util/simple_logger.hpp" +#include "../util/cast.hpp" +#include "../util/integer_range.hpp" +#include "../util/simple_logger.hpp" #include #include @@ -48,9 +48,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class Server { public: - // Note: returns a shared instead of a unique ptr as it is captured in a lambda somewhere else - static std::shared_ptr CreateServer(std::string &ip_address, int ip_port, unsigned requested_num_threads) + static std::shared_ptr + CreateServer(std::string &ip_address, int ip_port, unsigned requested_num_threads) { SimpleLogger().Write() << "http 1.1 compression handled by zlib version " << zlibVersion(); const unsigned hardware_threads = std::max(1u, std::thread::hardware_concurrency()); @@ -60,7 +60,7 @@ class Server explicit Server(const std::string &address, const int port, const unsigned thread_pool_size) : thread_pool_size(thread_pool_size), acceptor(io_service), - new_connection(std::make_shared(io_service, request_handler)), request_handler() + new_connection(std::make_shared(io_service, request_handler)) { const std::string port_string = cast::integral_to_string(port); @@ -116,4 +116,4 @@ class Server RequestHandler request_handler; }; -#endif // SERVER_H +#endif // SERVER_HPP diff --git a/3party/osrm/osrm-backend/taginfo.json b/3party/osrm/osrm-backend/taginfo.json old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/test/.gitignore b/3party/osrm/osrm-backend/test/.gitignore old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/test/.stxxl b/3party/osrm/osrm-backend/test/.stxxl old mode 100644 new mode 100755 diff --git a/3party/osrm/osrm-backend/third_party/libosmium/.gitignore b/3party/osrm/osrm-backend/third_party/libosmium/.gitignore new file mode 100755 index 0000000000..50139035b7 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/.gitignore @@ -0,0 +1,2 @@ +*.swp +.ycm_extra_conf.pyc diff --git a/3party/osrm/osrm-backend/third_party/libosmium/.travis.yml b/3party/osrm/osrm-backend/third_party/libosmium/.travis.yml new file mode 100755 index 0000000000..73dff72a1a --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/.travis.yml @@ -0,0 +1,51 @@ +#----------------------------------------------------------------------------- +# +# Configuration for continuous integration service at travis-ci.org +# +#----------------------------------------------------------------------------- + +language: cpp + +compiler: + - gcc + - clang + +env: + - CONFIGURATION=Dev + - CONFIGURATION=Release + +before_install: + # we need at least g++-4.8 for c++11 features + - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test + - sudo apt-get update --yes --quiet + +install: + - cd .. + # upgrade compilers + - sudo apt-get install --yes gcc-4.8 g++-4.8 + # make sure 'cpp' is the just installed current one + - sudo rm /usr/bin/cpp + - sudo ln -s /usr/bin/cpp-4.8 /usr/bin/cpp + # upgrade libosmium dependencies + - sudo apt-get install --yes make libboost-dev libboost-program-options-dev libsparsehash-dev libprotobuf-dev protobuf-compiler libgeos++-dev libproj-dev libgdal1h libgdal-dev + - git clone https://github.com/osmcode/osm-testdata.git + # OSMPBF is too old, install from git + #- sudo apt-get install --yes libosmpbf-dev + - git clone https://github.com/scrosby/OSM-binary.git + - cd OSM-binary/src + - make + - sudo make install + - cd ../.. + - cd libosmium + +before_script: + - true + +script: + - if [ "${CXX}" = 'g++' ]; then export CXX=g++-4.8; fi; + - mkdir build + - cd build + - cmake -LA -DCMAKE_BUILD_TYPE=${CONFIGURATION} .. + - make VERBOSE=1 + - ctest --output-on-failure + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/.ycm_extra_conf.py b/3party/osrm/osrm-backend/third_party/libosmium/.ycm_extra_conf.py new file mode 100755 index 0000000000..2b8730616a --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/.ycm_extra_conf.py @@ -0,0 +1,48 @@ +#----------------------------------------------------------------------------- +# +# Configuration for YouCompleteMe Vim plugin +# +# http://valloric.github.io/YouCompleteMe/ +# +#----------------------------------------------------------------------------- + +from os.path import realpath, dirname + +basedir = dirname(realpath(__file__)) + +# some default flags +# for more information install clang-3.2-doc package and +# check UsersManual.html +flags = [ +'-Werror', +'-Wall', +'-Wextra', +'-pedantic', +'-Wno-return-type', +'-Wno-unused-parameter', +'-Wno-unused-variable', + +'-std=c++11', + +# '-x' and 'c++' also required +# use 'c' for C projects +'-x', +'c++', + +# libosmium include dirs +'-I%s/include' % basedir, +'-I%s/test/include' % basedir, +'-I%s/test/data-test/include' % basedir, + +# include third party libraries +'-I/usr/include/gdal', +] + +# youcompleteme is calling this function to get flags +# You can also set database for flags. Check: JSONCompilationDatabase.html in +# clang-3.2-doc package +def FlagsForFile( filename ): + return { + 'flags': flags, + 'do_cache': True + } diff --git a/3party/osrm/osrm-backend/third_party/libosmium/CHANGELOG.md b/3party/osrm/osrm-backend/third_party/libosmium/CHANGELOG.md new file mode 100755 index 0000000000..4c345a4981 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/CHANGELOG.md @@ -0,0 +1,31 @@ + +# Change Log + +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](http://semver.org/). + +## [unreleased] - + +## [2.1.0] - 2015-03-31 + +### Added + +- When writing PBF files, sorting the PBF stringtables is now optional. +- More tests and documentation. + +### Changed + +- Some functions are now declared `noexcept`. +- XML parser fails now if the top-level element is not `osm` or `osmChange`. + +### Fixed + +- Race condition in PBF reader. +- Multipolygon collector was accessing non-existent NodeRef. +- Doxygen documentation wan't showing all classes/functions due to a bug in + Doxygen (up to version 1.8.8). This version contains a workaround to fix + this. + +[unreleased]: https://github.com/osmcode/libosmium/compare/v2.1.0...HEAD +[2.1.0]: https://github.com/osmcode/libosmium/compare/v2.0.0...v2.1.0 + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/CMakeLists.txt b/3party/osrm/osrm-backend/third_party/libosmium/CMakeLists.txt new file mode 100755 index 0000000000..5e70a9935a --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/CMakeLists.txt @@ -0,0 +1,333 @@ +#----------------------------------------------------------------------------- +# +# CMake Config +# +# Libosmium +# +#----------------------------------------------------------------------------- + +cmake_minimum_required(VERSION 2.8 FATAL_ERROR) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + + +#----------------------------------------------------------------------------- +# +# Project version +# +#----------------------------------------------------------------------------- + +set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev" + CACHE STRING + "List of available configuration types" + FORCE) + +project(libosmium) + +set(LIBOSMIUM_VERSION_MAJOR 2) +set(LIBOSMIUM_VERSION_MINOR 1) +set(LIBOSMIUM_VERSION_PATCH 0) + +set(LIBOSMIUM_VERSION + ${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}) + + +#----------------------------------------------------------------------------- +# +# Build options +# +# (Change with -DOPTION=VALUE on cmake command line.) +# +#----------------------------------------------------------------------------- + +if(CMAKE_BUILD_TYPE STREQUAL "Dev") + set(dev_build ON) +else() + set(dev_build OFF) +endif() + +option(BUILD_EXAMPLES "compile example programs" ON) +option(BUILD_TESTING "compile unit tests, please run them with ctest" ON) + +option(BUILD_HEADERS "compile every header file on its own" ${dev_build}) +option(BUILD_BENCHMARKS "compile benchmark programs" ${dev_build}) +option(BUILD_DATA_TESTS "compile data tests, please run them with ctest" ${dev_build}) + + +#----------------------------------------------------------------------------- +# +# Find external dependencies +# +#----------------------------------------------------------------------------- + +find_package(Boost 1.38) +mark_as_advanced(CLEAR BOOST_ROOT) + +if(Boost_FOUND) + include_directories(${Boost_INCLUDE_DIRS}) +else() + set(BOOST_ROOT "NOT FOUND: please choose" CACHE PATH "") + message(FATAL_ERROR "PLEASE, specify the directory where the Boost library is installed in BOOST_ROOT") +endif() + +set(OSMIUM_INCLUDE_DIR include) +find_package(Osmium COMPONENTS io gdal geos proj sparsehash) +include_directories(${OSMIUM_INCLUDE_DIRS}) + +if(MSVC) + find_path(GETOPT_INCLUDE_DIR getopt.h) + find_library(GETOPT_LIBRARY NAMES wingetopt) + if(GETOPT_INCLUDE_DIR AND GETOPT_LIBRARY) + include_directories(${GETOPT_INCLUDE_DIR}) + list(APPEND OSMIUM_LIBRARIES ${GETOPT_LIBRARY}) + else() + set(GETOPT_MISSING 1) + endif() +endif() + +include_directories(include) + + +#----------------------------------------------------------------------------- +# +# Decide which C++ version to use (Minimum/default: C++11). +# +#----------------------------------------------------------------------------- +if(NOT MSVC) + if(NOT USE_CPP_VERSION) + set(USE_CPP_VERSION c++11) + endif() + message(STATUS "Use C++ version: ${USE_CPP_VERSION}") + # following only available from cmake 2.8.12: + # add_compile_options(-std=${USE_CPP_VERSION}) + # so using this instead: + add_definitions(-std=${USE_CPP_VERSION}) +endif() + + +#----------------------------------------------------------------------------- +# +# Compiler and Linker flags +# +#----------------------------------------------------------------------------- +if(MSVC) + set(USUAL_COMPILE_OPTIONS "/Ox") +else() + set(USUAL_COMPILE_OPTIONS "-O3 -g") +endif() + +if(WIN32) + add_definitions(-DWIN32 -D_WIN32 -DMSWIN32 -DBGDWIN32 + -DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -D_WIN32_IE=0x0600) +endif() + +set(CMAKE_CXX_FLAGS_DEV "${USUAL_COMPILE_OPTIONS}" + CACHE STRING "Flags used by the compiler during developer builds." + FORCE) + +set(CMAKE_EXE_LINKER_FLAGS_DEV "" + CACHE STRING "Flags used by the linker during developer builds." + FORCE) +mark_as_advanced( + CMAKE_CXX_FLAGS_DEV + CMAKE_EXE_LINKER_FLAGS_DEV +) + +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${USUAL_COMPILE_OPTIONS}" + CACHE STRING "Flags used by the compiler during RELWITHDEBINFO builds." + FORCE) + + +#----------------------------------------------------------------------------- +# +# Build Type +# +#----------------------------------------------------------------------------- +# In 'Dev' mode: compile with very strict warnings and turn them into errors. +if(CMAKE_BUILD_TYPE STREQUAL "Dev") + if(NOT MSVC) + add_definitions(-Werror) + endif() + add_definitions(${OSMIUM_WARNING_OPTIONS}) +endif() + +# Force RelWithDebInfo build type if none was given +if(CMAKE_BUILD_TYPE) + set(build_type ${CMAKE_BUILD_TYPE}) +else() + set(build_type "RelWithDebInfo") +endif() + +set(CMAKE_BUILD_TYPE ${build_type} + CACHE STRING + "Choose the type of build, options are: ${CMAKE_CONFIGURATION_TYPES}." + FORCE) + + +#----------------------------------------------------------------------------- +# +# Unit and data tests +# +#----------------------------------------------------------------------------- +enable_testing() + +if(BUILD_TESTING OR BUILD_DATA_TESTS) + find_program(MEMORYCHECK_COMMAND valgrind) + + set(MEMORYCHECK_COMMAND_OPTIONS + "--trace-children=yes --leak-check=full --show-reachable=yes --error-exitcode=1") + + set(MEMORYCHECK_SUPPRESSIONS_FILE "${PROJECT_SOURCE_DIR}/test/valgrind.supp") +endif() + +if(BUILD_TESTING) + add_subdirectory(test) +endif() + +if(BUILD_DATA_TESTS) + add_subdirectory(test/data-tests) +endif() + + +#----------------------------------------------------------------------------- +# +# Optional "cppcheck" target that checks C++ code +# +#----------------------------------------------------------------------------- +message(STATUS "Looking for cppcheck") +find_program(CPPCHECK cppcheck) + +if(CPPCHECK) + message(STATUS "Looking for cppcheck - found") + set(CPPCHECK_OPTIONS + --enable=warning,style,performance,portability,information,missingInclude) + + # cpp doesn't find system includes for some reason, suppress that report + set(CPPCHECK_OPTIONS ${CPPCHECK_OPTIONS} --suppress=missingIncludeSystem) + + file(GLOB_RECURSE ALL_INCLUDES include/osmium/*.hpp) + file(GLOB ALL_EXAMPLES examples/*.cpp) + file(GLOB ALL_UNIT_TESTS test/t/*/test_*.cpp) + file(GLOB ALL_DATA_TESTS test/data-tests/*.cpp) + + if(Osmium_DEBUG) + message(STATUS "Checking includes : ${ALL_INCLUDES}") + message(STATUS "Checking example code : ${ALL_EXAMPLES}") + message(STATUS "Checking unit test code: ${ALL_UNIT_TESTS}") + message(STATUS "Checking data test code: ${ALL_DATA_TESTS}") + endif() + + set(CPPCHECK_FILES + ${ALL_INCLUDES} + ${ALL_EXAMPLES} + ${ALL_UNIT_TESTS} + ${ALL_DATA_TESTS}) + + add_custom_target(cppcheck + ${CPPCHECK} + --std=c++11 ${CPPCHECK_OPTIONS} + -I ${CMAKE_SOURCE_DIR}/include + ${CPPCHECK_FILES} + ) +else() + message(STATUS "Looking for cppcheck - not found") + message(STATUS " Build target 'cppcheck' will not be available.") +endif(CPPCHECK) + + +#----------------------------------------------------------------------------- +# +# Examples, benchmarks and documentation +# +#----------------------------------------------------------------------------- + +if(BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +if(BUILD_BENCHMARKS) + add_subdirectory(benchmarks) +endif() + +add_subdirectory(doc) + + +#----------------------------------------------------------------------------- +# +# Headers +# +# This will try to compile include files on their own to detect missing +# include directives and other dependency-related problems. Note that if this +# work, it is not enough to be sure it will compile in production code. +# But if it reports an error we know we are missing something. +# +#----------------------------------------------------------------------------- +if(BUILD_HEADERS) + file(GLOB_RECURSE + ALL_HPPS + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/include" + include/osmium/*.hpp) + + file(MAKE_DIRECTORY header_check) + + foreach(hpp ${ALL_HPPS}) + string(REPLACE ".hpp" "" tmp ${hpp}) + string(REPLACE "/" "__" libname ${tmp}) + + # Create a dummy .cpp file that includes the header file we want to + # check. + set(DUMMYCPP ${CMAKE_BINARY_DIR}/header_check/${libname}.cpp) + file(WRITE ${DUMMYCPP} "#include <${hpp}>\n") + + # There is no way in CMake to just compile but not link a C++ file, + # so we pretend to build a library here. + add_library(${libname} STATIC ${DUMMYCPP} include/${hpp}) + + #### this is better but only supported from cmake 3.0: + ###add_library(${libname} OBJECT ${DUMMYCPP} include/${hpp}) + + endforeach() +endif() + +install(DIRECTORY include/osmium DESTINATION include) + +# We only have a copy of this file so we can use older boost versions which +# don't have it. We probably don't want to install it. +#install(FILES include/boost_unicode_iterator.hpp DESTINATION include) + + +#----------------------------------------------------------------------------- +# +# Packaging +# +#----------------------------------------------------------------------------- + +set(CPACK_PACKAGE_VERSION_MAJOR ${LIBOSMIUM_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${LIBOSMIUM_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${LIBOSMIUM_VERSION_PATCH}) + +if(WIN32) + set(CPACK_GENERATOR ZIP) +else() + set(CPACK_GENERATOR TGZ) +endif() + +include(CPack) + + +#----------------------------------------------------------------------------- +# +# Print warnings at the end +# +#----------------------------------------------------------------------------- +if(BUILD_DATA_TESTS AND OSM_TESTDATA STREQUAL "OSM_TESTDATA-NOTFOUND") + message("\n========================== WARNING ==========================") + message("osm-testdata directory not found, data tests were disabled!\n") + message("You can get it from https://github.com/osmcode/osm-testdata") + message("Clone it into the same directory libosmium is in") + message("or set the OSM_TESTDATA cmake variable to its path.") + message("=============================================================\n") +endif() + +#----------------------------------------------------------------------------- diff --git a/3party/osrm/osrm-backend/third_party/libosmium/CONTRIBUTING.md b/3party/osrm/osrm-backend/third_party/libosmium/CONTRIBUTING.md new file mode 100755 index 0000000000..323c84744d --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/CONTRIBUTING.md @@ -0,0 +1,132 @@ + +# Notes for Developers + +Read this if you want to contribute to Libosmium. + + +## Versioning + +Osmium is currently considered in beta and doesn't use versioning yet. Proper +versions will be introduced as soon as it is somewhat stable. + + +## Namespace + +All Osmium code MUST be in the `osmium` namespace or one of its sub-namespaces. + + +## Include-Only + +Osmium is a include-only library. You can't compile the library itself. There +is no libosmium.so. + +One drawback ist that you can't have static data in classes, because there +is no place to put this data. + +All free functions must be declared `inline`. + + +## Coding Conventions + +These coding conventions have been changing over time and some code is still +different. + +* All include files have `#ifdef` guards around them, macros are the path name + in all uppercase where the slashes (`/`) have been changed to underscore (`_`). +* Class names begin with uppercase chars and use CamelCase. Smaller helper + classes are usually defined as struct and have lowercase names. +* Macros (and only macros) are all uppercase. Use macros sparingly, usually + a constexpr is better. +* Variables, attributes, and function names are lowercase with + `underscores_between_words`. +* Class attribute names start with `m_` (member). +* Template parameters are single uppercase letters or start with uppercase `T` + and use CamelCase. +* Typedefs have `names_like_this_type` which end in `_type`. +* Macros should only be used for controlling which parts of the code should be + included when compiling. +* Use `descriptive_variable_names`, exceptions are well-established conventions + like `i` for a loop variable. Iterators are usually called `it`. +* Declare variables where they are first used (C++ style), not at the beginning + of a function (old C style). +* Names from external namespaces (even `std`) are always mentioned explicitly. + Do not use `using` (except for `std::swap`). This way we can't even by + accident pollute the namespace of the code including Osmium. +* `#include` directives appear in three "blocks" after the copyright notice. + The blocks are separated by blank lines. First block contains `#include`s for + standard C/C++ includes, second block for any external libs used, third + block for osmium internal includes. Within each block `#include`s are usually + sorted by path name. All `#include`s use `<>` syntax not `""`. +* Names not to be used from outside the library should be in a namespace + called `detail` under the namespace where they would otherwise appear. If + whole include files are never meant to be included from outside they should + be in a subdirectory called `detail`. +* All files have suffix `.hpp`. +* Closing } of all classes and namespaces should have a trailing comment + with the name of the class/namespace. +* All constructors with one or more arguments should be declared "explicit" + unless there is a reason for them not to be. Document that reason. + +Keep to the indentation and other styles used in the code. Use `make indent` +in the toplevel directory to fix indentation and styling. It calls `astyle` +with the right parameters. This program is in the `astyle` Debian package. + + +## C++11 + +Osmium uses C++11 and you can use its features such as auto, lambdas, +threading, etc. There are a few features we do not use, because even modern +compilers don't support them yet. This list might change as we get more data +about which compilers support which feature and what operating system versions +or distributions have which versions of these compilers installed. + +GCC 4.6 - too old, not supported (Ubuntu 12.04 LTS) +GCC 4.7.2 - can probably not be supported (Debian wheezy/stable) +GCC 4.7.3 - works +GCC 4.8 - works +clang 3.0 - too old, not supported (Debian wheezy/stable, Ubuntu 12.04 LTS) +clang 3.2 - works + +C++11 features you should not use: +* Inherited Constructors (works only in GCC 4.8+ and clang 3.3+, not in Visual + Studio) + + +## Checking your code + +The Osmium makefiles use pretty draconian warning options for the compiler. +This is good. Code MUST never produce any warnings, even with those settings. +If absolutely necessary pragmas can be used to disable certain warnings in +specific areas of the code. + +If the static code checker `cppcheck` is installed, the CMake configuration +will add a new build target `cppcheck` that will check all `.cpp` and `.hpp` +files. Cppcheck finds some bugs that gcc/clang doesn't. But take the result +with a grain of salt, it also sometimes produces wrong warnings. + +Set `BUILD_HEADERS=ON` in the CMake config to enable compiling all include +files on their own to check whether dependencies are all okay. All include +files MUST include all other include files they depend on. + +Call `cmake/iwyu.sh` to check for proper includes and forward declarations. +This uses the clang-based `include-what-you-use` program. Note that it does +produce some false reports and crashes often. The `osmium.imp` file can be +used to define mappings for iwyu. See the IWYU tool at +. + + +## Testing + +There are a unit tests using the Catch Unit Test Framework in the `test` +directory and some data tests in `test/osm-testdata`. They are built by the +default cmake config. Run `ctest` to run them. Many more tests are needed. + + +## Documenting the code + +All namespaces, classes, functions, attributes, etc. should be documented. + +Osmium uses the Doxygen (www.doxygen.org) source code documentation system. +If it is installed, the CMake configuration will add a new build target, so +you can build it with `make doc`. + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/LICENSE.txt b/3party/osrm/osrm-backend/third_party/libosmium/LICENSE.txt new file mode 100755 index 0000000000..36b7cd93cd --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/LICENSE.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/3party/osrm/osrm-backend/third_party/libosmium/README.md b/3party/osrm/osrm-backend/third_party/libosmium/README.md new file mode 100755 index 0000000000..503440e8ed --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/README.md @@ -0,0 +1,104 @@ +# Libosmium + +http://osmcode.org/libosmium + +A fast and flexible C++ library for working with OpenStreetMap data. + +[![Build Status](https://secure.travis-ci.org/osmcode/libosmium.png)](http://travis-ci.org/osmcode/libosmium) +[![Build status](https://ci.appveyor.com/api/projects/status/mkbg6e6stdgq7c1b?svg=true)](https://ci.appveyor.com/project/Mapbox/libosmium) + +Libosmium is developed on Linux, but also works on OSX and Windows (with some +limitations). + +There are a few applications that use the Osmium library in the examples +directory. See the [osmium-contrib](http://github.com/osmcode/osmium-contrib) +repository for more example code. + +## Prerequisites + +Because Libosmium uses many C++11 features you need a modern compiler and +standard C++ library. Osmium needs at least GCC 4.8 or clang (LLVM) 3.4. +(Some parts may work with older versions.) + +Different parts of Libosmium (and the applications built on top of it) need +different libraries. You DO NOT NEED to install all of them, just install those +you need for your programs. + +For details see the +[list of dependencies](https://github.com/osmcode/libosmium/wiki/Libosmium-dependencies). + + +## Directories + +* benchmarks: Some benchmarks checking different parts of Libosmium. + +* cmake: CMake configuration scripts. + +* doc: Config for documentation. + +* examples: Osmium example applications. + +* include: C/C++ include files. All of Libosmium is in those header files + which are needed for building Osmium applications. + +* test: Tests (see below). + + +## Building + +Osmium is a header-only library, so there is nothing to build for the +library itself. + +But there are some tests and examples that can be build. Libosmium uses +cmake: + + mkdir build + cd build + cmake .. + make + +This will build the examples and tests. Call `ctest` to run the tests. + +For more see the +[Libosmium Wiki](https://github.com/osmcode/libosmium/wiki/Building-Libosmium). + + +## Testing + +See the +[Libosmium Wiki](https://github.com/osmcode/libosmium/wiki/Testing-Libosmium) +for instructions. + + +## Osmium on 32bit Machines + +Osmium works well on 64 bit machines, but on 32 bit machines there are some +problems. Be aware that not everything will work on 32 bit architectures. +This is mostly due to the 64 bit needed for node IDs. Also Osmium hasn't been +tested well on 32 bit systems. Here are some issues you might run into: + +* Google Sparsehash does not work on 32 bit machines in our use case. +* The `mmap` system call is called with a `size_t` argument, so it can't + give you more than 4GByte of memory on 32 bit systems. This might be a + problem. + +Please report any issues you have and we might be able to solve them. + + +## Switching from the old Osmium + +If you have been using the old version of Osmium at +https://github.com/joto/osmium you might want to read about the +[changes needed](https://github.com/osmcode/libosmium/wiki/Changes-from-old-versions-of-Osmium). + + +## License + +Libosmium is available under the Boost Software License. See LICENSE.txt. + + +## Authors + +Libosmium was mainly written and is maintained by Jochen Topf +(jochen@topf.org). See the git commit log for other authors. + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/appveyor.yml b/3party/osrm/osrm-backend/third_party/libosmium/appveyor.yml new file mode 100755 index 0000000000..06c8e69749 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/appveyor.yml @@ -0,0 +1,77 @@ +#----------------------------------------------------------------------------- +# +# Configuration for continuous integration service at appveyor.com +# +#----------------------------------------------------------------------------- + +environment: + matrix: + - config: Dev + - config: RelWithDebInfo + +# branches to build +branches: + # whitelist + only: + - master + +# Operating system (build VM template) +os: Visual Studio 2014 CTP4 + +# scripts that are called at very beginning, before repo cloning +init: + +# clone directory +clone_folder: c:\projects\libosmium + +platform: x64 + +install: + # show all availble env vars + - set + - echo cmake on AppVeyor + - cmake -version + - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64 + - set PATH=c:\projects\libosmium\cmake-3.1.0-win32-x86\bin;%PATH% + - set LODEPSDIR=c:\projects\libosmium\libosmium-deps + - set PROJ_LIB=%LODEPSDIR%\proj\share + - set GDAL_DATA=%LODEPSDIR%\gdal\data + #geos.dll + - set PATH=%LODEPSDIR%\geos\lib;%PATH% + #gdal.dll + - set PATH=%LODEPSDIR%\gdal\lib;%PATH% + #libexpat.dll + - set PATH=%LODEPSDIR%\expat\lib;%PATH% + #libtiff.dll + - set PATH=%LODEPSDIR%\libtiff\lib;%PATH% + #zlibwapi.dll + - set PATH=%LODEPSDIR%\zlib\lib;%PATH% + #convert backslashes in bzip2 path to forward slashes + #cmake cannot find it otherwise + - set LIBBZIP2=%LODEPSDIR%\bzip2\lib\libbz2.lib + - set LIBBZIP2=%LIBBZIP2:\=/% + - ps: Start-FileDownload https://mapnik.s3.amazonaws.com/deps/cmake-3.1.0-win32-x86.7z -FileName cm.7z + - ps: Start-FileDownload https://mapnik.s3.amazonaws.com/dist/dev/libosmium-deps-win-14.0-x64.7z -FileName lodeps.7z + - 7z x cm.7z | %windir%\system32\find "ing archive" + - 7z x lodeps.7z | %windir%\system32\find "ing archive" + - echo %LODEPSDIR% + - dir %LODEPSDIR% + - echo our own cmake + - cmake -version + - cd c:\projects + - git clone https://github.com/osmcode/osm-testdata.git + +build_script: + - cd c:\projects\libosmium + - mkdir build + - cd build + - echo %config% + - cmake .. -LA -G "Visual Studio 14 Win64" -DOsmium_DEBUG=TRUE -DCMAKE_BUILD_TYPE=%config% -DBUILD_BENCHMARKS=OFF -DBOOST_ROOT=%LODEPSDIR%\boost -DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_57.lib -DOSMPBF_LIBRARY=%LODEPSDIR%\osmpbf\lib\osmpbf.lib -DOSMPBF_INCLUDE_DIR=%LODEPSDIR%\osmpbf\include -DPROTOBUF_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf.lib -DPROTOBUF_LITE_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf-lite.lib -DPROTOBUF_INCLUDE_DIR=%LODEPSDIR%\protobuf\include -DZLIB_LIBRARY=%LODEPSDIR%\zlib\lib\zlibwapi.lib -DZLIB_INCLUDE_DIR=%LODEPSDIR%\zlib\include -DEXPAT_LIBRARY=%LODEPSDIR%\expat\lib\libexpat.lib -DEXPAT_INCLUDE_DIR=%LODEPSDIR%\expat\include -DBZIP2_LIBRARIES=%LIBBZIP2% -DBZIP2_INCLUDE_DIR=%LODEPSDIR%\bzip2\include -DGDAL_LIBRARY=%LODEPSDIR%\gdal\lib\gdal_i.lib -DGDAL_INCLUDE_DIR=%LODEPSDIR%\gdal\include -DGEOS_LIBRARY=%LODEPSDIR%\geos\lib\geos.lib -DGEOS_INCLUDE_DIR=%LODEPSDIR%\geos\include -DPROJ_LIBRARY=%LODEPSDIR%\proj\lib\proj.lib -DPROJ_INCLUDE_DIR=%LODEPSDIR%\proj\include -DSPARSEHASH_INCLUDE_DIR=%LODEPSDIR%\sparsehash\include -DGETOPT_LIBRARY=%LODEPSDIR%\wingetopt\lib\wingetopt.lib -DGETOPT_INCLUDE_DIR=%LODEPSDIR%\wingetopt\include + - msbuild libosmium.sln /p:Configuration=%config% /toolsversion:14.0 /p:Platform=x64 /p:PlatformToolset=v140 + #- cmake .. -LA -G "NMake Makefiles" -DOsmium_DEBUG=TRUE -DCMAKE_BUILD_TYPE=%config% -DBOOST_ROOT=%LODEPSDIR%\boost -DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_57.lib -DOSMPBF_LIBRARY=%LODEPSDIR%\osmpbf\lib\osmpbf.lib -DOSMPBF_INCLUDE_DIR=%LODEPSDIR%\osmpbf\include -DPROTOBUF_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf.lib -DPROTOBUF_LITE_LIBRARY=%LODEPSDIR%\protobuf\lib\libprotobuf-lite.lib -DPROTOBUF_INCLUDE_DIR=%LODEPSDIR%\protobuf\include -DZLIB_LIBRARY=%LODEPSDIR%\zlib\lib\zlibwapi.lib -DZLIB_INCLUDE_DIR=%LODEPSDIR%\zlib\include -DEXPAT_LIBRARY=%LODEPSDIR%\expat\lib\libexpat.lib -DEXPAT_INCLUDE_DIR=%LODEPSDIR%\expat\include -DBZIP2_LIBRARIES=%LIBBZIP2% -DBZIP2_INCLUDE_DIR=%LODEPSDIR%\bzip2\include -DGDAL_LIBRARY=%LODEPSDIR%\gdal\lib\gdal_i.lib -DGDAL_INCLUDE_DIR=%LODEPSDIR%\gdal\include -DGEOS_LIBRARY=%LODEPSDIR%\geos\lib\geos.lib -DGEOS_INCLUDE_DIR=%LODEPSDIR%\geos\include -DPROJ_LIBRARY=%LODEPSDIR%\proj\lib\proj.lib -DPROJ_INCLUDE_DIR=%LODEPSDIR%\proj\include -DSPARSEHASH_INCLUDE_DIR=%LODEPSDIR%\sparsehash\include -DGETOPT_LIBRARY=%LODEPSDIR%\wingetopt\lib\wingetopt.lib -DGETOPT_INCLUDE_DIR=%LODEPSDIR%\wingetopt\include + #- nmake + +test_script: + # -LE fails_on_windows exempts tests we know will fail + - ctest --output-on-failure -C %config% -LE fails_on_windows + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/CMakeLists.txt b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/CMakeLists.txt new file mode 100755 index 0000000000..6a4ca162db --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/CMakeLists.txt @@ -0,0 +1,48 @@ +#----------------------------------------------------------------------------- +# +# CMake Config +# +# Libosmium benchmarks +# +#----------------------------------------------------------------------------- + +message(STATUS "Configuring benchmarks") + +set(BENCHMARKS + count + count_tag + index_map + static_vs_dynamic_index + CACHE STRING "Benchmark programs" +) + + +#----------------------------------------------------------------------------- +# +# Configure benchmarks +# +#----------------------------------------------------------------------------- + +message(STATUS "Configuring benchmarks - Building these benchmarks:") +foreach(benchmark ${BENCHMARKS}) + message(STATUS " - osmium_benchmark_${benchmark}") + add_executable(osmium_benchmark_${benchmark} + "osmium_benchmark_${benchmark}.cpp") + target_link_libraries(osmium_benchmark_${benchmark} + ${OSMIUM_IO_LIBRARIES} + ${BENCHMARK_LIBS_${benchmark}}) + configure_file(run_benchmark_${benchmark}.sh + ${CMAKE_CURRENT_BINARY_DIR}/run_benchmark_${benchmark}.sh + @ONLY) +endforeach() + +foreach(file setup run_benchmarks) + configure_file(${file}.sh ${CMAKE_CURRENT_BINARY_DIR}/${file}.sh @ONLY) +endforeach() + + +#----------------------------------------------------------------------------- +message(STATUS "Configuring benchmarks - done") + + +#----------------------------------------------------------------------------- diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/README.md b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/README.md new file mode 100755 index 0000000000..f10045ca0a --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/README.md @@ -0,0 +1,41 @@ + +# Benchmarks + +Benchmarks check the performance of different parts of Libosmium. + +## Preparations + +To run the benchmarks first make a directory for the data files somewhere +(outside the repository) and set the `DATA_DIR` environment variable: + + export DATA_DIR=benchmark_data + mkdir $DATA_DIR + +Then copy the OSM files you want to do the benchmarks with into this directory. +You can use the `download_data.sh` script to download a selection of OSM files +in different sizes, but you can use a different selection, too. The benchmarks +will use whatever files you have in the `DATA_DIR` directory. + +The download script will start the data files names with a number in order of +the size of the file from smallest to largest. You can use the same convention +or use a different one. Benchmarks will be run on the files in alphabetical +order. + +The files don't have to be in that directory, you can add soft links from that +directory to the real file locations if that suits you. + +## Compiling the benchmarks + +To build the benchmarks set the `BUILD_BENCHMARKS` option when configuring with +CMake and run the compilation by calling `make` (or whatever build tool you +are using). + +## Running the benchmarks + +Go to the build directory and run `benchmarks/run_benchmarks.sh`. You can also +run each benchmark on its own by calling the respective script in the +`benchmarks` directory. + +Results of the benchmarks will be printed to stdout, you might want to redirect +them into a file. + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/download_data.sh b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/download_data.sh new file mode 100755 index 0000000000..8a6a8ff50d --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/download_data.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# +# download_data.sh +# + +cd $DATA_DIR +curl --location --output 1_liechtenstein.osm.pbf http://download.geofabrik.de/europe/liechtenstein-latest.osm.pbf # about 1 MB +curl --location --output 2_bremen.osm.pbf http://download.geofabrik.de/europe/germany/bremen-latest.osm.pbf # about 13 MB +curl --location --output 3_sachsen.osm.pbf http://download.geofabrik.de/europe/germany/sachsen-latest.osm.pbf # about 120 MB +curl --location --output 4_germany.osm.pbf http://download.geofabrik.de/europe/germany-latest.osm.pbf # about 2 GB +curl --location --output 5_planet.osm.pbf http://planet.osm.org/pbf/planet-latest.osm.pbf # about 26 GB + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_count.cpp b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_count.cpp new file mode 100755 index 0000000000..701d6faec8 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_count.cpp @@ -0,0 +1,54 @@ +/* + + The code in this file is released into the Public Domain. + +*/ + +#include + +#include +#include +#include + +struct CountHandler : public osmium::handler::Handler { + + int nodes = 0; + int ways = 0; + int relations = 0; + + void node(osmium::Node&) { + ++nodes; + } + + void way(osmium::Way&) { + ++ways; + } + + void relation(osmium::Relation&) { + ++relations; + } + +}; + + +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; + exit(1); + } + + std::string input_filename = argv[1]; + + osmium::io::Reader reader(input_filename); + + CountHandler handler; + osmium::apply(reader, handler); + reader.close(); + + std::cout << "Nodes: " << handler.nodes << "\n"; + std::cout << "Ways: " << handler.ways << "\n"; + std::cout << "Relations: " << handler.relations << "\n"; + + google::protobuf::ShutdownProtobufLibrary(); +} + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_count_tag.cpp b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_count_tag.cpp new file mode 100755 index 0000000000..4a77c34529 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_count_tag.cpp @@ -0,0 +1,55 @@ +/* + + The code in this file is released into the Public Domain. + +*/ + +#include + +#include +#include +#include + +struct CountHandler : public osmium::handler::Handler { + + int counter = 0; + int all = 0; + + void node(osmium::Node& node) { + ++all; + const char* amenity = node.tags().get_value_by_key("amenity"); + if (amenity && !strcmp(amenity, "post_box")) { + ++counter; + } + } + + void way(osmium::Way&) { + ++all; + } + + void relation(osmium::Relation&) { + ++all; + } + +}; + + +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; + exit(1); + } + + std::string input_filename = argv[1]; + + osmium::io::Reader reader(input_filename); + + CountHandler handler; + osmium::apply(reader, handler); + reader.close(); + + std::cout << "r_all=" << handler.all << " r_counter=" << handler.counter << "\n"; + + google::protobuf::ShutdownProtobufLibrary(); +} + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_index_map.cpp b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_index_map.cpp new file mode 100755 index 0000000000..fa75fb2b86 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_index_map.cpp @@ -0,0 +1,41 @@ +/* + + The code in this file is released into the Public Domain. + +*/ + +#include + +#include +#include +#include + +#include +#include + +typedef osmium::index::map::Map index_type; + +typedef osmium::handler::NodeLocationsForWays location_handler_type; + +int main(int argc, char* argv[]) { + if (argc != 3) { + std::cerr << "Usage: " << argv[0] << " OSMFILE FORMAT\n"; + exit(1); + } + + std::string input_filename = argv[1]; + std::string location_store = argv[2]; + + osmium::io::Reader reader(input_filename); + + const auto& map_factory = osmium::index::MapFactory::instance(); + std::unique_ptr index = map_factory.create_map(location_store); + location_handler_type location_handler(*index); + location_handler.ignore_errors(); + + osmium::apply(reader, location_handler); + reader.close(); + + google::protobuf::ShutdownProtobufLibrary(); +} + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp new file mode 100755 index 0000000000..9c47c84499 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp @@ -0,0 +1,136 @@ +/* + + This benchmarks compares the run time for statically vs. dynamically + configured index maps. You can configure index maps at compile-time using + typedefs or at run-time using polymorphism. + + This will read the input file into a buffer and then run the + NodeLocationForWays handler multiple times over the complete data. The + number of runs depends on the size of the input, but is never smaller + than 10. + + Do not run this with very large input files! It will need about 10 times + as much RAM as the file size of the input file. + + The code in this file is released into the Public Domain. + +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +typedef osmium::index::map::SparseMemArray static_index_type; +const std::string location_store="sparse_mem_array"; + +typedef osmium::index::map::Map dynamic_index_type; + +typedef osmium::handler::NodeLocationsForWays static_location_handler_type; +typedef osmium::handler::NodeLocationsForWays dynamic_location_handler_type; + +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; + exit(1); + } + + std::string input_filename = argv[1]; + + osmium::memory::Buffer buffer = osmium::io::read_file(input_filename); + google::protobuf::ShutdownProtobufLibrary(); + + const auto& map_factory = osmium::index::MapFactory::instance(); + + const auto buffer_size = buffer.committed() / (1024*1024); // buffer size in MBytes + const int runs = std::max(10, static_cast(5000ull / buffer_size)); + + std::cout << "input: filename=" << input_filename << " buffer_size=" << buffer_size << "MBytes\n"; + std::cout << "runs: " << runs << "\n"; + + double static_min = std::numeric_limits::max(); + double static_sum = 0; + double static_max = 0; + + double dynamic_min = std::numeric_limits::max(); + double dynamic_sum = 0; + double dynamic_max = 0; + + for (int i = 0; i < runs; ++i) { + + { + // static index + osmium::memory::Buffer tmp_buffer(buffer.committed()); + for (const auto& item : buffer) { + tmp_buffer.add_item(item); + tmp_buffer.commit(); + } + + static_index_type static_index; + static_location_handler_type static_location_handler(static_index); + + auto start = std::chrono::steady_clock::now(); + osmium::apply(tmp_buffer, static_location_handler); + auto end = std::chrono::steady_clock::now(); + + double duration = std::chrono::duration(end-start).count(); + + if (duration < static_min) static_min = duration; + if (duration > static_max) static_max = duration; + static_sum += duration; + } + + { + // dynamic index + osmium::memory::Buffer tmp_buffer(buffer.committed()); + for (const auto& item : buffer) { + tmp_buffer.add_item(item); + tmp_buffer.commit(); + } + + std::unique_ptr index = map_factory.create_map(location_store); + dynamic_location_handler_type dynamic_location_handler(*index); + dynamic_location_handler.ignore_errors(); + + auto start = std::chrono::steady_clock::now(); + osmium::apply(tmp_buffer, dynamic_location_handler); + auto end = std::chrono::steady_clock::now(); + + double duration = std::chrono::duration(end-start).count(); + + if (duration < dynamic_min) dynamic_min = duration; + if (duration > dynamic_max) dynamic_max = duration; + dynamic_sum += duration; + } + } + + double static_avg = static_sum/runs; + double dynamic_avg = dynamic_sum/runs; + + std::cout << "static min=" << static_min << "ms avg=" << static_avg << "ms max=" << static_max << "ms\n"; + std::cout << "dynamic min=" << dynamic_min << "ms avg=" << dynamic_avg << "ms max=" << dynamic_max << "ms\n"; + + double rfactor = 100.0; + double diff_min = std::round((dynamic_min - static_min) * rfactor) / rfactor; + double diff_avg = std::round((dynamic_avg - static_avg) * rfactor) / rfactor; + double diff_max = std::round((dynamic_max - static_max) * rfactor) / rfactor; + + double prfactor = 10.0; + double percent_min = std::round((100.0 * diff_min / static_min) * prfactor) / prfactor; + double percent_avg = std::round((100.0 * diff_avg / static_avg) * prfactor) / prfactor; + double percent_max = std::round((100.0 * diff_max / static_max) * prfactor) / prfactor; + + std::cout << "difference:"; + std::cout << " min=" << diff_min << "ms (" << percent_min << "%)"; + std::cout << " avg=" << diff_avg << "ms (" << percent_avg << "%)"; + std::cout << " max=" << diff_max << "ms (" << percent_max << "%)\n"; +} + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_count.sh b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_count.sh new file mode 100755 index 0000000000..d71508f764 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_count.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# +# run_benchmark_count.sh +# + +set -e + +BENCHMARK_NAME=count + +. @CMAKE_BINARY_DIR@/benchmarks/setup.sh + +CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME + +echo "# file size num mem time cpu_kernel cpu_user cpu_percent cmd options" +for data in $OB_DATA_FILES; do + filename=`basename $data` + filesize=`stat --format="%s" --dereference $data` + for n in $OB_SEQ; do + $OB_TIME_CMD -f "$filename $filesize $n $OB_TIME_FORMAT" $CMD $data 2>&1 >/dev/null | sed -e "s%$DATA_DIR/%%" | sed -e "s%$OB_DIR/%%" + done +done + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_count_tag.sh b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_count_tag.sh new file mode 100755 index 0000000000..4fa6a1068f --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_count_tag.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# +# run_benchmark_count_tag.sh +# + +set -e + +BENCHMARK_NAME=count_tag + +. @CMAKE_BINARY_DIR@/benchmarks/setup.sh + +CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME + +echo "# file size num mem time cpu_kernel cpu_user cpu_percent cmd options" +for data in $OB_DATA_FILES; do + filename=`basename $data` + filesize=`stat --format="%s" --dereference $data` + for n in $OB_SEQ; do + $OB_TIME_CMD -f "$filename $filesize $n $OB_TIME_FORMAT" $CMD $data 2>&1 >/dev/null | sed -e "s%$DATA_DIR/%%" | sed -e "s%$OB_DIR/%%" + done +done + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_index_map.sh b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_index_map.sh new file mode 100755 index 0000000000..30984d4603 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_index_map.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# run_benchmark_index_map.sh +# + +set -e + +BENCHMARK_NAME=index_map + +. @CMAKE_BINARY_DIR@/benchmarks/setup.sh + +CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME + +#MAPS="sparse_mem_map sparse_mem_table sparse_mem_array sparse_mmap_array sparse_file_array dense_mem_array dense_mmap_array dense_file_array" +MAPS="sparse_mem_map sparse_mem_table sparse_mem_array sparse_mmap_array sparse_file_array" + +echo "# file size num mem time cpu_kernel cpu_user cpu_percent cmd options" +for data in $OB_DATA_FILES; do + filename=`basename $data` + filesize=`stat --format="%s" --dereference $data` + for map in $MAPS; do + for n in $OB_SEQ; do + $OB_TIME_CMD -f "$filename $filesize $n $OB_TIME_FORMAT" $CMD $data $map 2>&1 >/dev/null | sed -e "s%$DATA_DIR/%%" | sed -e "s%$OB_DIR/%%" + done + done +done + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_static_vs_dynamic_index.sh b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_static_vs_dynamic_index.sh new file mode 100755 index 0000000000..05e32f1260 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmark_static_vs_dynamic_index.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# +# run_benchmark_static_vs_dynamic_index.sh +# + +set -e + +BENCHMARK_NAME=static_vs_dynamic_index + +. @CMAKE_BINARY_DIR@/benchmarks/setup.sh + +CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME + +for data in $OB_DATA_FILES; do + filesize=`stat --format="%s" --dereference $data` + if [ $filesize -lt 500000000 ]; then + echo "========================" + $CMD $data + fi +done + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmarks.sh b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmarks.sh new file mode 100755 index 0000000000..6a20c02141 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/run_benchmarks.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# +# run_benchmarks.sh +# +# Run all benchmarks. +# + +set -e + +for benchmark in @CMAKE_BINARY_DIR@/benchmarks/run_benchmark_*.sh; do + name=`basename $benchmark` + echo "Running $name..." + $benchmark +done + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/setup.sh b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/setup.sh new file mode 100755 index 0000000000..9733bfe1bd --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/benchmarks/setup.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# +# setup.sh +# + +if [ -z $DATA_DIR ]; then + echo "Please set DATA_DIR environment variable before running benchmark" + exit 1 +fi + +OB_DIR=@CMAKE_BINARY_DIR@/benchmarks + +OB_RUNS=3 +OB_SEQ=`seq -s' ' 1 $OB_RUNS` + +OB_TIME_CMD=/usr/bin/time +OB_TIME_FORMAT="%M %e %S %U %P %C" + +OB_DATA_FILES=`find -L $DATA_DIR -mindepth 1 -maxdepth 1 -type f | sort` + +echo "BENCHMARK: $BENCHMARK_NAME" +echo "---------------------" +echo "CPU:" +grep '^model name' /proc/cpuinfo | tail -1 +grep '^cpu MHz' /proc/cpuinfo | tail -1 +grep '^cpu cores' /proc/cpuinfo | tail -1 +grep '^siblings' /proc/cpuinfo | tail -1 + +echo "---------------------" +echo "MEMORY:" +free +echo "---------------------" +echo "RESULTS:" + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/cmake/FindGem.cmake b/3party/osrm/osrm-backend/third_party/libosmium/cmake/FindGem.cmake new file mode 100755 index 0000000000..f5389d1e83 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/cmake/FindGem.cmake @@ -0,0 +1,153 @@ +# Author thomas.roehr@dfki.de +# +# Version 0.3 2013-07-02 +# - rely on `gem content` to find library and header +# - introduce GEM_OS_PKG to allow search via pkgconfig +# Version 0.2 2010-01-14 +# - add support for searching for multiple gems +# Version 0.1 2010-12-15 +# - support basic search functionality +# - tested to find rice +# +# OUTPUT: +# +# GEM_INCLUDE_DIRS After successful search contains the include directores +# +# GEM_LIBRARIES After successful search contains the full path of each found library +# +# +# Usage: +# set(GEM_DEBUG TRUE) +# find_package(Gem COMPONENTS rice hoe) +# include_directories(${GEM_INCLUDE_DIRS}) +# target_link_libraries(${GEM_LIBRARIES} +# +# in case pkg-config should be used to search for the os pkg, set GEM_OS_PKG, i.e. +# set(GEM_OS_PKG TRUE) +# +# Check for how 'gem' should be called +include(FindPackageHandleStandardArgs) +find_program(GEM_EXECUTABLE + NAMES "gem${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}" + "gem${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}" + "gem-${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}" + "gem-${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}" + "gem${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}" + "gem${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}" + "gem-${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}" + "gem-${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}" + "gem") + +# Making backward compatible +if(Gem_DEBUG) + set(GEM_DEBUG TRUE) +endif() + +if(NOT GEM_EXECUTABLE) + MESSAGE(FATAL_ERROR "Could not find the gem executable - install 'gem' first") +endif() + +if(NOT Gem_FIND_COMPONENTS) + MESSAGE(FATAL_ERROR "If searching for a Gem you have to provide COMPONENTS with the name of the gem") +endif() + +foreach(Gem_NAME ${Gem_FIND_COMPONENTS}) + set(GEM_${Gem_NAME}_FOUND TRUE) + list(APPEND components_found_vars GEM_${Gem_NAME}_FOUND) + # If the gem is installed as a gem + if(NOT GEM_OS_PKG) + set(GEM_HOME ENV{GEM_HOME}) + + # Use `gem content ` to extract current information about installed gems + # Store the information into ${GEM_LOCAL_INFO} + EXECUTE_PROCESS(COMMAND ${GEM_EXECUTABLE} content ${Gem_NAME} + RESULT_VARIABLE GEM_RUN_RESULT + OUTPUT_VARIABLE GEM_LOCAL_INFO) + + if(GEM_RUN_RESULT STREQUAL "0") + list(APPEND FOUND_GEMS ${Gem_NAME}) + set(_library_NAME_PATTERN lib${Gem_NAME}.a + lib${Gem_NAME}.so + lib${Gem_NAME}.dylib + ${Gem_NAME}.a + ${Gem_NAME}.so + ${Gem_NAME}.dylib + .*.a + .*.so + .*.dylib + ) + + set(_header_SUFFIX_PATTERN + .h + .hh + .hpp + ) + + # Create a list from the output results of the gem command + string(REPLACE "\n" ";" GEM_CONTENT_LIST "${GEM_LOCAL_INFO}") + foreach(_gem_CONTENT_PATH ${GEM_CONTENT_LIST}) + + # Convert so that only '/' Unix path separator are being using + # needed to do proper regex matching + FILE(TO_CMAKE_PATH ${_gem_CONTENT_PATH} gem_CONTENT_PATH) + + # Identify library -- checking for a library in the gems 'lib' (sub)directory + # Search for an existing library, but only within the gems folder + foreach(_library_NAME ${_library_NAME_PATTERN}) + STRING(REGEX MATCH ".*${Gem_NAME}.*/lib/.*${_library_NAME}$" GEM_PATH_INFO "${gem_CONTENT_PATH}") + if(NOT "${GEM_PATH_INFO}" STREQUAL "") + list(APPEND GEM_LIBRARIES ${GEM_PATH_INFO}) + break() + endif() + endforeach() + + # Identify headers + # Checking for available headers in an include directory + foreach(_header_PATTERN ${_header_SUFFIX_PATTERN}) + STRING(REGEX MATCH ".*${Gem_NAME}.*/include/.*${_header_PATTERN}$" GEM_PATH_INFO "${gem_CONTENT_PATH}") + if(NOT "${GEM_PATH_INFO}" STREQUAL "") + STRING(REGEX REPLACE "(.*${Gem_NAME}.*/include/).*${_header_PATTERN}$" "\\1" GEM_PATH_INFO "${gem_CONTENT_PATH}") + list(APPEND GEM_INCLUDE_DIRS ${GEM_PATH_INFO}) + break() + endif() + endforeach() + endforeach() + else() + set(GEM_${Gem_NAME}_FOUND FALSE) + endif() + else(NOT GEM_OS_PKG) + pkg_check_modules(GEM_PKG ${Gem_NAME}) + set(GEM_${GEM_NAME}_FOUND GEM_PKG_FOUND) + set(GEM_INCLUDE_DIRS ${GEM_PKG_INCLUDE_DIRS}) + set(GEM_LIBRARIES ${GEM_PKG_LIBRARIES} ${GEM_PKG_STATIC_LIBRARIES}) + list(APPEND GEM_LIBRARIES ${GEM_PKG_LDFLAGS} ${GEM_PKG_STATIC_LDFLAGS}) + list(APPEND GEM_LIBRARIES ${GEM_PKG_LDFLAGS_OTHER} ${GEM_PKG_STATIC_LDFLAGS_OTHER}) + + if(GEM_DEBUG) + message(STATUS "GEM_OS_PKG is defined") + message(STATUS "GEM_INCLUDE_DIRS ${GEM_INCLUDE_DIRS}") + message(STATUS "GEM_STATIC_LIBRARY_DIRS ${GEM_PKG_STATIC_LIBRARY_DIRS}") + message(STATUS "GEM_LIBRARY_DIRS ${GEM_PKG_STATIC_LIBRARY_DIRS}") + message(STATUS "GEM_STATIC_LIBRARIES ${GEM_PKG_STATIC_LIBRARIES}") + message(STATUS "GEM_LIBRARIES ${GEM_LIBRARIES}") + endif() + endif() + + if(GEM_DEBUG) + message(STATUS "${Gem_NAME} library dir: ${GEM_LIBRARIES}") + message(STATUS "${Gem_NAME} include dir: ${GEM_INCLUDE_DIRS}") + endif() +endforeach() + +# Compact the lists +if(DEFINED GEM_LIBRARIES) + LIST(REMOVE_DUPLICATES GEM_LIBRARIES) +endif() +if(DEFINED GEM_INCLUDE_DIRS) + LIST(REMOVE_DUPLICATES GEM_INCLUDE_DIRS) +endif() + +find_package_handle_standard_args(GEM + REQUIRED_VARS ${components_found_vars} + FAIL_MESSAGE "Could not find all required gems") + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/cmake/FindOSMPBF.cmake b/3party/osrm/osrm-backend/third_party/libosmium/cmake/FindOSMPBF.cmake new file mode 100755 index 0000000000..deeebd8b6c --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/cmake/FindOSMPBF.cmake @@ -0,0 +1,50 @@ +# +# Locate OSMPBF library +# +# This module defines +# OSMPBF_FOUND - if false, do not try to link to OSMPBF +# OSMPBF_LIBRARIES - full library path name +# OSMPBF_INCLUDE_DIRS - where to find OSMPBF.hpp +# +# Note that the expected include convention is +# #include +# and not +# #include +# + +find_path(OSMPBF_INCLUDE_DIR osmpbf/osmpbf.h + HINTS $ENV{OSMPBF_DIR} + PATH_SUFFIXES include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /opt/local # DarwinPorts + /opt +) + +find_library(OSMPBF_LIBRARY + NAMES osmpbf + HINTS $ENV{OSMPBF_DIR} + PATH_SUFFIXES lib64 lib + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /opt/local + /opt +) + +# Handle the QUIETLY and REQUIRED arguments and set OSMPBF_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OSMPBF DEFAULT_MSG OSMPBF_LIBRARY OSMPBF_INCLUDE_DIR) + +# Copy the results to the output variables. +if(OSMPBF_FOUND) + set(OSMPBF_INCLUDE_DIRS ${OSMPBF_INCLUDE_DIR}) + set(OSMPBF_LIBRARIES ${OSMPBF_LIBRARY}) +endif() + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/cmake/FindOsmium.cmake b/3party/osrm/osrm-backend/third_party/libosmium/cmake/FindOsmium.cmake new file mode 100755 index 0000000000..1de41a0226 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/cmake/FindOsmium.cmake @@ -0,0 +1,340 @@ +#---------------------------------------------------------------------- +# +# FindOsmium.cmake +# +# Find the Libosmium headers and, optionally, several components needed for +# different Libosmium functions. +# +#---------------------------------------------------------------------- +# +# Usage: +# +# Copy this file somewhere into your project directory, where cmake can +# find it. Usually this will be a directory called "cmake" which you can +# add to the CMake module search path with the following line in your +# CMakeLists.txt: +# +# list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +# +# Then add the following in your CMakeLists.txt: +# +# find_package(Osmium REQUIRED COMPONENTS ) +# include_directories(${OSMIUM_INCLUDE_DIRS}) +# +# For the substitute a space separated list of one or more of the +# following components: +# +# pbf - include libraries needed for PBF input and output +# xml - include libraries needed for XML input and output +# io - include libraries needed for any type of input/output +# geos - include if you want to use any of the GEOS functions +# gdal - include if you want to use any of the OGR functions +# proj - include if you want to use any of the Proj.4 functions +# sparsehash - include if you use the sparsehash index +# +# You can check for success with something like this: +# +# if(NOT OSMIUM_FOUND) +# message(WARNING "Libosmium not found!\n") +# endif() +# +#---------------------------------------------------------------------- +# +# Variables: +# +# OSMIUM_FOUND - True if Osmium found. +# OSMIUM_INCLUDE_DIRS - Where to find include files. +# OSMIUM_XML_LIBRARIES - Libraries needed for XML I/O. +# OSMIUM_PBF_LIBRARIES - Libraries needed for PBF I/O. +# OSMIUM_IO_LIBRARIES - Libraries needed for XML or PBF I/O. +# OSMIUM_LIBRARIES - All libraries Osmium uses somewhere. +# +#---------------------------------------------------------------------- + +# Look for the header file. +find_path(OSMIUM_INCLUDE_DIR osmium/osm.hpp + PATH_SUFFIXES include + PATHS + ../libosmium + ../../libosmium + libosmium + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr/ + /opt/local # DarwinPorts + /opt +) + +# Handle the QUIETLY and REQUIRED arguments and set OSMIUM_FOUND to TRUE if +# all listed variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OSMIUM REQUIRED_VARS OSMIUM_INCLUDE_DIR) + +# Copy the results to the output variables. +if(OSMIUM_FOUND) + set(OSMIUM_INCLUDE_DIRS ${OSMIUM_INCLUDE_DIR}) +else() + set(OSMIUM_INCLUDE_DIRS "") +endif() + +if(Osmium_FIND_REQUIRED AND NOT OSMIUM_FOUND) + message(FATAL_ERROR "Can not find libosmium headers, please install them or configure the paths") +endif() + +#---------------------------------------------------------------------- +# +# Check for optional components +# +#---------------------------------------------------------------------- +if(Osmium_FIND_COMPONENTS) + foreach(_component ${Osmium_FIND_COMPONENTS}) + string(TOUPPER ${_component} _component_uppercase) + set(Osmium_USE_${_component_uppercase} TRUE) + endforeach() +endif() + +#---------------------------------------------------------------------- +# Component 'io' is an alias for 'pbf' and 'xml' +if(Osmium_USE_IO) + set(Osmium_USE_PBF TRUE) + set(Osmium_USE_XML TRUE) +endif() + +#---------------------------------------------------------------------- +# Component 'ogr' is an alias for 'gdal' +if(Osmium_USE_OGR) + set(Osmium_USE_GDAL TRUE) +endif() + +#---------------------------------------------------------------------- +# Component 'pbf' +if(Osmium_USE_PBF) + find_package(OSMPBF) + find_package(Protobuf) + find_package(ZLIB) + find_package(Threads) + + if(OSMPBF_FOUND AND PROTOBUF_FOUND AND ZLIB_FOUND AND Threads_FOUND) + list(APPEND OSMIUM_PBF_LIBRARIES + ${OSMPBF_LIBRARIES} + ${PROTOBUF_LITE_LIBRARY} + ${ZLIB_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + ) + if(WIN32) + list(APPEND OSMIUM_PBF_LIBRARIES ws2_32) + endif() + list(APPEND OSMIUM_INCLUDE_DIRS + ${OSMPBF_INCLUDE_DIRS} + ${PROTOBUF_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIR} + ) + else() + set(_missing_libraries 1) + message(WARNING "Osmium: Can not find some libraries for PBF input/output, please install them or configure the paths.") + endif() +endif() + +#---------------------------------------------------------------------- +# Component 'xml' +if(Osmium_USE_XML) + find_package(EXPAT) + find_package(BZip2) + find_package(ZLIB) + find_package(Threads) + + if(EXPAT_FOUND AND BZIP2_FOUND AND ZLIB_FOUND AND Threads_FOUND) + list(APPEND OSMIUM_XML_LIBRARIES + ${EXPAT_LIBRARIES} + ${BZIP2_LIBRARIES} + ${ZLIB_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + ) + list(APPEND OSMIUM_INCLUDE_DIRS + ${EXPAT_INCLUDE_DIR} + ${BZIP2_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIR} + ) + else() + set(_missing_libraries 1) + message(WARNING "Osmium: Can not find some libraries for XML input/output, please install them or configure the paths.") + endif() +endif() + +#---------------------------------------------------------------------- +list(APPEND OSMIUM_IO_LIBRARIES + ${OSMIUM_PBF_LIBRARIES} + ${OSMIUM_XML_LIBRARIES} +) + +list(APPEND OSMIUM_LIBRARIES + ${OSMIUM_IO_LIBRARIES} +) + +#---------------------------------------------------------------------- +# Component 'geos' +if(Osmium_USE_GEOS) + find_path(GEOS_INCLUDE_DIR geos/geom.h) + find_library(GEOS_LIBRARY NAMES geos) + + if(GEOS_INCLUDE_DIR AND GEOS_LIBRARY) + SET(GEOS_FOUND 1) + list(APPEND OSMIUM_LIBRARIES ${GEOS_LIBRARY}) + list(APPEND OSMIUM_INCLUDE_DIRS ${GEOS_INCLUDE_DIR}) + else() + set(_missing_libraries 1) + message(WARNING "Osmium: GEOS library is required but not found, please install it or configure the paths.") + endif() +endif() + +#---------------------------------------------------------------------- +# Component 'gdal' (alias 'ogr') +if(Osmium_USE_GDAL) + find_package(GDAL) + + if(GDAL_FOUND) + list(APPEND OSMIUM_LIBRARIES ${GDAL_LIBRARIES}) + list(APPEND OSMIUM_INCLUDE_DIRS ${GDAL_INCLUDE_DIRS}) + else() + set(_missing_libraries 1) + message(WARNING "Osmium: GDAL library is required but not found, please install it or configure the paths.") + endif() +endif() + +#---------------------------------------------------------------------- +# Component 'proj' +if(Osmium_USE_PROJ) + find_path(PROJ_INCLUDE_DIR proj_api.h) + find_library(PROJ_LIBRARY NAMES proj) + + if(PROJ_INCLUDE_DIR AND PROJ_LIBRARY) + set(PROJ_FOUND 1) + list(APPEND OSMIUM_LIBRARIES ${PROJ_LIBRARY}) + list(APPEND OSMIUM_INCLUDE_DIRS ${PROJ_INCLUDE_DIR}) + else() + set(_missing_libraries 1) + message(WARNING "Osmium: PROJ.4 library is required but not found, please install it or configure the paths.") + endif() +endif() + +#---------------------------------------------------------------------- +# Component 'sparsehash' +if(Osmium_USE_SPARSEHASH) + find_path(SPARSEHASH_INCLUDE_DIR google/sparsetable) + + if(SPARSEHASH_INCLUDE_DIR) + # Find size of sparsetable::size_type. This does not work on older + # CMake versions because they can do this check only in C, not in C++. + include(CheckTypeSize) + set(CMAKE_REQUIRED_INCLUDES ${SPARSEHASH_INCLUDE_DIR}) + set(CMAKE_EXTRA_INCLUDE_FILES "google/sparsetable") + check_type_size("google::sparsetable::size_type" SPARSETABLE_SIZE_TYPE LANGUAGE CXX) + set(CMAKE_EXTRA_INCLUDE_FILES) + set(CMAKE_REQUIRED_INCLUDES) + + # Falling back to checking size_t if google::sparsetable::size_type + # could not be checked. + if(SPARSETABLE_SIZE_TYPE STREQUAL "") + check_type_size("void*" VOID_PTR_SIZE) + set(SPARSETABLE_SIZE_TYPE ${VOID_PTR_SIZE}) + endif() + + # Sparsetable::size_type must be at least 8 bytes (64bit), otherwise + # OSM object IDs will not fit. + if(SPARSETABLE_SIZE_TYPE GREATER 7) + set(SPARSEHASH_FOUND 1) + add_definitions(-DOSMIUM_WITH_SPARSEHASH=${SPARSEHASH_FOUND}) + list(APPEND OSMIUM_INCLUDE_DIRS ${SPARSEHASH_INCLUDE_DIR}) + else() + message(WARNING "Osmium: Disabled Google SparseHash library on 32bit system (size_type=${SPARSETABLE_SIZE_TYPE}).") + endif() + else() + set(_missing_libraries 1) + message(WARNING "Osmium: Google SparseHash library is required but not found, please install it or configure the paths.") + endif() +endif() + +#---------------------------------------------------------------------- + +list(REMOVE_DUPLICATES OSMIUM_INCLUDE_DIRS) + +if(OSMIUM_XML_LIBRARIES) + list(REMOVE_DUPLICATES OSMIUM_XML_LIBRARIES) +endif() + +if(OSMIUM_PBF_LIBRARIES) + list(REMOVE_DUPLICATES OSMIUM_PBF_LIBRARIES) +endif() + +if(OSMIUM_IO_LIBRARIES) + list(REMOVE_DUPLICATES OSMIUM_IO_LIBRARIES) +endif() + +if(OSMIUM_LIBRARIES) + list(REMOVE_DUPLICATES OSMIUM_LIBRARIES) +endif() + +#---------------------------------------------------------------------- +# +# Check that all required libraries are available +# +#---------------------------------------------------------------------- +if(Osmium_FIND_REQUIRED AND _missing_libraries) + message(FATAL_ERROR "Required library or libraries missing. Aborting.") +endif() + +#---------------------------------------------------------------------- +# +# Add compiler flags +# +#---------------------------------------------------------------------- +add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64) + +if(MSVC) + add_definitions(-wd4996) + + # Disable warning C4068: "unknown pragma" because we want it to ignore + # pragmas for other compilers. + add_definitions(-wd4068) + + # Disable warning C4715: "not all control paths return a value" because + # it generates too many false positives. + add_definitions(-wd4715) + + # Disable warning C4351: new behavior: elements of array '...' will be + # default initialized. The new behaviour is correct and we don't support + # old compilers anyway. + add_definitions(-wd4351) + + add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS) +endif() + +if(APPLE) +# following only available from cmake 2.8.12: +# add_compile_options(-stdlib=libc++) +# so using this instead: + add_definitions(-stdlib=libc++) + set(LDFLAGS ${LDFLAGS} -stdlib=libc++) +endif() + +#---------------------------------------------------------------------- + +# This is a set of recommended warning options that can be added when compiling +# libosmium code. +if(MSVC) + set(OSMIUM_WARNING_OPTIONS "/W3 /wd4514" CACHE STRING "Recommended warning options for libosmium") +else() + set(OSMIUM_WARNING_OPTIONS "-Wall -Wextra -pedantic -Wredundant-decls -Wdisabled-optimization -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wsign-promo -Wold-style-cast -Wno-return-type" CACHE STRING "Recommended warning options for libosmium") +endif() + +set(OSMIUM_DRACONIC_CLANG_OPTIONS "-Wdocumentation -Wunused-exception-parameter -Wmissing-declarations -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-unused-macros -Wno-exit-time-destructors -Wno-global-constructors -Wno-padded -Wno-switch-enum -Wno-missing-prototypes -Wno-weak-vtables -Wno-cast-align -Wno-float-equal") + +if(Osmium_DEBUG) + message(STATUS "OSMIUM_XML_LIBRARIES=" ${OSMIUM_XML_LIBRARIES}) + message(STATUS "OSMIUM_PBF_LIBRARIES=" ${OSMIUM_PBF_LIBRARIES}) + message(STATUS "OSMIUM_IO_LIBRARIES=" ${OSMIUM_IO_LIBRARIES}) + message(STATUS "OSMIUM_LIBRARIES=" ${OSMIUM_LIBRARIES}) + message(STATUS "OSMIUM_INCLUDE_DIRS=" ${OSMIUM_INCLUDE_DIRS}) +endif() + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/cmake/README b/3party/osrm/osrm-backend/third_party/libosmium/cmake/README new file mode 100755 index 0000000000..4a035f7b21 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/cmake/README @@ -0,0 +1,3 @@ + +FindGem.cmake from https://github.com/rock-core/base-cmake + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/cmake/build.bat b/3party/osrm/osrm-backend/third_party/libosmium/cmake/build.bat new file mode 100755 index 0000000000..5ffab124eb --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/cmake/build.bat @@ -0,0 +1,15 @@ +call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 +set CMAKE_PREFIX_PATH=C:\PROJ +set VERSION=Debug +set TESTS=ON +set ALLHPPS=ON +set PREFIX=d:\libs18d +set BOOST_ROOT=d:\boost + +cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%PREFIX% -DBOOST_ROOT=%BOOST_ROOT% -DBoost_USE_STATIC_LIBS=ON -DBUILD_TESTING=%TESTS% -DBUILD_TRY_HPPS=%ALLHPPS$ -T CTP_Nov2013 +msbuild /clp:Verbosity=minimal /nologo libosmium.sln /flp1:logfile=build_errors.txt;errorsonly /flp2:logfile=build_warnings.txt;warningsonly +set PATH=%PATH%;%PREFIX%/bin + +del test\osm-testdata\*.db +del test\osm-testdata\*.json +if "%TESTS%"=="ON" ctest -VV >build_tests.log diff --git a/3party/osrm/osrm-backend/third_party/libosmium/cmake/iwyu.sh b/3party/osrm/osrm-backend/third_party/libosmium/cmake/iwyu.sh new file mode 100755 index 0000000000..d203844915 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/cmake/iwyu.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +# This will run IWYU (Include What You Use) on includes files. The iwyu +# program isn't very reliable and crashes often, but is still useful. +# +# TODO: This script should be integrated with cmake in some way... +# + +cmdline="iwyu -Xiwyu --mapping_file=osmium.imp -std=c++11 -I include" + +log=build/iwyu.log + +echo "INCLUDE WHAT YOU USE REPORT:" >$log + +allok=yes + +mkdir -p build/check_reports + +for file in `find include/osmium -name \*.hpp`; do + mkdir -p `dirname build/check_reports/$file` + ifile="build/check_reports/${file%.hpp}.iwyu" + $cmdline $file >$ifile 2>&1 + if grep -q 'has correct #includes/fwd-decls' ${ifile}; then + echo "\n\033[1m\033[32m========\033[0m \033[1m${file}\033[0m" >>$log + echo "[OK] ${file}" + elif grep -q 'Assertion failed' ${ifile}; then + echo "\n\033[1m======== ${file}\033[0m" >>$log + echo "[--] ${file}" + allok=no + else + echo "\n\033[1m\033[31m========\033[0m \033[1m${file}\033[0m" >>$log + echo "[ ] ${file}" + allok=no + fi + cat $ifile >>$log +done + +if [ "$allok" = "yes" ]; then + echo "All files OK" +else + echo "There were errors" +fi + diff --git a/3party/osrm/osrm-backend/third_party/libosmium/doc/CMakeLists.txt b/3party/osrm/osrm-backend/third_party/libosmium/doc/CMakeLists.txt new file mode 100755 index 0000000000..9d69a16bd9 --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/doc/CMakeLists.txt @@ -0,0 +1,35 @@ +#----------------------------------------------------------------------------- +# +# CMake Config +# +# Libosmium documentation +# +#----------------------------------------------------------------------------- + +message(STATUS "Configuring documentation") + +message(STATUS "Looking for doxygen") +find_package(Doxygen) + +if(DOXYGEN_FOUND) + message(STATUS "Looking for doxygen - found") + configure_file(header.html ${CMAKE_CURRENT_BINARY_DIR}/header.html @ONLY) + configure_file(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + add_custom_target(doc + ${DOXYGEN_EXECUTABLE} + ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen" VERBATIM + ) +# install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html" +# DESTINATION "share/doc/libosmium-dev") +else() + message(STATUS "Looking for doxygen - not found") + message(STATUS " Disabled making of documentation.") +endif() + +#----------------------------------------------------------------------------- +message(STATUS "Configuring documentation - done") + + +#----------------------------------------------------------------------------- diff --git a/3party/osrm/osrm-backend/third_party/libosmium/doc/Doxyfile.in b/3party/osrm/osrm-backend/third_party/libosmium/doc/Doxyfile.in new file mode 100755 index 0000000000..c03e255e9e --- /dev/null +++ b/3party/osrm/osrm-backend/third_party/libosmium/doc/Doxyfile.in @@ -0,0 +1,2313 @@ +# Doxyfile 1.8.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Libosmium" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = @LIBOSMIUM_VERSION@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Fast and flexible C++ library for working with OpenStreetMap data" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = "@PROJECT_BINARY_DIR@/doc" + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@/include + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. Do not use file names with spaces, bibtex cannot handle them. See +# also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = @PROJECT_SOURCE_DIR@/include/osmium \ + @PROJECT_SOURCE_DIR@/doc/doc.txt + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = *.hpp + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = detail + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = *::detail + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = "grep -v static_assert" + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = YES + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = NO + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = header.html + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- +# defined cascading style sheet that is included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet file to the output directory. For an example +# see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = "@PROJECT_SOURCE_DIR@/doc/osmium.css" + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the stylesheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NONE + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /