diff --git a/routing/base/astar_algorithm.hpp b/routing/base/astar_algorithm.hpp index 9e99038f0d..344c236dce 100644 --- a/routing/base/astar_algorithm.hpp +++ b/routing/base/astar_algorithm.hpp @@ -669,7 +669,7 @@ AStarAlgorithm::FindPathBidirectional(P & params, { // Break in Debug, log in Release and safe continue: std::max(reducedWeight, kZeroDistance). LOG(LERROR, ("Invariant violated for:", "v =", stateV.vertex, "w =", stateW.vertex, - "Start =", startVertex, "End =", finalVertex)); + "reduced weight =", reducedWeight)); } stateW.distance = stateV.distance + std::max(reducedWeight, kZeroDistance); diff --git a/routing/cross_mwm_connector.hpp b/routing/cross_mwm_connector.hpp index 08f4448639..c20227df43 100644 --- a/routing/cross_mwm_connector.hpp +++ b/routing/cross_mwm_connector.hpp @@ -39,6 +39,7 @@ enum class WeightsLoadState std::string DebugPrint(WeightsLoadState state); } // namespace connector +/// @param CrossMwmId Encoded OSM feature (way) ID that should be equal and unique in all MWMs. template class CrossMwmConnector final { @@ -132,9 +133,21 @@ public: uint32_t const featureId = fIt->second; - auto const tIt = m_transitions.find(Key(featureId, segmentIdx)); + auto tIt = m_transitions.find(Key(featureId, segmentIdx)); if (tIt == m_transitions.cend()) - return nullptr; + { + /// @todo By VNG: Workaround until cross-mwm transitions generator investigation. + /// https://github.com/organicmaps/organicmaps/issues/1736 + /// Actually, the fix is valid, because transition features can have segment = 1 when leaving MWM + /// and segment = 2 when entering MWM due to *not precise* packed MWM borders. + if (isEnter) + tIt = m_transitions.find(Key(featureId, segmentIdx + 1)); + else if (segmentIdx > 0) + tIt = m_transitions.find(Key(featureId, segmentIdx - 1)); + + if (tIt == m_transitions.cend()) + return nullptr; + } auto const & transition = tIt->second; CHECK_EQUAL(transition.m_crossMwmId, crossMwmId, ("fId:", featureId, ", segId:", segmentIdx)); @@ -176,7 +189,7 @@ public: } std::vector const & GetEnters() const { return m_enters; } - std::vector const & GetExits() const { return m_exits; } + std::vector const & GetExits() const { return m_exits; } Segment const & GetEnter(size_t i) const { diff --git a/routing/index_router.cpp b/routing/index_router.cpp index 555e86cc31..6a59079120 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -825,6 +825,13 @@ RouterResultCode IndexRouter::CalculateSubrouteLeapsOnlyMode( nullptr /* prevRoute */, delegate.GetCancellable(), move(visitor), AStarLengthChecker(starter)); + params.m_badReducedWeight = [](Weight const &, Weight const &) + { + /// @see CrossMwmConnector::GetTransition comment. + /// Unfortunately, reduced weight invariant in LeapsOnly mode doesn't work with the workaround above. + return false; + }; + RoutingResult routingResult; RouterResultCode const result = FindPath(params, {} /* mwmIds */, routingResult); diff --git a/routing/routing_integration_tests/route_test.cpp b/routing/routing_integration_tests/route_test.cpp index 49b2a37233..ef8798a03c 100644 --- a/routing/routing_integration_tests/route_test.cpp +++ b/routing/routing_integration_tests/route_test.cpp @@ -591,4 +591,48 @@ namespace mercator::FromLatLon(48.7498, 30.2203), {0., 0.}, mercator::FromLatLon(46.4859, 30.6837), 265163.); } + + // https://github.com/organicmaps/organicmaps/issues/1736 + UNIT_TEST(Belgium_LiegeBrugge) + { + integration::CalculateRouteAndTestRouteLength( + integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(50.645205, 5.573507), {0., 0.}, + mercator::FromLatLon(51.208479, 3.225558), 193436.); + } + + // https://github.com/organicmaps/organicmaps/issues/1627 + UNIT_TEST(Spain_MadridSevilla) + { + integration::CalculateRouteAndTestRouteLength( + integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(40.415322, -3.703517), {0., 0.}, + mercator::FromLatLon(37.388667, -5.995355), 528667.); + } + + UNIT_TEST(Belarus_Lithuania_MinskVilnius) + { + integration::CalculateRouteAndTestRouteLength( + integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(53.902837, 27.562144), {0., 0.}, + mercator::FromLatLon(54.686821, 25.283189), 183231.); + } + + // https://github.com/organicmaps/organicmaps/issues/338 + UNIT_TEST(Russia_MendeleevoReutov) + { + integration::CalculateRouteAndTestRouteLength( + integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(56.036866, 37.232630), {0., 0.}, + mercator::FromLatLon(55.762128, 37.856665), 66261.9); + } + + // https://github.com/organicmaps/organicmaps/issues/1721 + UNIT_TEST(Austria_Croatia_SalzburgZagreb) + { + integration::CalculateRouteAndTestRouteLength( + integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(47.795928, 13.047597), {0., 0.}, + mercator::FromLatLon(45.812822, 15.977049), 414275); + } } // namespace