Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'routing/cross_mwm_connector.hpp')
-rw-r--r--routing/cross_mwm_connector.hpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/routing/cross_mwm_connector.hpp b/routing/cross_mwm_connector.hpp
new file mode 100644
index 0000000000..22ef84de61
--- /dev/null
+++ b/routing/cross_mwm_connector.hpp
@@ -0,0 +1,139 @@
+#pragma once
+
+#include "routing/segment.hpp"
+
+#include "geometry/point2d.hpp"
+
+#include "base/assert.hpp"
+
+#include <cmath>
+#include <limits>
+#include <unordered_map>
+#include <vector>
+
+namespace routing
+{
+class CrossMwmConnector final
+{
+public:
+ CrossMwmConnector() : m_mwmId(kFakeNumMwmId) {}
+ explicit CrossMwmConnector(NumMwmId mwmId) : m_mwmId(mwmId) {}
+
+ void AddTransition(uint32_t featureId, uint32_t segmentIdx, bool oneWay, bool forwardIsEnter,
+ m2::PointD const & backPoint, m2::PointD const & frontPoint);
+
+ bool IsTransition(Segment const & segment, bool isOutgoing) const;
+ m2::PointD const & GetPoint(Segment const & segment, bool front) const;
+ void GetEdgeList(Segment const & segment, bool isOutgoing,
+ std::vector<SegmentEdge> & edges) const;
+
+ std::vector<Segment> const & GetEnters() const { return m_enters; }
+ std::vector<Segment> const & GetExits() const { return m_exits; }
+ bool HasWeights() const { return !m_weights.empty(); }
+ bool WeightsWereLoaded() const;
+
+ template <typename CalcWeight>
+ void FillWeights(CalcWeight && calcWeight)
+ {
+ CHECK_EQUAL(m_weightsLoadState, WeightsLoadState::Unknown, ());
+ CHECK(m_weights.empty(), ());
+
+ m_weights.reserve(m_enters.size() * m_exits.size());
+ for (Segment const & enter : m_enters)
+ {
+ for (Segment const & exit : m_exits)
+ {
+ double const weight = calcWeight(enter, exit);
+ // Edges weights should be >= astar heuristic, so use std::ceil.
+ m_weights.push_back(static_cast<Weight>(std::ceil(weight)));
+ }
+ }
+ }
+
+private:
+ // This is an internal type for storing edges weights.
+ // Weight is the time requred for the route to pass.
+ // Weight is measured in seconds rounded upwards.
+ using Weight = uint32_t;
+
+ static Weight constexpr kNoRoute = 0;
+
+ struct Key
+ {
+ Key() = default;
+
+ Key(uint32_t featureId, uint32_t segmentIdx) : m_featureId(featureId), m_segmentIdx(segmentIdx)
+ {
+ }
+
+ bool operator==(Key const & key) const
+ {
+ return m_featureId == key.m_featureId && m_segmentIdx == key.m_segmentIdx;
+ }
+
+ uint32_t m_featureId = 0;
+ uint32_t m_segmentIdx = 0;
+ };
+
+ struct HashKey
+ {
+ size_t operator()(Key const & key) const
+ {
+ return std::hash<uint64_t>()((static_cast<uint64_t>(key.m_featureId) << 32) +
+ static_cast<uint64_t>(key.m_segmentIdx));
+ }
+ };
+
+ struct Transition
+ {
+ Transition() = default;
+
+ Transition(uint32_t enterIdx, uint32_t exitIdx, bool oneWay, bool forwardIsEnter,
+ m2::PointD const & backPoint, m2::PointD const & frontPoint)
+ : m_enterIdx(enterIdx)
+ , m_exitIdx(exitIdx)
+ , m_backPoint(backPoint)
+ , m_frontPoint(frontPoint)
+ , m_oneWay(oneWay)
+ , m_forwardIsEnter(forwardIsEnter)
+ {
+ }
+
+ uint32_t m_enterIdx = 0;
+ uint32_t m_exitIdx = 0;
+ // Endpoints of transition segment.
+ // m_backPoint = points[segmentIdx]
+ // m_frontPoint = points[segmentIdx + 1]
+ m2::PointD m_backPoint = m2::PointD::Zero();
+ m2::PointD m_frontPoint = m2::PointD::Zero();
+ bool m_oneWay = false;
+ // Transition represents both forward and backward segments with same featureId, segmentIdx.
+ // m_forwardIsEnter == true means: forward segment is enter to mwm:
+ // Enter means: m_backPoint is outside mwm borders, m_frontPoint is inside.
+ bool m_forwardIsEnter = false;
+ };
+
+ enum class WeightsLoadState
+ {
+ Unknown,
+ NotExists,
+ ReadyToLoad,
+ Loaded
+ };
+
+ friend class CrossMwmConnectorSerializer;
+ friend std::string DebugPrint(WeightsLoadState state);
+
+ void AddEdge(Segment const & segment, Weight weight, std::vector<SegmentEdge> & edges) const;
+ Transition const & GetTransition(Segment const & segment) const;
+ Weight GetWeight(size_t enterIdx, size_t exitIdx) const;
+
+ NumMwmId const m_mwmId;
+ std::vector<Segment> m_enters;
+ std::vector<Segment> m_exits;
+ std::unordered_map<Key, Transition, HashKey> m_transitions;
+ WeightsLoadState m_weightsLoadState = WeightsLoadState::Unknown;
+ uint64_t m_weightsOffset = 0;
+ std::vector<Weight> m_weights;
+};
+} // namespace routing