MCPcopy Create free account
hub / github.com/comaps/comaps / PrepareNearestPointOnTrack

Function PrepareNearestPointOnTrack

libs/transit/world_feed/feed_helpers.cpp:131–184  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

129}
130
131std::pair<size_t, bool> PrepareNearestPointOnTrack(m2::PointD const & point,
132 std::optional<m2::PointD> const & prevPoint, size_t prevIndex,
133 Direction direction, std::vector<m2::PointD> & polyline)
134{
135 // We skip 70% of the distance in a straight line between two stops for preventing incorrect
136 // projection of the |point| to the polyline of complex shape.
137 double const distStopsM = prevPoint ? mercator::DistanceOnEarth(point, *prevPoint) * 0.7 : 0.0;
138
139 std::vector<ProjectionData> projections;
140 // Reserve space for points on polyline which are relatively close to the shape.
141 // Approximately 1/4 of all points on shape.
142 auto const size = direction == Direction::Forward ? polyline.size() - prevIndex : prevIndex;
143 projections.reserve(size / 4);
144
145 auto const startIndex = direction == Direction::Forward ? prevIndex : 0;
146 auto const endIndex = direction == Direction::Forward ? polyline.size() - 1 : prevIndex;
147 FillProjections(polyline, startIndex, endIndex, point, distStopsM, direction, projections);
148
149 if (projections.empty())
150 return {polyline.size() + 1, false};
151
152 // We find the most fitting projection of the stop to the polyline. For two different projections
153 // with approximately equal distances to the stop the most preferable is the one that is closer
154 // to the beginning of the polyline segment.
155 auto const cmp = [](ProjectionData const & p1, ProjectionData const & p2)
156 {
157 if (CloserToEndingAndOnSimilarDistToLine(p1, p2))
158 return true;
159
160 if (CloserToEndingAndOnSimilarDistToLine(p2, p1))
161 return false;
162
163 if (p1.m_distFromPoint == p2.m_distFromPoint)
164 return p1.m_distFromEnding < p2.m_distFromEnding;
165
166 return p1.m_distFromPoint < p2.m_distFromPoint;
167 };
168
169 auto proj = std::min_element(projections.begin(), projections.end(), cmp);
170
171 // This case is possible not only for the first stop on the shape. We try to resolve situation
172 // when two stops are projected to the same point on the shape.
173 if (proj->m_indexOnShape == prevIndex)
174 {
175 proj = std::min_element(projections.begin(), projections.end(),
176 [](ProjectionData const & p1, ProjectionData const & p2)
177 { return p1.m_distFromPoint < p2.m_distFromPoint; });
178 }
179
180 if (proj->m_needsInsertion)
181 polyline.insert(polyline.begin() + proj->m_indexOnShape, proj->m_proj);
182
183 return {proj->m_indexOnShape, proj->m_needsInsertion};
184}
185
186bool IsRelevantType(gtfs::RouteType const & routeType)
187{

Callers 2

ProjectStopsToShapeMethod · 0.85
UNIT_TESTFunction · 0.85

Calls 9

FillProjectionsFunction · 0.85
DistanceOnEarthFunction · 0.50
sizeMethod · 0.45
reserveMethod · 0.45
emptyMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
insertMethod · 0.45

Tested by 1

UNIT_TESTFunction · 0.68