| 315 | {} |
| 316 | |
| 317 | bool DecodeSegment(LinearSegment const & segment, DecodedPath & path, v2::Stats & stat) |
| 318 | { |
| 319 | LOG(LINFO, ("DecodeSegment(...) seg id:", segment.m_segmentId, ", point num:", segment.GetLRPs().size())); |
| 320 | |
| 321 | uint32_t constexpr kMaxJunctionCandidates = 10; |
| 322 | uint32_t constexpr kMaxProjectionCandidates = 5; |
| 323 | |
| 324 | path.m_segmentId.Set(segment.m_segmentId); |
| 325 | |
| 326 | auto const & points = segment.GetLRPs(); |
| 327 | CHECK_GREATER(points.size(), 1, ("A segment cannot consist of less than two points")); |
| 328 | vector<ScorePathVec> lineCandidates; |
| 329 | lineCandidates.reserve(points.size()); |
| 330 | LOG(LINFO, ("Decoding segment:", segment.m_segmentId, "with", points.size(), "points")); |
| 331 | |
| 332 | ScoreCandidatePointsGetter pointsGetter(kMaxJunctionCandidates, kMaxProjectionCandidates, m_dataSource, m_graph); |
| 333 | ScoreCandidatePathsGetter pathsGetter(pointsGetter, m_graph, m_infoGetter, stat); |
| 334 | |
| 335 | if (!pathsGetter.GetLineCandidatesForPoints(points, segment.m_source, lineCandidates)) |
| 336 | return false; |
| 337 | |
| 338 | vector<Graph::EdgeVector> resultPath; |
| 339 | ScorePathsConnector connector(m_graph, m_infoGetter, stat); |
| 340 | if (!connector.FindBestPath(points, lineCandidates, segment.m_source, resultPath)) |
| 341 | { |
| 342 | LOG(LINFO, ("Connections not found:", segment.m_segmentId)); |
| 343 | auto const mercatorPoints = segment.GetMercatorPoints(); |
| 344 | for (auto const & mercatorPoint : mercatorPoints) |
| 345 | LOG(LINFO, (mercator::ToLatLon(mercatorPoint))); |
| 346 | return false; |
| 347 | } |
| 348 | |
| 349 | Graph::EdgeVector route; |
| 350 | for (auto const & part : resultPath) |
| 351 | route.insert(route.end(), part.begin(), part.end()); |
| 352 | |
| 353 | double requiredRouteDistanceM = 0.0; |
| 354 | // Sum up all distances between points. Last point's m_distanceToNextPoint |
| 355 | // should be equal to zero, but let's skip it just in case. |
| 356 | CHECK(!points.empty(), ()); |
| 357 | for (auto it = points.begin(); it != prev(points.end()); ++it) |
| 358 | requiredRouteDistanceM += it->m_distanceToNextPoint; |
| 359 | |
| 360 | double actualRouteDistanceM = 0.0; |
| 361 | for (auto const & e : route) |
| 362 | actualRouteDistanceM += EdgeLength(e); |
| 363 | |
| 364 | auto const scale = actualRouteDistanceM / requiredRouteDistanceM; |
| 365 | LOG(LINFO, ("actualRouteDistance:", actualRouteDistanceM, "requiredRouteDistance:", requiredRouteDistanceM, |
| 366 | "scale:", scale)); |
| 367 | |
| 368 | if (segment.m_locationReference.m_positiveOffsetMeters + segment.m_locationReference.m_negativeOffsetMeters >= |
| 369 | requiredRouteDistanceM) |
| 370 | { |
| 371 | ++stat.m_wrongOffsets; |
| 372 | LOG(LINFO, ("Wrong offsets for segment:", segment.m_segmentId)); |
| 373 | return false; |
| 374 | } |
nothing calls this directly
no test coverage detected