diff --git a/data/WorldCoasts_obsolete.mwm b/data/WorldCoasts_obsolete.mwm new file mode 100644 index 0000000000..5e14ccfb5f Binary files /dev/null and b/data/WorldCoasts_obsolete.mwm differ diff --git a/routing/bicycle_directions.cpp b/routing/bicycle_directions.cpp index bac5f0f28e..e5cedbb90a 100644 --- a/routing/bicycle_directions.cpp +++ b/routing/bicycle_directions.cpp @@ -105,7 +105,7 @@ void BicycleDirectionsEngine::Generate(IRoadGraph const & graph, vectorm_adjacentEdges[UniNodeId()] = AdjacentEdges(1); + this->m_adjacentEdges[UniNodeId(UniNodeId::Type::Mwm)] = AdjacentEdges(1); }; if (pathSize == 1) @@ -130,7 +130,7 @@ void BicycleDirectionsEngine::Generate(IRoadGraph const & graph, vector adjacentNodes; ingoingCount = 0; - for (EdgeID const e : m_routingMapping.m_dataFacade.GetAdjacentEdgeRange(node.GetIndex())) + for (EdgeID const e : m_routingMapping.m_dataFacade.GetAdjacentEdgeRange(node.GetNodeId())) { - QueryEdge::EdgeData const data = m_routingMapping.m_dataFacade.GetEdgeData(e, node.GetIndex()); + QueryEdge::EdgeData const data = m_routingMapping.m_dataFacade.GetEdgeData(e, node.GetNodeId()); if (data.shortcut) continue; if (data.forward) @@ -105,11 +105,11 @@ public: for (NodeID const adjacentNode : geomNodes) { - if (adjacentNode == node.GetIndex()) + if (adjacentNode == node.GetNodeId()) continue; for (EdgeID const e : m_routingMapping.m_dataFacade.GetAdjacentEdgeRange(adjacentNode)) { - if (m_routingMapping.m_dataFacade.GetTarget(e) != node.GetIndex()) + if (m_routingMapping.m_dataFacade.GetTarget(e) != node.GetNodeId()) continue; QueryEdge::EdgeData const data = m_routingMapping.m_dataFacade.GetEdgeData(e, adjacentNode); if (data.shortcut) @@ -172,7 +172,7 @@ public: for (auto const & pathSegments : m_rawResult.unpackedPathSegments) { auto numSegments = pathSegments.size(); - m_loadedSegments.resize(numSegments); + m_loadedSegments.resize(numSegments, LoadedPathSegment(UniNodeId::Type::Osrm)); for (size_t segmentIndex = 0; segmentIndex < numSegments; ++segmentIndex) { bool isStartNode = (segmentIndex == 0); diff --git a/routing/loaded_path_segment.hpp b/routing/loaded_path_segment.hpp index ae6c405459..ad785300f0 100644 --- a/routing/loaded_path_segment.hpp +++ b/routing/loaded_path_segment.hpp @@ -40,7 +40,7 @@ struct LoadedPathSegment bool m_onRoundabout; bool m_isLink; - LoadedPathSegment() + LoadedPathSegment(UniNodeId::Type type) : m_nodeId(type) { Clear(); } diff --git a/routing/routing_tests/turns_generator_test.cpp b/routing/routing_tests/turns_generator_test.cpp index 47c12bd8d9..f4f2b2bdfb 100644 --- a/routing/routing_tests/turns_generator_test.cpp +++ b/routing/routing_tests/turns_generator_test.cpp @@ -326,7 +326,7 @@ UNIT_TEST(TestCalculateMercatorDistanceAlongRoute) UNIT_TEST(TestCheckUTurnOnRoute) { - TUnpackedPathSegments pathSegments(4); + TUnpackedPathSegments pathSegments(4, LoadedPathSegment(UniNodeId::Type::Osrm)); pathSegments[0].m_name = "A road"; pathSegments[0].m_weight = 1; pathSegments[0].m_nodeId = UniNodeId(0 /* node id */); diff --git a/routing/turns.cpp b/routing/turns.cpp index f78e75042d..e883ce66a7 100644 --- a/routing/turns.cpp +++ b/routing/turns.cpp @@ -52,20 +52,34 @@ static_assert(g_turnNames.size() == static_cast(TurnDirection::Count), namespace routing { // UniNodeId ------------------------------------------------------------------- -bool UniNodeId::operator==(UniNodeId const & rh) const +bool UniNodeId::operator==(UniNodeId const & rhs) const { - return m_featureId == rh.m_featureId && m_segId == rh.m_segId && m_forward == rh.m_forward; + if (m_type != rhs.m_type) + return false; + + switch (m_type) { + case Type::Osrm: return m_nodeId == rhs.m_nodeId; + case Type::Mwm: return m_featureId == rhs.m_featureId + && m_segId == rhs.m_segId && m_forward == rhs.m_forward; + } } -bool UniNodeId::operator<(UniNodeId const & rh) const +bool UniNodeId::operator<(UniNodeId const & rhs) const { - if (m_featureId != rh.m_featureId) - return m_featureId < rh.m_featureId; + if (m_type != rhs.m_type) + return m_type < rhs.m_type; - if (m_segId != rh.m_segId) - return m_segId < rh.m_segId; + switch (m_type) { + case Type::Osrm: return m_nodeId < rhs.m_nodeId; + case Type::Mwm: + if (m_featureId != rhs.m_featureId) + return m_featureId < rhs.m_featureId; - return m_forward < rh.m_forward; + if (m_segId != rhs.m_segId) + return m_segId < rhs.m_segId; + + return m_forward < rhs.m_forward; + } } void UniNodeId::Clear() @@ -73,6 +87,39 @@ void UniNodeId::Clear() m_featureId = FeatureID(); m_segId = 0; m_forward = true; + m_nodeId = SPECIAL_NODEID; +} + +uint32_t UniNodeId::GetNodeId() const +{ + ASSERT_EQUAL(m_type, Type::Osrm, ()); + return m_nodeId; +} + +FeatureID const & UniNodeId::GetFeature() const +{ + ASSERT_EQUAL(m_type, Type::Mwm, ()); + return m_featureId; +} + +uint32_t UniNodeId::GetSegId() const +{ + ASSERT_EQUAL(m_type, Type::Mwm, ()); + return m_segId; +} + +bool UniNodeId::IsForward() const +{ + ASSERT_EQUAL(m_type, Type::Mwm, ()); + return m_forward; +} + +string DebugPrint(UniNodeId::Type type) +{ + switch (type) { + case UniNodeId::Type::Osrm: return "Osrm"; + case UniNodeId::Type::Mwm: return "Mwm"; + } } namespace turns diff --git a/routing/turns.hpp b/routing/turns.hpp index faed89b460..7039a41b66 100644 --- a/routing/turns.hpp +++ b/routing/turns.hpp @@ -16,32 +16,42 @@ namespace routing using TNodeId = uint32_t; using TEdgeWeight = double; -/// \brief Unique identification for a road edge between to junctions (joints). +/// \brief Unique identification for a road edge between two junctions (joints). /// In case of OSRM it's NodeID and in case of RoadGraph (IndexGraph) /// it's mwm id, feature id, segment id and direction. struct UniNodeId { - UniNodeId() = default; + enum class Type + { + Osrm, + Mwm, + }; + + UniNodeId(Type type) : m_type(type) {} UniNodeId(FeatureID const & featureId, uint32_t segId, bool forward) - : m_featureId(featureId), m_segId(segId), m_forward(forward) {} - UniNodeId(uint32_t nodeId) : m_featureId(MwmSet::MwmId(), nodeId) {} + : m_type(Type::Mwm), m_featureId(featureId), m_segId(segId), m_forward(forward) {} + UniNodeId(uint32_t nodeId) : m_type(Type::Osrm), m_nodeId(nodeId) {} bool operator==(UniNodeId const & rh) const; bool operator<(UniNodeId const & rh) const; - uint32_t GetIndex() const { return m_featureId.m_index; } - FeatureID const & GetFeature() const { return m_featureId; } - uint32_t GetSegId() const { return m_segId; } - bool IsForward() const { return m_forward; } void Clear(); + uint32_t GetNodeId() const; + FeatureID const & GetFeature() const; + uint32_t GetSegId() const; + bool IsForward() const; private: + Type m_type; /// \note In case of OSRM unique id is kept in |m_featureId.m_index|. /// So |m_featureId.m_mwmId|, |m_segId| and |m_forward| have default values. FeatureID m_featureId; // |m_featureId.m_index| is NodeID for OSRM. uint32_t m_segId = 0; // Not valid for OSRM. bool m_forward = true; // Segment direction in |m_featureId|. + NodeID m_nodeId = SPECIAL_NODEID; }; +string DebugPrint(UniNodeId::Type type); + namespace turns { /// @todo(vbykoianko) It's a good idea to gather all the turns information into one entity.