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

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

#include "geometry/mercator.hpp"

#include "geometry/point2d.hpp"
#include "geometry/polyline2d.hpp"

#include <vector>

namespace routing
{
class FollowedPolyline
{
public:
  FollowedPolyline() = default;
  template <class TIter>
  FollowedPolyline(TIter begin, TIter end)
    : m_poly(begin, end)
  {
    Update();
    // Initially we do not have intermediate points. Next checkpoint is finish.
    m_nextCheckpointIndex = m_segProj.size();
  }

  void SetNextCheckpointIndex(size_t index) { m_nextCheckpointIndex = index; }

  void Swap(FollowedPolyline & rhs);

  void Append(FollowedPolyline const & poly)
  {
    m_poly.Append(poly.m_poly);
    Update();
  }

  void PopBack()
  {
    m_poly.PopBack();
    Update();
  }

  bool IsValid() const { return (m_current.IsValid() && m_poly.GetSize() > 1); }
  m2::PolylineD const & GetPolyline() const { return m_poly; }

  std::vector<double> const & GetSegDistanceMeters() const { return m_segDistance; }
  double GetTotalDistanceMeters() const;
  double GetDistanceFromStartMeters() const;
  double GetDistanceToEndMeters() const;
  double GetDistFromCurPointToRoutePointMerc() const;
  double GetDistFromCurPointToRoutePointMeters() const;
  double GetMercatorDistanceFromBegin() const;

  /*! \brief Return next navigation point for direction widgets.
   *  Returns first geometry point from the polyline after your location if it is farther then
   *  toleranceM.
   */
  void GetCurrentDirectionPoint(m2::PointD & pt, double toleranceM) const;

  struct Iter
  {
    m2::PointD m_pt;
    size_t m_ind;

    static size_t constexpr kInvalidIndex = std::numeric_limits<size_t>::max();

    Iter(m2::PointD pt, size_t ind) : m_pt(pt), m_ind(ind) {}
    Iter() : m_ind(kInvalidIndex) {}
    bool IsValid() const { return m_ind != kInvalidIndex; }
  };

  const Iter GetCurrentIter() const { return m_current; }

  double GetDistanceM(Iter const & it1, Iter const & it2) const;

  Iter UpdateProjectionByPrediction(m2::RectD const & posRect, double predictDistance) const;
  Iter UpdateProjection(m2::RectD const & posRect) const;

  Iter Begin() const;
  Iter End() const;
  Iter GetIterToIndex(size_t index) const;

private:
  template <class DistanceFn>
  Iter GetClosestProjectionInInterval(m2::RectD const & posRect, DistanceFn const & distFn,
                                      size_t startIdx, size_t endIdx) const;

  /// \returns iterator to the best projection of center of |posRect| to the |m_poly|.
  /// If there's a good projection of center of |posRect| to two closest segments of |m_poly|
  /// after |m_current| the iterator corresponding of the projection is returned.
  /// Otherwise returns a projection to closest point of route.
  template <class DistanceFn>
  Iter GetBestProjection(m2::RectD const & posRect, DistanceFn const & distFn) const;

  void Update();

  m2::PolylineD m_poly;

  /// Iterator with the current position. Position sets with UpdateProjection methods.
  mutable Iter m_current;
  size_t m_nextCheckpointIndex;
  /// Precalculated info for fast projection finding.
  std::vector<m2::ProjectionToSection<m2::PointD>> m_segProj;
  /// Accumulated cache of segments length in meters.
  std::vector<double> m_segDistance;
};

}  // namespace routing