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

Method ProcessLeapsJoints

libs/routing/index_router.cpp:1445–1623  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1443}
1444
1445RouterResultCode IndexRouter::ProcessLeapsJoints(vector<Segment> const & input, IndexGraphStarter & starter,
1446 shared_ptr<AStarProgress> const & progress,
1447 RoutesCalculator & calculator, RoutingResultT & result)
1448{
1449 LOG(LDEBUG, ("Process input:", input));
1450
1451 // { fake, mwmId1, mwmId2, mwmId2, mwmId3, .. pairs of ids .. , fake }.
1452 ASSERT_GREATER_OR_EQUAL(input.size(), 4, ());
1453 ASSERT(input.size() % 2 == 0, ());
1454
1455 WorldGraph & worldGraph = starter.GetGraph();
1456
1457 // For all leaps except the first leap which connects start to mwm exit in LeapsOnly mode we need
1458 // to drop first segment of the leap because we already have its twin from the previous mwm.
1459 bool dropFirstSegment = false;
1460
1461 // While route building in LeapOnly mode we estimate start to mwm exit distance. This estimation may
1462 // be incorrect and it causes appearance of unneeded loops: route goes from start to wrongly selected mwm exit,
1463 // then we have small unneeded leap in other mwm which returns us to start mwm, then we have leap in start mwm
1464 // to the correct start mwm exit and then we have normal route.
1465 // |input| mwm ids for such case look like
1466 // { fake, startId, otherId, otherId, startId, startId, .. pairs of ids for other leaps .. , finishId, fake }.
1467
1468 // Stable solution here is to calculate all routes with and without loops, and choose the best one.
1469 // https://github.com/organicmaps/organicmaps/issues/821
1470 // https://github.com/organicmaps/organicmaps/issues/2085
1471 // https://github.com/organicmaps/organicmaps/issues/5069
1472
1473 buffer_vector<size_t, 4> arrBeg, arrEnd;
1474 size_t const begIdx = 1;
1475 size_t const endIdx = input.size() - 2;
1476
1477 auto const firstMwmId = input[begIdx].GetMwmId();
1478 for (size_t i = begIdx; i < endIdx; ++i)
1479 if (input[i].GetMwmId() == firstMwmId && (i % 2 == 1))
1480 arrBeg.push_back(i);
1481
1482 auto const lastMwmId = input[endIdx].GetMwmId();
1483 for (size_t i = endIdx; i > begIdx; --i)
1484 if (input[i].GetMwmId() == lastMwmId && (i % 2 == 0))
1485 arrEnd.push_back(i);
1486
1487 size_t const variantsCount = arrBeg.size() * arrEnd.size();
1488 ASSERT(variantsCount > 0, ());
1489
1490 for (size_t startLeapEnd : arrBeg)
1491 for (size_t finishLeapStart : arrEnd)
1492 {
1493 size_t maxStart = 0;
1494
1495 auto const runAStarAlgorithm = [&](size_t start, size_t end, WorldGraphMode mode)
1496 {
1497 ASSERT_LESS(start, input.size(), ());
1498 ASSERT_LESS(end, input.size(), ());
1499
1500 maxStart = max(maxStart, start);
1501 auto const contribCoef = static_cast<double>(end - maxStart + 1) / input.size() / variantsCount;
1502

Callers

nothing calls this directly

Calls 15

ASSERTFunction · 0.85
CalcMethod · 0.80
sizeMethod · 0.45
GetMwmIdMethod · 0.45
push_backMethod · 0.45
SetModeMethod · 0.45
emptyMethod · 0.45
pop_backMethod · 0.45
cbeginMethod · 0.45
emplace_backMethod · 0.45
cendMethod · 0.45
GetPointMethod · 0.45

Tested by

no test coverage detected