diff options
Diffstat (limited to 'routing')
-rw-r--r-- | routing/CMakeLists.txt | 4 | ||||
-rw-r--r-- | routing/car_router.cpp | 30 | ||||
-rw-r--r-- | routing/car_router.hpp | 7 | ||||
-rw-r--r-- | routing/index_graph_starter.cpp | 3 | ||||
-rw-r--r-- | routing/index_router.cpp (renamed from routing/single_mwm_router.cpp) | 104 | ||||
-rw-r--r-- | routing/index_router.hpp (renamed from routing/single_mwm_router.hpp) | 35 | ||||
-rw-r--r-- | routing/road_graph_router.cpp | 1 | ||||
-rw-r--r-- | routing/routing.pro | 4 | ||||
-rw-r--r-- | routing/routing_integration_tests/routing_test_tools.cpp | 4 | ||||
-rw-r--r-- | routing/world_graph.cpp | 17 | ||||
-rw-r--r-- | routing/world_graph.hpp | 7 |
11 files changed, 138 insertions, 78 deletions
diff --git a/routing/CMakeLists.txt b/routing/CMakeLists.txt index d0feaee435..76d127bd05 100644 --- a/routing/CMakeLists.txt +++ b/routing/CMakeLists.txt @@ -48,6 +48,8 @@ set( index_graph_starter.hpp index_road_graph.cpp index_road_graph.hpp + index_router.cpp + index_router.hpp joint.cpp joint.hpp joint_index.cpp @@ -103,8 +105,6 @@ set( routing_session.hpp routing_settings.hpp segment.hpp - single_mwm_router.cpp - single_mwm_router.hpp speed_camera.cpp speed_camera.hpp traffic_stash.hpp diff --git a/routing/car_router.cpp b/routing/car_router.cpp index fc29851422..4b92293e28 100644 --- a/routing/car_router.cpp +++ b/routing/car_router.cpp @@ -13,6 +13,7 @@ #include "traffic/traffic_info.hpp" #include "platform/country_file.hpp" +#include "platform/mwm_traits.hpp" #include "platform/platform.hpp" #include "geometry/angles.hpp" @@ -250,7 +251,7 @@ bool CarRouter::CheckRoutingAbility(m2::PointD const & startPoint, m2::PointD co } CarRouter::CarRouter(Index & index, TCountryFileFn const & countryFileFn, - unique_ptr<SingleMwmRouter> localRouter) + unique_ptr<IndexRouter> localRouter) : m_index(index), m_indexManager(countryFileFn, index), m_router(move(localRouter)) { } @@ -400,6 +401,10 @@ CarRouter::ResultCode CarRouter::CalculateRoute(m2::PointD const & startPoint, m2::PointD const & finalPoint, RouterDelegate const & delegate, Route & route) { +// TODO uncomment this to activate cross mwm index router. +// if (AllMwmsHaveRoutingIndex()) +// return m_router->CalculateRoute(startPoint, startDirection, finalPoint, delegate, route); + my::HighResTimer timer(true); TRoutingMappingPtr startMapping = m_indexManager.GetMappingByPoint(startPoint); @@ -578,6 +583,22 @@ bool CarRouter::DoesEdgeIndexExist(Index::MwmId const & mwmId) return true; } +bool CarRouter::AllMwmsHaveRoutingIndex() const +{ + vector<shared_ptr<MwmInfo>> infos; + m_index.GetMwmsInfo(infos); + for (auto const & info : infos) + { + if (info->GetType() != MwmInfo::COUNTRY) + continue; + + if (!version::MwmTraits(info->m_version).HasRoutingIndex()) + return false; + } + + return true; +} + IRouter::ResultCode CarRouter::FindSingleRouteDispatcher(FeatureGraphNode const & source, FeatureGraphNode const & target, RouterDelegate const & delegate, @@ -599,10 +620,9 @@ IRouter::ResultCode CarRouter::FindSingleRouteDispatcher(FeatureGraphNode const } LOG(LINFO, (m_router->GetName(), "route from", MercatorBounds::ToLatLon(source.segmentPoint), "to", MercatorBounds::ToLatLon(target.segmentPoint))); - m_router->SetCountry(source.mwmId.GetInfo()->GetCountryName()); - result = m_router->CalculateRoute(source.segmentPoint, - m2::PointD(0, 0) /* direction */, target.segmentPoint, - delegate, mwmRoute); + result = m_router->CalculateRouteForSingleMwm( + source.mwmId.GetInfo()->GetCountryName(), source.segmentPoint, + m2::PointD(0, 0) /* direction */, target.segmentPoint, delegate, mwmRoute); } else { diff --git a/routing/car_router.hpp b/routing/car_router.hpp index 4a62046391..d32fc9252a 100644 --- a/routing/car_router.hpp +++ b/routing/car_router.hpp @@ -1,11 +1,11 @@ #pragma once +#include "routing/index_router.hpp" #include "routing/osrm_data_facade.hpp" #include "routing/osrm_engine.hpp" #include "routing/route.hpp" #include "routing/router.hpp" #include "routing/routing_mapping.hpp" -#include "routing/single_mwm_router.hpp" #include "std/unique_ptr.hpp" #include "std/vector.hpp" @@ -35,7 +35,7 @@ public: typedef vector<double> GeomTurnCandidateT; CarRouter(Index & index, TCountryFileFn const & countryFileFn, - unique_ptr<SingleMwmRouter> localRouter); + unique_ptr<IndexRouter> localRouter); virtual string GetName() const override; @@ -85,6 +85,7 @@ private: // @TODO(bykoianko) When routing section implementation is merged to master // this method should be moved to routing loader. bool DoesEdgeIndexExist(Index::MwmId const & mwmId); + bool AllMwmsHaveRoutingIndex() const; /*! * \brief Builds a route within one mwm using A* if edge index section is available and osrm @@ -115,6 +116,6 @@ private: RoutingIndexManager m_indexManager; - unique_ptr<SingleMwmRouter> m_router; + unique_ptr<IndexRouter> m_router; }; } // namespace routing diff --git a/routing/index_graph_starter.cpp b/routing/index_graph_starter.cpp index 8fa511e2dd..064d96bb5b 100644 --- a/routing/index_graph_starter.cpp +++ b/routing/index_graph_starter.cpp @@ -22,8 +22,7 @@ m2::PointD const & IndexGraphStarter::GetPoint(Segment const & segment, bool fro if (segment == kFinishFakeSegment || (front && m_finish.Fits(segment))) return m_finish.GetPoint(); - return m_graph.GetRoadGeometry(segment.GetMwmId(), segment.GetFeatureId()) - .GetPoint(segment.GetPointId(front)); + return m_graph.GetPoint(segment, front); } // static diff --git a/routing/single_mwm_router.cpp b/routing/index_router.cpp index afcab0dd2e..cc202f7b53 100644 --- a/routing/single_mwm_router.cpp +++ b/routing/index_router.cpp @@ -1,4 +1,4 @@ -#include "routing/single_mwm_router.hpp" +#include "routing/index_router.hpp" #include "routing/base/astar_algorithm.hpp" #include "routing/base/astar_progress.hpp" @@ -38,12 +38,11 @@ uint32_t constexpr kDrawPointsPeriod = 10; namespace routing { -SingleMwmRouter::SingleMwmRouter(string const & name, TCountryFileFn const & countryFileFn, - shared_ptr<NumMwmIds> numMwmIds, - shared_ptr<TrafficStash> trafficStash, - shared_ptr<VehicleModelFactory> vehicleModelFactory, - shared_ptr<EdgeEstimator> estimator, - unique_ptr<IDirectionsEngine> directionsEngine, Index & index) +IndexRouter::IndexRouter(string const & name, TCountryFileFn const & countryFileFn, + shared_ptr<NumMwmIds> numMwmIds, shared_ptr<TrafficStash> trafficStash, + shared_ptr<VehicleModelFactory> vehicleModelFactory, + shared_ptr<EdgeEstimator> estimator, + unique_ptr<IDirectionsEngine> directionsEngine, Index & index) : m_name(name) , m_index(index) , m_countryFileFn(countryFileFn) @@ -63,14 +62,36 @@ SingleMwmRouter::SingleMwmRouter(string const & name, TCountryFileFn const & cou CHECK(m_directionsEngine, ()); } -IRouter::ResultCode SingleMwmRouter::CalculateRoute(m2::PointD const & startPoint, - m2::PointD const & startDirection, - m2::PointD const & finalPoint, - RouterDelegate const & delegate, Route & route) +IRouter::ResultCode IndexRouter::CalculateRoute(m2::PointD const & startPoint, + m2::PointD const & startDirection, + m2::PointD const & finalPoint, + RouterDelegate const & delegate, Route & route) +{ + string const startCountry = m_countryFileFn(startPoint); + string const finishCountry = m_countryFileFn(finalPoint); + return CalculateRoute(startCountry, finishCountry, false /* blockMwmBorders */, startPoint, + startDirection, finalPoint, delegate, route); +} + +IRouter::ResultCode IndexRouter::CalculateRouteForSingleMwm( + string const & country, m2::PointD const & startPoint, m2::PointD const & startDirection, + m2::PointD const & finalPoint, RouterDelegate const & delegate, Route & route) +{ + return CalculateRoute(country, country, true /* blockMwmBorders */, startPoint, startDirection, + finalPoint, delegate, route); +} + +IRouter::ResultCode IndexRouter::CalculateRoute(string const & startCountry, + string const & finishCountry, bool blockMwmBorders, + m2::PointD const & startPoint, + m2::PointD const & startDirection, + m2::PointD const & finalPoint, + RouterDelegate const & delegate, Route & route) { try { - return DoCalculateRoute(startPoint, startDirection, finalPoint, delegate, route); + return DoCalculateRoute(startCountry, finishCountry, blockMwmBorders, startPoint, + startDirection, finalPoint, delegate, route); } catch (RootException const & e) { @@ -80,29 +101,26 @@ IRouter::ResultCode SingleMwmRouter::CalculateRoute(m2::PointD const & startPoin } } -IRouter::ResultCode SingleMwmRouter::DoCalculateRoute(m2::PointD const & startPoint, - m2::PointD const & /* startDirection */, - m2::PointD const & finalPoint, - RouterDelegate const & delegate, - Route & route) +IRouter::ResultCode IndexRouter::DoCalculateRoute( + string const & startCountry, string const & finishCountry, bool blockMwmBorders, + m2::PointD const & startPoint, m2::PointD const & /* startDirection */, + m2::PointD const & finalPoint, RouterDelegate const & delegate, Route & route) { - // TODO: remove field m_country. - // Use m_countryFileFn(startPoint), m_countryFileFn(finalPoint) here. - auto const startCountry = platform::CountryFile(m_country); - auto const finishCountry = platform::CountryFile(m_country); + auto const startFile = platform::CountryFile(startCountry); + auto const finishFile = platform::CountryFile(finishCountry); Edge startEdge; - if (!FindClosestEdge(startCountry, startPoint, startEdge)) + if (!FindClosestEdge(startFile, startPoint, startEdge)) return IRouter::StartPointNotFound; Edge finishEdge; - if (!FindClosestEdge(finishCountry, finalPoint, finishEdge)) + if (!FindClosestEdge(finishFile, finalPoint, finishEdge)) return IRouter::EndPointNotFound; - IndexGraphStarter::FakeVertex const start(m_numMwmIds->GetId(startCountry), + IndexGraphStarter::FakeVertex const start(m_numMwmIds->GetId(startFile), startEdge.GetFeatureId().m_index, startEdge.GetSegId(), startPoint); - IndexGraphStarter::FakeVertex const finish(m_numMwmIds->GetId(finishCountry), + IndexGraphStarter::FakeVertex const finish(m_numMwmIds->GetId(finishFile), finishEdge.GetFeatureId().m_index, finishEdge.GetSegId(), finalPoint); @@ -112,8 +130,8 @@ IRouter::ResultCode SingleMwmRouter::DoCalculateRoute(m2::PointD const & startPo IndexGraphLoader::Create(m_numMwmIds, m_vehicleModelFactory, m_estimator, m_index), m_estimator); - // TODO remove to activate CrossMwmGraph. - graph.BlockMwmBorders(); + if (blockMwmBorders) + graph.CloseBorders(); IndexGraphStarter starter(start, finish, graph); @@ -160,8 +178,8 @@ IRouter::ResultCode SingleMwmRouter::DoCalculateRoute(m2::PointD const & startPo } } -bool SingleMwmRouter::FindClosestEdge(platform::CountryFile const & file, m2::PointD const & point, - Edge & closestEdge) const +bool IndexRouter::FindClosestEdge(platform::CountryFile const & file, m2::PointD const & point, + Edge & closestEdge) const { MwmSet::MwmHandle handle = m_index.GetMwmHandleByCountryFile(file); if (!handle.IsAlive()) @@ -198,15 +216,14 @@ bool SingleMwmRouter::FindClosestEdge(platform::CountryFile const & file, m2::Po return true; } -IRouter::ResultCode SingleMwmRouter::ProcessLeaps(vector<Segment> const & input, - RouterDelegate const & delegate, - IndexGraphStarter & starter, - vector<Segment> & output) +IRouter::ResultCode IndexRouter::ProcessLeaps(vector<Segment> const & input, + RouterDelegate const & delegate, + IndexGraphStarter & starter, vector<Segment> & output) { output.reserve(input.size()); WorldGraph & worldGraph = starter.GetGraph(); - worldGraph.BlockMwmBorders(); + worldGraph.CloseBorders(); for (size_t i = 0; i < input.size(); ++i) { @@ -252,9 +269,8 @@ IRouter::ResultCode SingleMwmRouter::ProcessLeaps(vector<Segment> const & input, return IRouter::NoError; } -bool SingleMwmRouter::RedressRoute(vector<Segment> const & segments, - RouterDelegate const & delegate, IndexGraphStarter & starter, - Route & route) const +bool IndexRouter::RedressRoute(vector<Segment> const & segments, RouterDelegate const & delegate, + IndexGraphStarter & starter, Route & route) const { vector<Junction> junctions; size_t const numPoints = IndexGraphStarter::GetRouteNumPoints(segments); @@ -267,6 +283,7 @@ bool SingleMwmRouter::RedressRoute(vector<Segment> const & segments, } IndexRoadGraph roadGraph(m_numMwmIds, starter, segments, junctions, m_index); + starter.GetGraph().OpenBorders(); CHECK(m_directionsEngine, ()); ReconstructRoute(*m_directionsEngine, roadGraph, m_trafficStash, delegate, junctions, route); @@ -293,9 +310,10 @@ bool SingleMwmRouter::RedressRoute(vector<Segment> const & segments, } // static -unique_ptr<SingleMwmRouter> SingleMwmRouter::CreateCarRouter( - TCountryFileFn const & countryFileFn, shared_ptr<NumMwmIds> numMwmIds, - traffic::TrafficCache const & trafficCache, Index & index) +unique_ptr<IndexRouter> IndexRouter::CreateCarRouter(TCountryFileFn const & countryFileFn, + shared_ptr<NumMwmIds> numMwmIds, + traffic::TrafficCache const & trafficCache, + Index & index) { CHECK(numMwmIds, ()); auto vehicleModelFactory = make_shared<CarModelFactory>(); @@ -314,9 +332,9 @@ unique_ptr<SingleMwmRouter> SingleMwmRouter::CreateCarRouter( auto trafficStash = make_shared<TrafficStash>(trafficCache, numMwmIds); auto estimator = EdgeEstimator::CreateForCar(trafficStash, maxSpeed); - auto router = make_unique<SingleMwmRouter>("astar-bidirectional-car", countryFileFn, numMwmIds, - trafficStash, vehicleModelFactory, estimator, - move(directionsEngine), index); + auto router = + make_unique<IndexRouter>("astar-bidirectional-car", countryFileFn, numMwmIds, trafficStash, + vehicleModelFactory, estimator, move(directionsEngine), index); return router; } } // namespace routing diff --git a/routing/single_mwm_router.hpp b/routing/index_router.hpp index e815d4e0bc..63dc2c193a 100644 --- a/routing/single_mwm_router.hpp +++ b/routing/index_router.hpp @@ -22,14 +22,14 @@ namespace routing class IndexGraph; class IndexGraphStarter; -class SingleMwmRouter : public IRouter +class IndexRouter : public IRouter { public: - SingleMwmRouter(string const & name, TCountryFileFn const & countryFileFn, - shared_ptr<NumMwmIds> numMwmIds, shared_ptr<TrafficStash> trafficStash, - shared_ptr<VehicleModelFactory> vehicleModelFactory, - shared_ptr<EdgeEstimator> estimator, - unique_ptr<IDirectionsEngine> directionsEngine, Index & index); + IndexRouter(string const & name, TCountryFileFn const & countryFileFn, + shared_ptr<NumMwmIds> numMwmIds, shared_ptr<TrafficStash> trafficStash, + shared_ptr<VehicleModelFactory> vehicleModelFactory, + shared_ptr<EdgeEstimator> estimator, unique_ptr<IDirectionsEngine> directionsEngine, + Index & index); // IRouter overrides: virtual string GetName() const override { return m_name; } @@ -39,16 +39,26 @@ public: RouterDelegate const & delegate, Route & route) override; - void SetCountry(string const & country) { m_country = country; } + IRouter::ResultCode CalculateRouteForSingleMwm(string const & country, + m2::PointD const & startPoint, + m2::PointD const & startDirection, + m2::PointD const & finalPoint, + RouterDelegate const & delegate, Route & route); /// \note |numMwmIds| should not be null. - static unique_ptr<SingleMwmRouter> CreateCarRouter(TCountryFileFn const & countryFileFn, - shared_ptr<NumMwmIds> numMwmIds, - traffic::TrafficCache const & trafficCache, - Index & index); + static unique_ptr<IndexRouter> CreateCarRouter(TCountryFileFn const & countryFileFn, + shared_ptr<NumMwmIds> numMwmIds, + traffic::TrafficCache const & trafficCache, + Index & index); private: - IRouter::ResultCode DoCalculateRoute(m2::PointD const & startPoint, + IRouter::ResultCode CalculateRoute(string const & startCountry, string const & finishCountry, + bool blockMwmBorders, m2::PointD const & startPoint, + m2::PointD const & startDirection, + m2::PointD const & finalPoint, RouterDelegate const & delegate, + Route & route); + IRouter::ResultCode DoCalculateRoute(string const & startCountry, string const & finishCountry, + bool blockMwmBorders, m2::PointD const & startPoint, m2::PointD const & startDirection, m2::PointD const & finalPoint, RouterDelegate const & delegate, Route & route); @@ -62,7 +72,6 @@ private: IndexGraphStarter & starter, Route & route) const; string const m_name; - string m_country; Index & m_index; TCountryFileFn const m_countryFileFn; shared_ptr<NumMwmIds> m_numMwmIds; diff --git a/routing/road_graph_router.cpp b/routing/road_graph_router.cpp index a93d33177a..95b7fa4a64 100644 --- a/routing/road_graph_router.cpp +++ b/routing/road_graph_router.cpp @@ -9,7 +9,6 @@ #include "routing/pedestrian_model.hpp" #include "routing/route.hpp" #include "routing/routing_helpers.hpp" -#include "routing/single_mwm_router.hpp" #include "coding/reader_wrapper.hpp" diff --git a/routing/routing.pro b/routing/routing.pro index 46a7f5a1cb..ce480092d2 100644 --- a/routing/routing.pro +++ b/routing/routing.pro @@ -32,6 +32,7 @@ SOURCES += \ index_graph_serialization.cpp \ index_graph_starter.cpp \ index_road_graph.cpp \ + index_router.cpp \ joint.cpp \ joint_index.cpp \ nearest_edge_finder.cpp \ @@ -55,7 +56,6 @@ SOURCES += \ routing_helpers.cpp \ routing_mapping.cpp \ routing_session.cpp \ - single_mwm_router.cpp \ speed_camera.cpp \ turns.cpp \ turns_generator.cpp \ @@ -87,6 +87,7 @@ HEADERS += \ index_graph_serialization.hpp \ index_graph_starter.hpp \ index_road_graph.hpp \ + index_router.hpp \ joint.hpp \ joint_index.hpp \ loaded_path_segment.hpp \ @@ -119,7 +120,6 @@ HEADERS += \ routing_session.hpp \ routing_settings.hpp \ segment.hpp \ - single_mwm_router.hpp \ speed_camera.hpp \ traffic_stash.hpp \ turn_candidate.hpp \ diff --git a/routing/routing_integration_tests/routing_test_tools.cpp b/routing/routing_integration_tests/routing_test_tools.cpp index 52c8495604..45c7ec0fa6 100644 --- a/routing/routing_integration_tests/routing_test_tools.cpp +++ b/routing/routing_integration_tests/routing_test_tools.cpp @@ -9,12 +9,12 @@ #include "geometry/distance_on_sphere.hpp" #include "geometry/latlon.hpp" +#include "routing/index_router.hpp" #include "routing/online_absent_fetcher.hpp" #include "routing/online_cross_fetcher.hpp" #include "routing/road_graph_router.hpp" #include "routing/route.hpp" #include "routing/router_delegate.hpp" -#include "routing/single_mwm_router.hpp" #include "indexer/index.hpp" @@ -91,7 +91,7 @@ namespace integration numMwmIds->RegisterFile(f.GetCountryFile()); auto carRouter = make_unique<CarRouter>(index, countryFileGetter, - SingleMwmRouter::CreateCarRouter(countryFileGetter, numMwmIds, + IndexRouter::CreateCarRouter(countryFileGetter, numMwmIds, trafficCache, index)); return carRouter; } diff --git a/routing/world_graph.cpp b/routing/world_graph.cpp index 2d38d49e8c..0546699eb6 100644 --- a/routing/world_graph.cpp +++ b/routing/world_graph.cpp @@ -15,7 +15,7 @@ WorldGraph::WorldGraph(unique_ptr<CrossMwmIndexGraph> crossMwmGraph, void WorldGraph::GetEdgeList(Segment const & segment, bool isOutgoing, bool isLeap, vector<SegmentEdge> & edges) { - if (m_crossMwmGraph && isLeap) + if (m_crossMwmGraph && m_bordersAreOpened && isLeap) { if (m_crossMwmGraph->IsTransition(segment, isOutgoing)) GetTwins(segment, isOutgoing, edges); @@ -27,10 +27,16 @@ void WorldGraph::GetEdgeList(Segment const & segment, bool isOutgoing, bool isLe IndexGraph & indexGraph = GetIndexGraph(segment.GetMwmId()); indexGraph.GetEdgeList(segment, isOutgoing, edges); - if (m_crossMwmGraph && m_crossMwmGraph->IsTransition(segment, isOutgoing)) + if (m_crossMwmGraph && m_bordersAreOpened && m_crossMwmGraph->IsTransition(segment, isOutgoing)) GetTwins(segment, isOutgoing, edges); } +m2::PointD const & WorldGraph::GetPoint(Segment const & segment, bool front) +{ + return GetRoadGeometry(segment.GetMwmId(), segment.GetFeatureId()) + .GetPoint(segment.GetPointId(front)); +} + RoadGeometry const & WorldGraph::GetRoadGeometry(NumMwmId mwmId, uint32_t featureId) { return GetIndexGraph(mwmId).GetGeometry().GetRoad(featureId); @@ -41,6 +47,11 @@ void WorldGraph::GetTwins(Segment const & segment, bool isOutgoing, vector<Segme m_twins.clear(); m_crossMwmGraph->GetTwins(segment, isOutgoing, m_twins); for (Segment const & twin : m_twins) - edges.emplace_back(twin, 0.0 /* weight */); + { + m2::PointD const & from = GetPoint(segment, true /* front */); + m2::PointD const & to = GetPoint(twin, true /* front */); + double const weight = m_estimator->CalcHeuristic(from, to); + edges.emplace_back(twin, weight); + } } } // namespace routing diff --git a/routing/world_graph.hpp b/routing/world_graph.hpp index ef40180b9e..9ff880111b 100644 --- a/routing/world_graph.hpp +++ b/routing/world_graph.hpp @@ -25,11 +25,13 @@ public: IndexGraph & GetIndexGraph(NumMwmId numMwmId) { return m_loader->GetIndexGraph(numMwmId); } EdgeEstimator const & GetEstimator() const { return *m_estimator; } + m2::PointD const & GetPoint(Segment const & segment, bool front); RoadGeometry const & GetRoadGeometry(NumMwmId mwmId, uint32_t featureId); // Disable edges between mwms. - // Unblocking is not implemented due to YAGNI principle. - void BlockMwmBorders() { m_crossMwmGraph = nullptr; } + void CloseBorders() { m_bordersAreOpened = false; } + // Enable edges between mwms. + void OpenBorders() { m_bordersAreOpened = true; } // Clear memory used by loaded index graphs. void ClearIndexGraphs() { m_loader->Clear(); } @@ -40,5 +42,6 @@ private: std::unique_ptr<IndexGraphLoader> m_loader; std::shared_ptr<EdgeEstimator> m_estimator; std::vector<Segment> m_twins; + bool m_bordersAreOpened = true; }; } // namespace routing |