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

cross_mwm_graph.hpp « routing - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 601ff16ad6ccb5860b7dd22ef2ab2ece282969ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#pragma once

#include "routing/cross_mwm_ids.hpp"
#include "routing/cross_mwm_index_graph.hpp"
#include "routing/router.hpp"
#include "routing/segment.hpp"
#include "routing/vehicle_mask.hpp"

#include "routing_common/num_mwm_id.hpp"
#include "routing_common/vehicle_model.hpp"

#include "geometry/tree4d.hpp"

#include "base/math.hpp"
#include "base/osm_id.hpp"

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

class DataSourceBase;

namespace routing
{
/// \brief Getting information for cross mwm routing.
class CrossMwmGraph final
{
public:
  enum class MwmStatus
  {
    NotLoaded,
    SectionExists,
    NoSection,
  };

  CrossMwmGraph(std::shared_ptr<NumMwmIds> numMwmIds, shared_ptr<m4::Tree<NumMwmId>> numMwmTree,
                std::shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory, VehicleType vehicleType,
                CourntryRectFn const & countryRectFn, DataSourceBase & dataSource);

  /// \brief Transition segment is a segment which is crossed by mwm border. That means
  /// start and finish of such segment have to lie in different mwms. If a segment is
  /// crossed by mwm border but its start and finish lie in the same mwm it's not
  /// a transition segment.
  /// For most cases there is only one transition segment for a transition feature.
  /// Transition segment at the picture below is marked as *===>*.
  /// Transition feature is a feature which contains one or more transition segments.
  /// Transition features at the picture below is marked as *===>*------>*.
  /// Every transition feature is duplicated in two neighbouring mwms.
  /// The duplicate is called "twin" at the picture below.
  /// For most cases a transition feature contains only one transition segment.
  /// -------MWM0---------------MWM1----------------MWM2-------------
  /// |                   |                 |                       |
  /// | F0 in MWM0   *===>*------>*    *===>*------>*  F2 of MWM1   |
  /// | Twin in MWM1 *===>*------>*    *===>*------>*  Twin in MWM2 |
  /// |                   |                 |                       |
  /// | F1 in MWM0      *===>*---->*      *===>*--->*  F3 of MWM1   |
  /// | Twin in MWM1    *===>*---->*      *===>*--->*  Twin in MWM2 |
  /// |                   |                 |                       |
  /// ---------------------------------------------------------------
  /// There are two kinds of transition segments:
  /// * enter transition segments are enters to their mwms;
  /// * exit transition segments are exits from their mwms;
  /// \returns true if |s| is an exit (|isOutgoing| == true) or an enter (|isOutgoing| == false)
  /// transition segment.
  bool IsTransition(Segment const & s, bool isOutgoing);

  /// \brief Fills |twins| with duplicates of |s| transition segment in neighbouring mwm.
  /// For most cases there is only one twin for |s|.
  /// If |isOutgoing| == true |s| should be an exit transition segment and
  /// the method fills |twins| with appropriate enter transition segments.
  /// If |isOutgoing| == false |s| should be an enter transition segment and
  /// the method fills |twins| with appropriate exit transition segments.
  /// \note GetTwins(s, isOutgoing, ...) shall be called only if IsTransition(s, isOutgoing) returns
  /// true.
  /// \note GetTwins(s, isOutgoing, twins) fills |twins| only if mwm contained |twins| has been
  /// downloaded.
  /// If not, |twins| could be emply after a GetTwins(...) call.
  void GetTwins(Segment const & s, bool isOutgoing, std::vector<Segment> & twins);

  /// \brief Fills |edges| with edges outgoing from |s|.
  /// |s| should be an enter transition segment, |edges| is filled with all edges starting from |s|
  /// and ending at all reachable exit transition segments of the mwm of |s|.
  /// Weight of each edge is equal to weight of the route form |s| to |SegmentEdge::m_target|.
  /// Getting ingoing edges is not supported because we do not have enough information
  /// to calculate |segment| weight.
  void GetOutgoingEdgeList(Segment const & s, std::vector<SegmentEdge> & edges);

