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

index_graph_starter.hpp « routing - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 5754cf642ca4e9d621b56971cfe5c56082b56fa0 (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
#pragma once

#include "routing/index_graph.hpp"
#include "routing/joint.hpp"
#include "routing/num_mwm_id.hpp"
#include "routing/route_point.hpp"
#include "routing/world_graph.hpp"

#include "std/limits.hpp"
#include "std/utility.hpp"
#include "std/vector.hpp"

namespace routing
{
// IndexGraphStarter adds fake start and finish vertexes for AStarAlgorithm.
class IndexGraphStarter final
{
public:
  // AStarAlgorithm types aliases:
  using TVertexType = WorldGraph::Vertex;
  using TEdgeType = WorldGraph::Edge;

  class FakeVertex final
  {
  public:
    FakeVertex(NumMwmId mwmId, uint32_t featureId, uint32_t segmentIdx, m2::PointD const & point)
      : m_segment(mwmId, featureId, segmentIdx, true /* forward */), m_point(point), m_soft(true)
    {
    }

    FakeVertex(Segment const & segment, m2::PointD const & point, bool soft)
      : m_segment(segment), m_point(point), m_soft(soft)
    {
    }

    NumMwmId GetMwmId() const { return m_segment.GetMwmId(); }
    uint32_t GetFeatureId() const { return m_segment.GetFeatureId(); }
    m2::PointD const & GetPoint() const { return m_point; }
    Segment const & GetSegment() const { return m_segment; }
    bool GetSoft() const { return m_soft; }

    Segment GetSegmentWithDirection(bool forward) const
    {
      return Segment(m_segment.GetMwmId(), m_segment.GetFeatureId(), m_segment.GetSegmentIdx(),
                     forward);
    }

    bool Fits(Segment const & segment) const
    {
      if (!m_soft)
        return segment == m_segment;

      return segment.GetMwmId() == m_segment.GetMwmId() &&
             segment.GetFeatureId() == m_segment.GetFeatureId() &&
             segment.GetSegmentIdx() == m_segment.GetSegmentIdx();
    }

    uint32_t GetSegmentIdxForTesting() const { return m_segment.GetSegmentIdx(); }

  private:
    Segment m_segment;
    m2::PointD const m_point;
    // If |m_soft| == true it means that |m_segment| should be used as a two way segment. So it's
    // possible to go along |m_segment| in any direction. In that case the instanse of FakeVertex
    // could be considered as a soft FakeVertex.
    // If |m_soft| == true it means it's possible to go along |m_segment| only in direction according
    // to its |m_forward| parameter.
    bool const m_soft;
  };

  static uint32_t constexpr kFakeFeatureId = numeric_limits<uint32_t>::max();
  static uint32_t constexpr kFakeSegmentIdx = numeric_limits<uint32_t>::max();
  static Segment constexpr kStartFakeSegment =
    Segment(kFakeNumMwmId, kFakeFeatureId, kFakeSegmentIdx, false);
  static Segment constexpr kFinishFakeSegment =
    Segment(kFakeNumMwmId, kFakeFeatureId, kFakeSegmentIdx, true);

  IndexGraphStarter(FakeVertex const & start, FakeVertex const & finish, WorldGraph & graph);

  WorldGraph & GetGraph() { return m_graph; }
  Segment const & GetStart() const { return kStartFakeSegment; }
  Segment const & GetFinish() const { return kFinishFakeSegment; }
  FakeVertex const & GetStartVertex() const { return m_start; }
  FakeVertex const & GetFinishVertex() const { return m_finish; }
  m2::PointD const & GetPoint(Segment const & segment, bool front);
  bool FitsStart(Segment const & s) const { return m_start.Fits(s); }
  bool FitsFinish(Segment const & s) const { return m_finish.Fits(s); }

  static size_t GetRouteNumPoints(vector<Segment> const & route);
  m2::PointD const & GetRoutePoint(vector<Segment> const & route, size_t pointIndex);

  void GetEdgesList(Segment const & segment, bool isOutgoing, vector<SegmentEdge> & edges);

  void GetOutgoingEdgesList(TVertexType const & segment, vector<TEdgeType> & edges)
  {
    GetEdgesList(segment, true /* isOutgoing */, edges);
  }

  void GetIngoingEdgesList(TVertexType const & segment, vector<TEdgeType> & edges)
  {
    GetEdgesList(segment, false /* isOutgoing */, edges);
  }

  double HeuristicCostEstimate(TVertexType const & from, TVertexType const & to)
  {
    return m_graph.GetEstimator().CalcHeuristic(GetPoint(from, true /* front */),
                                                GetPoint(to, true /* front */));
  }

  double CalcSegmentWeight(Segment const & segment) const
  {
    return m_graph.GetEstimator().CalcSegmentWeight(
        segment, m_graph.GetRoadGeometry(segment.GetMwmId(), segment.GetFeatureId()));
  }

  bool IsLeap(NumMwmId mwmId) const
  {
    return mwmId != kFakeNumMwmId && mwmId != m_start.GetMwmId() && mwmId != m_finish.GetMwmId() &&
           m_graph.GetEstimator().LeapIsAllowed(mwmId);
  }

  static bool IsFakeSegment(Segment const & segment)
  {
    return segment.GetFeatureId() == kFakeFeatureId;
  }

private:
  void GetFakeToNormalEdges(FakeVertex const & fakeVertex, bool isOutgoing,
                            vector<SegmentEdge> & edges);
  void GetFakeToNormalEdge(FakeVertex const & fakeVertex, bool forward,
                           vector<SegmentEdge> & edges);
  void GetNormalToFakeEdge(Segment const & segment, FakeVertex const & fakeVertex,
                           Segment const & fakeSegment, bool isOutgoing,
                           vector<SegmentEdge> & edges);
  /// \brief If |isOutgoing| == true fills |edges| with SegmentEdge(s) which connects
  /// |fakeVertex| with all exits of mwm.
  /// \brief If |isOutgoing| == false fills |edges| with SegmentEdge(s) which connects
  /// all enters to mwm with |fakeVertex|.
  void ConnectLeapToTransitions(Segment const & segment, bool isOutgoing,
                                vector<SegmentEdge> & edges);

  WorldGraph & m_graph;
  FakeVertex const m_start;
  FakeVertex const m_finish;
};
}  // namespace routing