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
|
#pragma once
#include "openlr/graph.hpp"
#include "openlr/openlr_model.hpp"
#include "openlr/road_info_getter.hpp"
#include "openlr/stats.hpp"
#include "geometry/point2d.hpp"
#include <cstddef>
#include <cstdint>
#include <limits>
#include <memory>
#include <vector>
namespace openlr
{
class CandidatePointsGetter;
class CandidatePathsGetter
{
public:
CandidatePathsGetter(CandidatePointsGetter & pointsGetter, Graph & graph,
RoadInfoGetter & infoGetter, v2::Stats & stat)
: m_pointsGetter(pointsGetter), m_graph(graph), m_infoGetter(infoGetter), m_stats(stat)
{
}
bool GetLineCandidatesForPoints(std::vector<LocationReferencePoint> const & points,
std::vector<std::vector<Graph::EdgeVector>> & lineCandidates);
private:
struct Link;
using LinkPtr = std::shared_ptr<Link>;
size_t static constexpr kMaxCandidates = 5;
size_t static constexpr kMaxFakeCandidates = 2;
// TODO(mgsergio): Rename to Vertex.
struct Link
{
Link(LinkPtr const & parent, Graph::Edge const & edge, double const distanceM)
: m_parent(parent)
, m_edge(edge)
, m_distanceM(distanceM)
, m_hasFake((parent && parent->m_hasFake) || edge.IsFake())
{
}
bool IsJunctionInPath(routing::Junction const & j) const;
Graph::Edge GetStartEdge() const;
LinkPtr const m_parent;
Graph::Edge const m_edge;
double const m_distanceM;
bool const m_hasFake;
};
struct CandidatePath
{
double static constexpr kBearingDiffFactor = 5;
double static constexpr kPathDistanceFactor = 1;
double static constexpr kPointDistanceFactor = 2;
CandidatePath() = default;
CandidatePath(LinkPtr const path, uint32_t const bearingDiff, double const pathDistanceDiff,
double const startPointDistance)
: m_path(path)
, m_bearingDiff(bearingDiff)
, m_pathDistanceDiff(pathDistanceDiff)
, m_startPointDistance(startPointDistance)
{
}
bool operator<(CandidatePath const & o) const { return GetPenalty() < o.GetPenalty(); }
double GetPenalty() const
{
return kBearingDiffFactor * m_bearingDiff + kPathDistanceFactor * m_pathDistanceDiff +
kPointDistanceFactor * m_startPointDistance;
}
bool HasFakeEndings() const { return m_path && m_path->m_hasFake; }
LinkPtr m_path = nullptr;
uint32_t m_bearingDiff = std::numeric_limits<uint32_t>::max(); // Domain is roughly [0, 30]
double m_pathDistanceDiff = std::numeric_limits<double>::max(); // Domain is roughly [0, 25]
double m_startPointDistance = std::numeric_limits<double>::max(); // Domain is roughly [0, 50]
};
// Note: In all methods below if |isLastPoint| is true than algorithm should
// calculate all parameters (such as bearing, distance to next point, etc.)
// relative to the last point.
// o ----> o ----> o <---- o.
// 1 2 3 4
// ^ isLastPoint = true.
// To calculate bearing for points 1 to 3 one have to go beardist from
// previous point to the next one (eg. from 1 to 2 and from 2 to 3).
// For point 4 one have to go from 4 to 3 reversing directions. And
// distance-to-next point is taken from point 3. You can learn more in
// TomTom OpenLR spec.
void GetStartLines(std::vector<m2::PointD> const & points, bool const isLastPoint,
Graph::EdgeVector & edges);
void GetAllSuitablePaths(Graph::EdgeVector const & startLines, bool isLastPoint,
double bearDistM, FunctionalRoadClass functionalRoadClass,
FormOfWay formOfWay, std::vector<LinkPtr> & allPaths);
void GetBestCandidatePaths(std::vector<LinkPtr> const & allPaths, bool const isLastPoint,
uint32_t const requiredBearing, double const bearDistM,
m2::PointD const & startPoint,
std::vector<Graph::EdgeVector> & candidates);
void GetLineCandidates(openlr::LocationReferencePoint const & p, bool const isLastPoint,
double const distanceToNextPointM,
std::vector<m2::PointD> const & pointCandidates,
std::vector<Graph::EdgeVector> & candidates);
CandidatePointsGetter & m_pointsGetter;
Graph & m_graph;
RoadInfoGetter & m_infoGetter;
v2::Stats & m_stats;
};
} // namespace openlr
|