| 331 | } |
| 332 | |
| 333 | void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding) |
| 334 | { |
| 335 | Segment const dummy = Segment(); |
| 336 | |
| 337 | map<Segment, vector<LatLonWithAltitude>> otherSegments; |
| 338 | for (auto const & ending : m_otherEndings) |
| 339 | { |
| 340 | for (auto const & p : ending.m_projections) |
| 341 | { |
| 342 | otherSegments[p.m_segment].push_back(p.m_junction); |
| 343 | // We use |otherEnding| to generate proper fake edges in case both endings have projections |
| 344 | // to the same segment. Direction of p.m_segment does not matter. |
| 345 | otherSegments[p.m_segment.GetReversed()].push_back(p.m_junction); |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | // Add pure fake vertex |
| 350 | auto const fakeSegment = GetFakeSegmentAndIncr(); |
| 351 | FakeVertex fakeVertex(kFakeNumMwmId, thisEnding.m_originJunction, thisEnding.m_originJunction, |
| 352 | FakeVertex::Type::PureFake); |
| 353 | m_fake.AddStandaloneVertex(fakeSegment, fakeVertex); |
| 354 | for (bool isStart : {true, false}) |
| 355 | { |
| 356 | for (auto const & projection : thisEnding.m_projections) |
| 357 | { |
| 358 | // Add projection edges |
| 359 | auto const projectionSegment = GetFakeSegmentAndIncr(); |
| 360 | FakeVertex projectionVertex( |
| 361 | projection.m_segment.GetMwmId(), isStart ? thisEnding.m_originJunction : projection.m_junction, |
| 362 | isStart ? projection.m_junction : thisEnding.m_originJunction, FakeVertex::Type::PureFake); |
| 363 | m_fake.AddVertex(fakeSegment, projectionSegment, projectionVertex, isStart /* isOutgoing */, |
| 364 | false /* isPartOfReal */, dummy /* realSegment */); |
| 365 | |
| 366 | // Add fake parts of real |
| 367 | auto frontJunction = projection.m_segmentFront; |
| 368 | auto backJunction = projection.m_segmentBack; |
| 369 | |
| 370 | // Check whether we have projections to same real segment from both endings. |
| 371 | auto const it = otherSegments.find(projection.m_segment); |
| 372 | if (it != otherSegments.end()) |
| 373 | { |
| 374 | ASSERT(!it->second.empty(), ()); |
| 375 | |
| 376 | LatLonWithAltitude otherJunction; |
| 377 | double distBackToOther = 1.0E8; |
| 378 | for (auto const & coord : it->second) |
| 379 | { |
| 380 | double const curDist = ms::DistanceOnEarth(backJunction.GetLatLon(), coord.GetLatLon()); |
| 381 | if (curDist < distBackToOther) |
| 382 | { |
| 383 | distBackToOther = curDist; |
| 384 | otherJunction = coord; |
| 385 | } |
| 386 | } |
| 387 | |
| 388 | double const distBackToThis = ms::DistanceOnEarth(backJunction.GetLatLon(), projection.m_junction.GetLatLon()); |
| 389 | |
| 390 | if (distBackToThis < distBackToOther) |
no test coverage detected