  void Clear();

  // \returns transitions for mwm with id |numMwmId| for CrossMwmIndexGraph.
  std::vector<Segment> const & GetTransitions(NumMwmId numMwmId, bool isEnter)
  {
    CHECK(CrossMwmSectionExists(numMwmId), ("Should be used in LeapsOnly mode only. LeapsOnly mode requires CrossMwmIndexGraph."));
    return m_crossMwmIndexGraph.GetTransitions(numMwmId, isEnter);
  }

private:
  struct ClosestSegment
  {
    ClosestSegment();
    ClosestSegment(double minDistM, Segment const & bestSeg, bool exactMatchFound);
    void Update(double distM, Segment const & bestSeg);

    double m_bestDistM;
    Segment m_bestSeg;
    bool m_exactMatchFound;
  };

  /// \returns points of |s|. |s| should be a transition segment of mwm with an index graph cross-mwm section.
  /// \param s is a transition segment of type |isOutgoing|.
  /// \note the result of the method is returned by value because the size of the vector is usually
  /// one or very small.
  TransitionPoints GetTransitionPoints(Segment const & s, bool isOutgoing);

  MwmStatus GetMwmStatus(NumMwmId numMwmId, std::string const & sectionName) const;
  MwmStatus GetCrossMwmStatus(NumMwmId numMwmId) const;
  MwmStatus GetTransitCrossMwmStatus(NumMwmId numMwmId) const;
  bool CrossMwmSectionExists(NumMwmId numMwmId) const;
  bool TransitCrossMwmSectionExists(NumMwmId numMwmId) const;

  /// \brief Fills |twins| with transition segments of feature |ft| of type |isOutgoing|.
  void GetTwinCandidates(FeatureType const & ft, bool isOutgoing,
                         std::vector<Segment> & twinCandidates);

  /// \brief Fills structure |twins| or for feature |ft| if |ft| contains transition segment(s).
  /// \param sMwmId mwm id of a segment which twins are looked for
  /// \param ft feature which could contain twin segments
  /// \param point point of a segment which twins are looked for
  /// \param minDistSegs is used to keep the best twin candidate
  /// \param twins is filled with twins if there're twins (one or more) that have a point which is
  ///        very near or equal to |point|.
  /// \note If the method finds twin segment with a point which is very close to |point| the twin segment is
  /// added to |twins| anyway. If there's no such segment in mwm it tries find the closet one and adds it
  /// to |minDistSegs|.
  void FindBestTwins(NumMwmId sMwmId, bool isOutgoing, FeatureType const & ft,
                     m2::PointD const & point, std::map<NumMwmId, ClosestSegment> & minDistSegs,
                     std::vector<Segment> & twins);

  /// \brief Fills |neighbors| with number mwm id of all loaded neighbors of |numMwmId| and
  /// sets |allNeighborsHaveCrossMwmSection| to true if all loaded neighbors have cross mwm section
  /// and to false otherwise.
  void GetAllLoadedNeighbors(NumMwmId numMwmId,
                             std::vector<NumMwmId> & neighbors,
                             bool & allNeighborsHaveCrossMwmSection);
  /// \brief Deserizlize transitions for mwm with |ids|.
  void DeserializeTransitions(std::vector<NumMwmId> const & mwmIds);
  void DeserializeTransitTransitions(std::vector<NumMwmId> const & mwmIds);

  DataSourceBase & m_dataSource;
  std::shared_ptr<NumMwmIds> m_numMwmIds;
  std::shared_ptr<m4::Tree<NumMwmId>> m_numMwmTree;
  std::shared_ptr<VehicleModelFactoryInterface> m_vehicleModelFactory;
  CourntryRectFn const & m_countryRectFn;
  CrossMwmIndexGraph<osm::Id> m_crossMwmIndexGraph;
  CrossMwmIndexGraph<connector::TransitId> m_crossMwmTransitGraph;
};

string DebugPrint(CrossMwmGraph::MwmStatus status);
}  // routing