diff --git a/routing/CMakeLists.txt b/routing/CMakeLists.txt index b723516654..b557d90956 100644 --- a/routing/CMakeLists.txt +++ b/routing/CMakeLists.txt @@ -23,6 +23,8 @@ set( car_router.cpp car_router.hpp cross_mwm_index_graph.hpp + cross_mwm_index_graph_osrm.cpp + cross_mwm_index_graph_osrm.hpp cross_mwm_road_graph.cpp cross_mwm_road_graph.hpp cross_mwm_router.cpp diff --git a/routing/cross_mwm_index_graph.hpp b/routing/cross_mwm_index_graph.hpp index e57b1e4360..c3ec20f21a 100644 --- a/routing/cross_mwm_index_graph.hpp +++ b/routing/cross_mwm_index_graph.hpp @@ -40,7 +40,7 @@ public: /// * exit transition segments are exits from their mwms; /// \returns true if |s| is an exit (|isOutgoing| == true) or an enter (|isOutgoing| == false) /// transition segment. - virtual bool IsTransition(Segment const & s, bool isOutgoing) const = 0; + virtual bool IsTransition(Segment const & s, bool isOutgoing) = 0; /// \brief Fills |twins| with duplicates of |s| transition segment in neighbouring mwm. /// For most cases there is only one twin for |s|. diff --git a/routing/cross_mwm_index_graph_osrm.cpp b/routing/cross_mwm_index_graph_osrm.cpp new file mode 100644 index 0000000000..4fd2f99c19 --- /dev/null +++ b/routing/cross_mwm_index_graph_osrm.cpp @@ -0,0 +1,76 @@ +#include "routing/cross_mwm_index_graph_osrm.hpp" + +#include "platform/country_file.hpp" + +#include "base/macros.hpp" + +#include + +namespace +{ +void FillTransitionSegments(routing::OsrmFtSegMapping const & segMapping, routing::TWrittenNodeId nodeId, + routing::NumMwmId mwmId, std::set & transitionSegments) +{ + auto const range = segMapping.GetSegmentsRange(nodeId); + for (size_t segmentIndex = range.first; segmentIndex != range.second; ++segmentIndex) + { + routing::OsrmMappingTypes::FtSeg seg; + // The meaning of node id in osrm is an edge between two joints. + // So, it's possible to consider the first valid segment from the range which returns by GetSegmentsRange(). + segMapping.GetSegmentByIndex(segmentIndex, seg); + if (!seg.IsValid()) + continue; + + CHECK_NOT_EQUAL(seg.m_pointStart, seg.m_pointEnd, ()); + transitionSegments.emplace(seg.m_fid, min(seg.m_pointStart, seg.m_pointEnd), mwmId, seg.IsForward()); + return; + } + LOG(LERROR, ("No valid segments in the range returned by OsrmFtSegMapping::GetSegmentsRange(", nodeId, ")")); +} +} // namespace + +namespace routing +{ +bool CrossMwmIndexGraphOsrm::IsTransition(Segment const & s, bool isOutgoing) +{ + auto it = m_transitionCache.find(s.GetMwmId()); + if (it == m_transitionCache.cend()) + { + platform::CountryFile const & countryFile = m_numMwmIds->GetFile(s.GetMwmId()); + TRoutingMappingPtr mappingPtr = m_indexManager.GetMappingByName(countryFile.GetName()); + CHECK(mappingPtr, ("countryFile:", countryFile)); + mappingPtr->LoadCrossContext(); + + TransitionSegments transitionSegments; + mappingPtr->m_crossContext.ForEachOutgoingNode([&](OutgoingCrossNode const & node) + { + FillTransitionSegments(mappingPtr->m_segMapping, node.m_nodeId, s.GetMwmId(), + transitionSegments.m_outgoing); + }); + mappingPtr->m_crossContext.ForEachIngoingNode([&](IngoingCrossNode const & node) + { + FillTransitionSegments(mappingPtr->m_segMapping, node.m_nodeId, s.GetMwmId(), + transitionSegments.m_ingoing); + }); + auto const p = m_transitionCache.emplace(s.GetMwmId(), transitionSegments); + it = p.first; + CHECK(p.second, ("Mwm num id:", s.GetMwmId(), "has been inserted before. countryFile:", + countryFile)); + } + + if (isOutgoing) + return it->second.m_outgoing.count(s) != 0; + return it->second.m_ingoing.count(s) != 0; +} + +void CrossMwmIndexGraphOsrm::GetTwin(Segment const & /* s */, std::vector & /* twins */) const +{ + NOTIMPLEMENTED(); +} + +void CrossMwmIndexGraphOsrm::GetEdgeList(Segment const & /* s */, + bool /* isOutgoing */, std::vector & /* edges */) const +{ + NOTIMPLEMENTED(); +} +} // namespace routing diff --git a/routing/cross_mwm_index_graph_osrm.hpp b/routing/cross_mwm_index_graph_osrm.hpp new file mode 100644 index 0000000000..986ba3c0e2 --- /dev/null +++ b/routing/cross_mwm_index_graph_osrm.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "routing/cross_mwm_index_graph.hpp" +#include "routing/num_mwm_id.hpp" +#include "routing/routing_mapping.hpp" + +#include "base/math.hpp" + +#include +#include +#include + +namespace routing +{ +class CrossMwmIndexGraphOsrm : public CrossMwmIndexGraph +{ +public: + CrossMwmIndexGraphOsrm(std::shared_ptr numMwmIds, RoutingIndexManager & indexManager) + : m_indexManager(indexManager), m_numMwmIds(numMwmIds) + { + } + + // CrossMwmIndexGraph overrides: + bool IsTransition(Segment const & s, bool isOutgoing) override; + void GetTwin(Segment const & s, std::vector & twins) const override; + void GetEdgeList(Segment const & s, bool isOutgoing, std::vector & edges) const override; + +private: + struct TransitionSegments + { + std::set m_ingoing; + std::set m_outgoing; + }; + + RoutingIndexManager & m_indexManager; + std::shared_ptr m_numMwmIds; + + std::map m_transitionCache; +}; +} // namespace routing diff --git a/routing/routing.pro b/routing/routing.pro index d27264dffc..9d7a6d4515 100644 --- a/routing/routing.pro +++ b/routing/routing.pro @@ -19,6 +19,7 @@ SOURCES += \ bicycle_model.cpp \ car_model.cpp \ car_router.cpp \ + cross_mwm_index_graph_osrm.cpp \ cross_mwm_road_graph.cpp \ cross_mwm_router.cpp \ cross_routing_context.cpp \ @@ -72,6 +73,7 @@ HEADERS += \ car_model.hpp \ car_router.hpp \ cross_mwm_index_graph.hpp \ + cross_mwm_index_graph_osrm.hpp \ cross_mwm_road_graph.hpp \ cross_mwm_router.hpp \ cross_routing_context.hpp \ diff --git a/routing/segment.hpp b/routing/segment.hpp index 143e9ac689..f108c362c1 100644 --- a/routing/segment.hpp +++ b/routing/segment.hpp @@ -28,7 +28,7 @@ public: } constexpr Segment(NumMwmId mwmId, uint32_t featureId, uint32_t segmentIdx, bool forward) - : m_mwmId(mwmId), m_featureId(featureId), m_segmentIdx(segmentIdx), m_forward(forward) + : m_featureId(featureId), m_segmentIdx(segmentIdx), m_mwmId(mwmId), m_forward(forward) { } @@ -67,10 +67,10 @@ public: bool operator!=(Segment const & seg) const { return !(*this == seg); } private: - // @TODO(bykoianko, dobriy-eeh). It's a placeholder. Init m_mwmId in a proper way. - NumMwmId m_mwmId = 0; uint32_t m_featureId = 0; uint32_t m_segmentIdx = 0; + // @TODO(bykoianko, dobriy-eeh). It's a placeholder. Init m_mwmId in a proper way. + NumMwmId m_mwmId = 0; bool m_forward = true; }; diff --git a/xcode/routing/routing.xcodeproj/project.pbxproj b/xcode/routing/routing.xcodeproj/project.pbxproj index a335e7b4ab..ccb14d8aba 100644 --- a/xcode/routing/routing.xcodeproj/project.pbxproj +++ b/xcode/routing/routing.xcodeproj/project.pbxproj @@ -60,6 +60,8 @@ 56CA09E71E30E73B00D05C9A /* restriction_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56CA09E21E30E73B00D05C9A /* restriction_test.cpp */; }; 56CA09E91E30F19800D05C9A /* libtraffic.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56CA09E81E30F19800D05C9A /* libtraffic.a */; }; 56CC5A371E3884960016AC46 /* cross_mwm_index_graph.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 56CC5A361E3884960016AC46 /* cross_mwm_index_graph.hpp */; }; + 56D637D31E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56D637D11E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.cpp */; }; + 56D637D41E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 56D637D21E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.hpp */; }; 56EA2FD51D8FD8590083F01A /* routing_helpers.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 56EA2FD41D8FD8590083F01A /* routing_helpers.hpp */; }; 56F0D7341D896A5300045886 /* libmap.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67BD35DE1C69F198003AA26F /* libmap.a */; }; 56F0D7391D896A5300045886 /* libstorage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67BD35D41C69F155003AA26F /* libstorage.a */; }; @@ -309,6 +311,8 @@ 56CA09E21E30E73B00D05C9A /* restriction_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = restriction_test.cpp; sourceTree = ""; }; 56CA09E81E30F19800D05C9A /* libtraffic.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtraffic.a; path = "/Users/vladimirbykoyanko/src_github_master/omim/xcode/traffic/../../../omim-build/xcode/Debug/libtraffic.a"; sourceTree = ""; }; 56CC5A361E3884960016AC46 /* cross_mwm_index_graph.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cross_mwm_index_graph.hpp; sourceTree = ""; }; + 56D637D11E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cross_mwm_index_graph_osrm.cpp; sourceTree = ""; }; + 56D637D21E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cross_mwm_index_graph_osrm.hpp; sourceTree = ""; }; 56EA2FD41D8FD8590083F01A /* routing_helpers.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = routing_helpers.hpp; sourceTree = ""; }; 56F0D75F1D896A5300045886 /* routing_benchmarks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = routing_benchmarks.app; sourceTree = BUILT_PRODUCTS_DIR; }; 670B84BE1A9381D900CE4492 /* cross_routing_context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cross_routing_context.cpp; sourceTree = ""; }; @@ -707,6 +711,8 @@ 675343FA1A3F640D00A0A8C3 /* routing */ = { isa = PBXGroup; children = ( + 56D637D11E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.cpp */, + 56D637D21E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.hpp */, 674F9BBA1B0A580E00704FFA /* async_router.cpp */, 674F9BBB1B0A580E00704FFA /* async_router.hpp */, 671F58BA1B874EA20032311E /* base */, @@ -895,6 +901,7 @@ 670D049F1B0B4A970013A7AC /* nearest_edge_finder.hpp in Headers */, A120B34F1B4A7C0A002F3808 /* online_absent_fetcher.hpp in Headers */, 674F9BD51B0A580E00704FFA /* road_graph.hpp in Headers */, + 56D637D41E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.hpp in Headers */, 56826BD11DB51C4E00807C62 /* car_router.hpp in Headers */, A120B3511B4A7C0A002F3808 /* routing_algorithm.hpp in Headers */, 0C5FEC6B1DDE193F0017688C /* road_point.hpp in Headers */, @@ -1134,6 +1141,7 @@ 0C0DF9211DE898B70055A22F /* index_graph_starter.cpp in Sources */, A120B3471B4A7BE5002F3808 /* cross_mwm_router.cpp in Sources */, 670EE5731B664796001E8064 /* pedestrian_directions.cpp in Sources */, + 56D637D31E49F8DA00B86D7B /* cross_mwm_index_graph_osrm.cpp in Sources */, 6753441B1A3F644F00A0A8C3 /* route.cpp in Sources */, 674F9BCA1B0A580E00704FFA /* async_router.cpp in Sources */, 675344191A3F644F00A0A8C3 /* osrm2feature_map.cpp in Sources */,