From e6852907319b32e5dde5e0a4361a096ecc5066ee Mon Sep 17 00:00:00 2001 From: melonSkin76 Date: Tue, 26 Jul 2022 09:36:29 -0500 Subject: [PATCH 1/6] Prototype for quantified avoiding options same as title --- routing/edge_estimator.cpp | 16 ++++++++++++++++ routing/edge_estimator.hpp | 5 +++++ routing/index_graph.cpp | 10 ++++++---- routing/routing_options.cpp | 2 +- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index ca15a3dfb6..66cbaeaa3c 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -4,6 +4,7 @@ #include "routing/latlon_with_altitude.hpp" #include "routing/routing_exceptions.hpp" #include "routing/routing_helpers.hpp" +#include "routing/routing_options.hpp" #include "routing/traffic_stash.hpp" #include "traffic/speed_groups.hpp" @@ -209,6 +210,16 @@ double EdgeEstimator::CalcOffroad(ms::LatLon const & from, ms::LatLon const & to return TimeBetweenSec(from, to, KmphToMps(offroadSpeedKMpH)); } +RoutingOptions EdgeEstimator::GetAvoidRoutingOptions() const +{ + return m_avoidRoutingOptions; +} + +void EdgeEstimator::SetAvoidRoutingOptions(RoutingOptions avoidRoutingOptions) +{ + m_avoidRoutingOptions = avoidRoutingOptions; +} + // PedestrianEstimator ----------------------------------------------------------------------------- class PedestrianEstimator final : public EdgeEstimator { @@ -315,6 +326,11 @@ double CarEstimator::CalcSegmentWeight(Segment const & segment, RoadGeometry con { double result = CalcClimbSegment(purpose, segment, road, GetCarClimbPenalty); + if (!road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions())) + { + result += (24 * 60 * 60); + } + if (m_trafficStash) { SpeedGroup const speedGroup = m_trafficStash->GetSpeedGroup(segment); diff --git a/routing/edge_estimator.hpp b/routing/edge_estimator.hpp index f7c36d4aa2..6426a4b38f 100644 --- a/routing/edge_estimator.hpp +++ b/routing/edge_estimator.hpp @@ -1,5 +1,6 @@ #pragma once +#include "routing/routing_options.hpp" #include "routing/segment.hpp" #include "routing/vehicle_mask.hpp" @@ -46,6 +47,9 @@ public: // Estimates time in seconds it takes to go from point |from| to point |to| along direct fake edge. double CalcOffroad(ms::LatLon const & from, ms::LatLon const & to, Purpose purpose) const; + RoutingOptions GetAvoidRoutingOptions() const; + void SetAvoidRoutingOptions(RoutingOptions avoidRoutingOptions); + virtual double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const = 0; virtual double GetUTurnPenalty(Purpose purpose) const = 0; @@ -66,6 +70,7 @@ public: private: double const m_maxWeightSpeedMpS; SpeedKMpH const m_offroadSpeedKMpH; + RoutingOptions m_avoidRoutingOptions; //DataSource * m_dataSourcePtr; //std::shared_ptr m_numMwmIds; diff --git a/routing/index_graph.cpp b/routing/index_graph.cpp index 399b1d07f8..7f5a53e821 100644 --- a/routing/index_graph.cpp +++ b/routing/index_graph.cpp @@ -254,8 +254,8 @@ void IndexGraph::GetNeighboringEdges(astar::VertexData con if (!road.IsValid()) return; - if (useRoutingOptions && !road.SuitableForOptions(m_avoidRoutingOptions)) - return; +// if (useRoutingOptions && !road.SuitableForOptions(m_avoidRoutingOptions)) +// return; bool const bidirectional = !road.IsOneWay(); auto const & from = fromVertexData.m_vertex; @@ -282,8 +282,8 @@ void IndexGraph::GetSegmentCandidateForRoadPoint(RoadPoint const & rp, NumMwmId if (!road.IsValid()) return; - if (!road.SuitableForOptions(m_avoidRoutingOptions)) - return; +// if (!road.SuitableForOptions(m_avoidRoutingOptions)) +// return; bool const bidirectional = !road.IsOneWay(); auto const pointId = rp.GetPointId(); @@ -556,6 +556,8 @@ RouteWeight IndexGraph::CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool auto const & segment = isOutgoing ? to : from; auto const & road = GetRoadGeometry(segment.GetFeatureId()); + m_estimator->SetAvoidRoutingOptions(this->m_avoidRoutingOptions); + auto const weight = RouteWeight(m_estimator->CalcSegmentWeight(segment, road, purpose)); auto const penalties = GetPenalties(purpose, isOutgoing ? from : to, isOutgoing ? to : from, prevWeight); diff --git a/routing/routing_options.cpp b/routing/routing_options.cpp index 8a7f144a53..e2f7db6e1f 100644 --- a/routing/routing_options.cpp +++ b/routing/routing_options.cpp @@ -28,7 +28,7 @@ RoutingOptions RoutingOptions::LoadCarOptionsFromSettings() { uint32_t mode = 0; if (!settings::Get(kAvoidRoutingOptionSettingsForCar, mode)) - mode = 0; + mode = 2; return RoutingOptions(base::checked_cast(mode)); } -- 2.45.3 From d224a441c513085927ceacfdd4ee5ca4a4cf9a95 Mon Sep 17 00:00:00 2001 From: melonSkin76 Date: Wed, 27 Jul 2022 23:55:52 -0500 Subject: [PATCH 2/6] Some Improvements to the Previous Modifications 1. Changed the indent to 2 spaces 2. Moved the instantiations of RoutingOptions member variable of EdgeEstimator to its constructor, so we no longer need to create a new RoutingOptions object before each CalcSegmentWeight() call 3. Added the similar mechanisms to BicycleEstimator and PedestrianEstimator --- routing/edge_estimator.cpp | 26 +++++++++++++++++++++----- routing/edge_estimator.hpp | 2 +- routing/index_graph.cpp | 2 +- routing/routing_options.cpp | 7 ++++++- routing/routing_options.hpp | 1 + 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index 66cbaeaa3c..20f53bb856 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -132,6 +132,8 @@ EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroa if (m_offroadSpeedKMpH.m_eta != kNotUsed) CHECK_GREATER_OR_EQUAL(m_maxWeightSpeedMpS, KmphToMps(m_offroadSpeedKMpH.m_eta), ()); + + m_avoidRoutingOptions = RoutingOptions(); } double EdgeEstimator::CalcHeuristic(ms::LatLon const & from, ms::LatLon const & to) const @@ -212,12 +214,12 @@ double EdgeEstimator::CalcOffroad(ms::LatLon const & from, ms::LatLon const & to RoutingOptions EdgeEstimator::GetAvoidRoutingOptions() const { - return m_avoidRoutingOptions; + return m_avoidRoutingOptions; } -void EdgeEstimator::SetAvoidRoutingOptions(RoutingOptions avoidRoutingOptions) +void EdgeEstimator::SetAvoidRoutingOptions(RoutingOptions::RoadType options) { - m_avoidRoutingOptions = avoidRoutingOptions; + m_avoidRoutingOptions.SetOptions(options); } // PedestrianEstimator ----------------------------------------------------------------------------- @@ -245,7 +247,14 @@ public: double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override { - return CalcClimbSegment(purpose, segment, road, GetPedestrianClimbPenalty); + double result = CalcClimbSegment(purpose, segment, road, GetPedestrianClimbPenalty); + + if (!road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions())) + { + result += (24 * 60 * 60); + } + + return result; } }; @@ -274,7 +283,14 @@ public: double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override { - return CalcClimbSegment(purpose, segment, road, GetBicycleClimbPenalty); + double result = CalcClimbSegment(purpose, segment, road, GetBicycleClimbPenalty); + + if (!road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions())) + { + result += (24 * 60 * 60); + } + + return result; } }; diff --git a/routing/edge_estimator.hpp b/routing/edge_estimator.hpp index 6426a4b38f..1d1203061b 100644 --- a/routing/edge_estimator.hpp +++ b/routing/edge_estimator.hpp @@ -48,7 +48,7 @@ public: double CalcOffroad(ms::LatLon const & from, ms::LatLon const & to, Purpose purpose) const; RoutingOptions GetAvoidRoutingOptions() const; - void SetAvoidRoutingOptions(RoutingOptions avoidRoutingOptions); + void SetAvoidRoutingOptions(RoutingOptions::RoadType options); virtual double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const = 0; diff --git a/routing/index_graph.cpp b/routing/index_graph.cpp index 7f5a53e821..875fb05bf3 100644 --- a/routing/index_graph.cpp +++ b/routing/index_graph.cpp @@ -556,7 +556,7 @@ RouteWeight IndexGraph::CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool auto const & segment = isOutgoing ? to : from; auto const & road = GetRoadGeometry(segment.GetFeatureId()); - m_estimator->SetAvoidRoutingOptions(this->m_avoidRoutingOptions); + m_estimator->SetAvoidRoutingOptions(this->m_avoidRoutingOptions.GetOptions()); auto const weight = RouteWeight(m_estimator->CalcSegmentWeight(segment, road, purpose)); auto const penalties = GetPenalties(purpose, isOutgoing ? from : to, isOutgoing ? to : from, prevWeight); diff --git a/routing/routing_options.cpp b/routing/routing_options.cpp index e2f7db6e1f..03ae20d6e6 100644 --- a/routing/routing_options.cpp +++ b/routing/routing_options.cpp @@ -28,7 +28,7 @@ RoutingOptions RoutingOptions::LoadCarOptionsFromSettings() { uint32_t mode = 0; if (!settings::Get(kAvoidRoutingOptionSettingsForCar, mode)) - mode = 2; + mode = 4; return RoutingOptions(base::checked_cast(mode)); } @@ -55,6 +55,11 @@ bool RoutingOptions::Has(RoutingOptions::Road type) const return (m_options & static_cast(type)) != 0; } +void RoutingOptions::SetOptions(RoadType options) +{ + m_options = options; +} + // RoutingOptionsClassifier --------------------------------------------------------------------------- RoutingOptionsClassifier::RoutingOptionsClassifier() diff --git a/routing/routing_options.hpp b/routing/routing_options.hpp index 0b3faedca6..abef2498f0 100644 --- a/routing/routing_options.hpp +++ b/routing/routing_options.hpp @@ -36,6 +36,7 @@ public: bool Has(Road type) const; RoadType GetOptions() const { return m_options; } + void SetOptions(RoadType options); private: RoadType m_options = 0; -- 2.45.3 From 98a25d981296f53849635ddb06557b2ff6a4573b Mon Sep 17 00:00:00 2001 From: melonSkin76 Date: Wed, 31 Aug 2022 10:02:48 -0500 Subject: [PATCH 3/6] Avoid Options Optimized and Adding the Strategy Feature 1. Moved the routing option setting to the asynchronous router 2. Developed the strategy feature for edge estimator and index graph 3. Finished implemented the shortest path strategy 4. Additionally separated the extra weights of avoid options from ETA calculations --- data/route_points.dat | 1 + routing/async_router.cpp | 6 +++++ routing/edge_estimator.cpp | 48 +++++++++++++++++++++++++++---------- routing/edge_estimator.hpp | 10 ++++++++ routing/index_graph.cpp | 8 ++++++- routing/index_router.cpp | 4 ++++ routing/index_router.hpp | 5 ++++ routing/router.hpp | 6 +++++ routing/routing_options.cpp | 2 +- 9 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 data/route_points.dat diff --git a/data/route_points.dat b/data/route_points.dat new file mode 100644 index 0000000000..f34fcc6510 --- /dev/null +++ b/data/route_points.dat @@ -0,0 +1 @@ +[{"type":0,"title":"","subtitle":"","x":114.25822345504994,"y":22.903850160103033},{"type":2,"title":"","subtitle":"","x":114.25066146448764,"y":22.848765080380442}] \ No newline at end of file diff --git a/routing/async_router.cpp b/routing/async_router.cpp index 8eb79b5ea2..d9f24e3f23 100644 --- a/routing/async_router.cpp +++ b/routing/async_router.cpp @@ -1,4 +1,5 @@ #include "routing/async_router.hpp" +#include "routing/routing_options.hpp" #include "geometry/mercator.hpp" @@ -344,6 +345,11 @@ void AsyncRouter::CalculateRoute() if (absentRegionsFinder) absentRegionsFinder->GenerateAbsentRegions(checkpoints, delegateProxy->GetDelegate()); + RoutingOptions const routingOptions = RoutingOptions::LoadCarOptionsFromSettings(); + router->SetEstimatorOptions(routingOptions.GetOptions()); + + router->SetEstimatorStrategy(EdgeEstimator::Strategy::Shortest); + // Run basic request. code = router->CalculateRoute(checkpoints, startDirection, adjustToPrevRoute, delegateProxy->GetDelegate(), *route); diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index 20f53bb856..385d07ae8b 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -51,19 +51,23 @@ double CalcTrafficFactor(SpeedGroup speedGroup) template double CalcClimbSegment(EdgeEstimator::Purpose purpose, Segment const & segment, - RoadGeometry const & road, GetClimbPenalty && getClimbPenalty) + RoadGeometry const & road, GetClimbPenalty && getClimbPenalty, EdgeEstimator::Strategy strategy) { LatLonWithAltitude const & from = road.GetJunction(segment.GetPointId(false /* front */)); LatLonWithAltitude const & to = road.GetJunction(segment.GetPointId(true /* front */)); SpeedKMpH const & speed = road.GetSpeed(segment.IsForward()); double const distance = road.GetDistance(segment.GetSegmentIdx()); - double const speedMpS = + double speedMpS = KmphToMps(purpose == EdgeEstimator::Purpose::Weight ? speed.m_weight : speed.m_eta); + if (strategy == EdgeEstimator::Strategy::Shortest && purpose == EdgeEstimator::Purpose::Weight) + { + speedMpS = 1.0; + } CHECK_GREATER(speedMpS, 0.0, ("from:", from.GetLatLon(), "to:", to.GetLatLon(), "speed:", speed)); double const timeSec = distance / speedMpS; - if (base::AlmostEqualAbs(distance, 0.0, 0.1)) + if (base::AlmostEqualAbs(distance, 0.0, 0.1) || strategy == EdgeEstimator::Strategy::Shortest) return timeSec; double const altitudeDiff = @@ -134,6 +138,7 @@ EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroa CHECK_GREATER_OR_EQUAL(m_maxWeightSpeedMpS, KmphToMps(m_offroadSpeedKMpH.m_eta), ()); m_avoidRoutingOptions = RoutingOptions(); + m_strategy = EdgeEstimator::Strategy::Fastest; } double EdgeEstimator::CalcHeuristic(ms::LatLon const & from, ms::LatLon const & to) const @@ -222,6 +227,16 @@ void EdgeEstimator::SetAvoidRoutingOptions(RoutingOptions::RoadType options) m_avoidRoutingOptions.SetOptions(options); } +EdgeEstimator::Strategy EdgeEstimator::GetStrategy() const +{ + return m_strategy; +} + +void EdgeEstimator::SetStrategy(EdgeEstimator::Strategy strategy) +{ + m_strategy = strategy; +} + // PedestrianEstimator ----------------------------------------------------------------------------- class PedestrianEstimator final : public EdgeEstimator { @@ -247,11 +262,14 @@ public: double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override { - double result = CalcClimbSegment(purpose, segment, road, GetPedestrianClimbPenalty); + double result = CalcClimbSegment(purpose, segment, road, GetPedestrianClimbPenalty, this->GetStrategy()); - if (!road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions())) + if (purpose == EdgeEstimator::Purpose::Weight) { - result += (24 * 60 * 60); + if (!road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions())) + { + result += (24 * 60 * 60); + } } return result; @@ -283,11 +301,14 @@ public: double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override { - double result = CalcClimbSegment(purpose, segment, road, GetBicycleClimbPenalty); + double result = CalcClimbSegment(purpose, segment, road, GetBicycleClimbPenalty, this->GetStrategy()); - if (!road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions())) + if (purpose == EdgeEstimator::Purpose::Weight) { - result += (24 * 60 * 60); + if (!road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions())) + { + result += (24 * 60 * 60); + } } return result; @@ -340,11 +361,14 @@ double CarEstimator::GetFerryLandingPenalty(Purpose purpose) const double CarEstimator::CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const { - double result = CalcClimbSegment(purpose, segment, road, GetCarClimbPenalty); + double result = CalcClimbSegment(purpose, segment, road, GetCarClimbPenalty, this->GetStrategy()); - if (!road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions())) + if (purpose == EdgeEstimator::Purpose::Weight) { - result += (24 * 60 * 60); + if (!road.SuitableForOptions(EdgeEstimator::GetAvoidRoutingOptions())) + { + result += (24 * 60 * 60); + } } if (m_trafficStash) diff --git a/routing/edge_estimator.hpp b/routing/edge_estimator.hpp index 1d1203061b..4bdb9626f6 100644 --- a/routing/edge_estimator.hpp +++ b/routing/edge_estimator.hpp @@ -29,6 +29,12 @@ public: ETA }; + enum class Strategy + { + Fastest, + Shortest + }; + EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH, DataSource * dataSourcePtr = nullptr, std::shared_ptr numMwmIds = nullptr); virtual ~EdgeEstimator() = default; @@ -50,6 +56,9 @@ public: RoutingOptions GetAvoidRoutingOptions() const; void SetAvoidRoutingOptions(RoutingOptions::RoadType options); + Strategy GetStrategy() const; + void SetStrategy(Strategy strategy); + virtual double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const = 0; virtual double GetUTurnPenalty(Purpose purpose) const = 0; @@ -71,6 +80,7 @@ private: double const m_maxWeightSpeedMpS; SpeedKMpH const m_offroadSpeedKMpH; RoutingOptions m_avoidRoutingOptions; + Strategy m_strategy; //DataSource * m_dataSourcePtr; //std::shared_ptr m_numMwmIds; diff --git a/routing/index_graph.cpp b/routing/index_graph.cpp index 875fb05bf3..d5952f676f 100644 --- a/routing/index_graph.cpp +++ b/routing/index_graph.cpp @@ -556,9 +556,15 @@ RouteWeight IndexGraph::CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool auto const & segment = isOutgoing ? to : from; auto const & road = GetRoadGeometry(segment.GetFeatureId()); - m_estimator->SetAvoidRoutingOptions(this->m_avoidRoutingOptions.GetOptions()); +// m_estimator->SetAvoidRoutingOptions(this->m_avoidRoutingOptions.GetOptions()); auto const weight = RouteWeight(m_estimator->CalcSegmentWeight(segment, road, purpose)); + + if(m_estimator->GetStrategy() == EdgeEstimator::Strategy::Shortest) + { + return weight; + } + auto const penalties = GetPenalties(purpose, isOutgoing ? from : to, isOutgoing ? to : from, prevWeight); return weight + penalties; diff --git a/routing/index_router.cpp b/routing/index_router.cpp index 8394252dd2..0e2606058d 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -326,6 +326,10 @@ bool IndexRouter::FindClosestProjectionToRoad(m2::PointD const & point, return true; } +void IndexRouter::SetEstimatorOptions(RoutingOptions::RoadType options) {m_estimator ->SetAvoidRoutingOptions(options);} + +void IndexRouter::SetEstimatorStrategy(EdgeEstimator::Strategy strategy) {m_estimator ->SetStrategy(strategy);} + void IndexRouter::SetGuides(GuidesTracks && guides) { m_guides = GuidesConnections(guides); } RouterResultCode IndexRouter::CalculateRoute(Checkpoints const & checkpoints, diff --git a/routing/index_router.hpp b/routing/index_router.hpp index 6590854f9a..47c78fedb3 100644 --- a/routing/index_router.hpp +++ b/routing/index_router.hpp @@ -14,6 +14,7 @@ #include "routing/regions_decl.hpp" #include "routing/router.hpp" #include "routing/routing_callbacks.hpp" +#include "routing/routing_options.hpp" #include "routing/segment.hpp" #include "routing/segmented_route.hpp" @@ -77,6 +78,10 @@ public: std::string GetName() const override { return m_name; } void ClearState() override; + void SetEstimatorOptions(RoutingOptions::RoadType options) override; + + void SetEstimatorStrategy(EdgeEstimator::Strategy strategy) override; + void SetGuides(GuidesTracks && guides) override; RouterResultCode CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & startDirection, bool adjustToPrevRoute, diff --git a/routing/router.hpp b/routing/router.hpp index 1d5220f4f6..685c003b48 100644 --- a/routing/router.hpp +++ b/routing/router.hpp @@ -1,9 +1,11 @@ #pragma once #include "routing/checkpoints.hpp" +#include "routing/edge_estimator.hpp" #include "routing/road_graph.hpp" #include "routing/router_delegate.hpp" #include "routing/routing_callbacks.hpp" +#include "routing/routing_options.hpp" #include "kml/type_utils.hpp" @@ -61,6 +63,10 @@ public: /// Clear all temporary buffers. virtual void ClearState() {} + virtual void SetEstimatorOptions(RoutingOptions::RoadType options) {} + + virtual void SetEstimatorStrategy(EdgeEstimator::Strategy strategy) {} + virtual void SetGuides(GuidesTracks && guides) = 0; /// Override this function with routing implementation. diff --git a/routing/routing_options.cpp b/routing/routing_options.cpp index 03ae20d6e6..42291deec9 100644 --- a/routing/routing_options.cpp +++ b/routing/routing_options.cpp @@ -28,7 +28,7 @@ RoutingOptions RoutingOptions::LoadCarOptionsFromSettings() { uint32_t mode = 0; if (!settings::Get(kAvoidRoutingOptionSettingsForCar, mode)) - mode = 4; + mode = 0; return RoutingOptions(base::checked_cast(mode)); } -- 2.45.3 From 6a4cb5c168fac440d7f0a76b3609ad11eabb673b Mon Sep 17 00:00:00 2001 From: melonSkin76 Date: Tue, 6 Sep 2022 05:53:58 -0500 Subject: [PATCH 4/6] FewerTurns Done Added new strategy "Fewer Turns" with the corresponding turn check for connected segments u and v --- data/route_points.dat | 1 - routing/async_router.cpp | 2 +- routing/edge_estimator.cpp | 35 +++++++++++ routing/edge_estimator.hpp | 4 +- routing/index_graph.cpp | 64 ++++++++++++++++++++- routing/index_graph.hpp | 2 + routing/routing_tests/index_graph_tools.cpp | 1 + routing/routing_tests/index_graph_tools.hpp | 1 + 8 files changed, 105 insertions(+), 5 deletions(-) delete mode 100644 data/route_points.dat diff --git a/data/route_points.dat b/data/route_points.dat deleted file mode 100644 index f34fcc6510..0000000000 --- a/data/route_points.dat +++ /dev/null @@ -1 +0,0 @@ -[{"type":0,"title":"","subtitle":"","x":114.25822345504994,"y":22.903850160103033},{"type":2,"title":"","subtitle":"","x":114.25066146448764,"y":22.848765080380442}] \ No newline at end of file diff --git a/routing/async_router.cpp b/routing/async_router.cpp index d9f24e3f23..3f0f385f5e 100644 --- a/routing/async_router.cpp +++ b/routing/async_router.cpp @@ -348,7 +348,7 @@ void AsyncRouter::CalculateRoute() RoutingOptions const routingOptions = RoutingOptions::LoadCarOptionsFromSettings(); router->SetEstimatorOptions(routingOptions.GetOptions()); - router->SetEstimatorStrategy(EdgeEstimator::Strategy::Shortest); + router->SetEstimatorStrategy(EdgeEstimator::Strategy::Fastest); // Run basic request. code = router->CalculateRoute(checkpoints, startDirection, adjustToPrevRoute, diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index 385d07ae8b..918e559ddd 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -248,6 +248,17 @@ public: // EdgeEstimator overrides: double GetUTurnPenalty(Purpose /* purpose */) const override { return 0.0 /* seconds */; } + double GetTurnPenalty(Purpose purpose) const override + { + if (purpose == EdgeEstimator::Purpose::Weight) + { + if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) + { + return 24 * 60 * 60; + } + } + return 0.0; + } // Based on: https://confluence.mail.ru/display/MAPSME/Ferries double GetFerryLandingPenalty(Purpose purpose) const override { @@ -287,6 +298,17 @@ public: // EdgeEstimator overrides: double GetUTurnPenalty(Purpose /* purpose */) const override { return 20.0 /* seconds */; } + double GetTurnPenalty(Purpose purpose) const override + { + if (purpose == EdgeEstimator::Purpose::Weight) + { + if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) + { + return 24 * 60 * 60; + } + } + return 10.0; + } // Based on: https://confluence.mail.ru/display/MAPSME/Ferries double GetFerryLandingPenalty(Purpose purpose) const override { @@ -326,6 +348,7 @@ public: // EdgeEstimator overrides: double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override; double GetUTurnPenalty(Purpose /* purpose */) const override; + double GetTurnPenalty(Purpose purpose) const override; double GetFerryLandingPenalty(Purpose purpose) const override; private: @@ -348,6 +371,18 @@ double CarEstimator::GetUTurnPenalty(Purpose /* purpose */) const return 2 * 60; // seconds } +double CarEstimator::GetTurnPenalty(Purpose purpose) const +{ + if (purpose == EdgeEstimator::Purpose::Weight) + { + if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) + { + return 24 * 60 * 60; + } + } + return 60; +} + double CarEstimator::GetFerryLandingPenalty(Purpose purpose) const { switch (purpose) diff --git a/routing/edge_estimator.hpp b/routing/edge_estimator.hpp index 4bdb9626f6..2437184ec3 100644 --- a/routing/edge_estimator.hpp +++ b/routing/edge_estimator.hpp @@ -32,7 +32,8 @@ public: enum class Strategy { Fastest, - Shortest + Shortest, + FewerTurns }; EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH, @@ -62,6 +63,7 @@ public: virtual double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const = 0; virtual double GetUTurnPenalty(Purpose purpose) const = 0; + virtual double GetTurnPenalty(Purpose purpose) const = 0; virtual double GetFerryLandingPenalty(Purpose purpose) const = 0; static std::shared_ptr Create(VehicleType vehicleType, double maxWeighSpeedKMpH, diff --git a/routing/index_graph.cpp b/routing/index_graph.cpp index d5952f676f..c162f3fc36 100644 --- a/routing/index_graph.cpp +++ b/routing/index_graph.cpp @@ -12,6 +12,7 @@ #include "base/timer.hpp" #include +#include #include #include #include @@ -514,6 +515,9 @@ RouteWeight IndexGraph::GetPenalties(EdgeEstimator::Purpose purpose, Segment con if (IsUTurn(u, v)) weightPenalty += m_estimator->GetUTurnPenalty(purpose); + if (IsTurn(u, v)) + weightPenalty += m_estimator->GetTurnPenalty(purpose); + if (IsBoarding(fromPenaltyData.m_isFerry, toPenaltyData.m_isFerry)) weightPenalty += m_estimator->GetFerryLandingPenalty(purpose); @@ -549,6 +553,59 @@ bool IndexGraph::IsUTurnAndRestricted(Segment const & parent, Segment const & ch return uTurn.m_atTheEnd && turnPoint == n - 1; } +bool IndexGraph::IsTurn(Segment const & u, Segment const & v) const +{ + // Boundary check for segmentIdx + if (u.GetSegmentIdx() == 0 && !(u.IsForward())) + { + return false; + } + + if (v.GetSegmentIdx() == 0 && !(v.IsForward())) + { + return false; + } + + auto geoU = GetRoadGeometry(u.GetFeatureId()); + auto startPointU = geoU.GetPoint(u.GetSegmentIdx()); + auto endPointU = geoU.GetPoint(u.IsForward() ? u.GetSegmentIdx() + 1: u.GetSegmentIdx() - 1); + + auto geoV = GetRoadGeometry(v.GetFeatureId()); + auto startPointV = geoV.GetPoint(v.GetSegmentIdx()); + auto endPointV = geoV.GetPoint(v.IsForward() ? v.GetSegmentIdx() + 1: v.GetSegmentIdx() - 1); + + if (!(endPointU == startPointV)) + { + LOG(LDEBUG, ("Turn checking: u and v are not connected")); + + return false; + } + + double vectorU[2] = {endPointU.m_lat - startPointU.m_lat, endPointU.m_lon - startPointU.m_lon}; + double vectorV[2] = {endPointV.m_lat - startPointV.m_lat, endPointV.m_lon - startPointV.m_lon}; + + //dot product + double dot = vectorU[0] * vectorV[0] + vectorU[1] * vectorV[1]; + + //determinant + double det = vectorU[0] * vectorV[1] - vectorU[1] * vectorV[0]; + + //calculate the anlge + double angle = atan2(det, dot); + + //convert to degree value + angle = angle * 180 / 3.141592; + + if (abs(angle) >= 45) + { + return true; + } + else + { + return false; + } +} + RouteWeight IndexGraph::CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool isOutgoing, Segment const & from, Segment const & to, std::optional const & prevWeight) const @@ -560,9 +617,12 @@ RouteWeight IndexGraph::CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool auto const weight = RouteWeight(m_estimator->CalcSegmentWeight(segment, road, purpose)); - if(m_estimator->GetStrategy() == EdgeEstimator::Strategy::Shortest) + if (purpose == EdgeEstimator::Purpose::Weight) { - return weight; + if(m_estimator->GetStrategy() == EdgeEstimator::Strategy::Shortest) + { + return weight; + } } auto const penalties = GetPenalties(purpose, isOutgoing ? from : to, isOutgoing ? to : from, prevWeight); diff --git a/routing/index_graph.hpp b/routing/index_graph.hpp index be7a1bab3c..e0cb7a2a4b 100644 --- a/routing/index_graph.hpp +++ b/routing/index_graph.hpp @@ -133,6 +133,8 @@ public: bool IsUTurnAndRestricted(Segment const & parent, Segment const & child, bool isOutgoing) const; + bool IsTurn(Segment const & u, Segment const & v) const; + /// @param[in] isOutgoing true, when movig from -> to, false otherwise. /// @param[in] prevWeight used for fetching access:conditional. /// I suppose :) its time when user will be at the end of |from| (|to| if \a isOutgoing == false) segment. diff --git a/routing/routing_tests/index_graph_tools.cpp b/routing/routing_tests/index_graph_tools.cpp index 425f9a7d97..86e57b793c 100644 --- a/routing/routing_tests/index_graph_tools.cpp +++ b/routing/routing_tests/index_graph_tools.cpp @@ -146,6 +146,7 @@ double WeightedEdgeEstimator::CalcSegmentWeight(Segment const & segment, } double WeightedEdgeEstimator::GetUTurnPenalty(Purpose purpose) const { return 0.0; } +double WeightedEdgeEstimator::GetTurnPenalty(Purpose purpose) const { return 0.0; } double WeightedEdgeEstimator::GetFerryLandingPenalty(Purpose purpose) const { return 0.0; } // TestIndexGraphTopology -------------------------------------------------------------------------- diff --git a/routing/routing_tests/index_graph_tools.hpp b/routing/routing_tests/index_graph_tools.hpp index 4587a1388e..c1893719e5 100644 --- a/routing/routing_tests/index_graph_tools.hpp +++ b/routing/routing_tests/index_graph_tools.hpp @@ -181,6 +181,7 @@ public: EdgeEstimator::Purpose purpose) const override; double GetUTurnPenalty(Purpose purpose) const override; + double GetTurnPenalty(Purpose purpose) const override; double GetFerryLandingPenalty(Purpose purpose) const override; private: -- 2.45.3 From 6406c9da1bbe9b05bb6971545b001bfd65939ba2 Mon Sep 17 00:00:00 2001 From: melonSkin76 Date: Thu, 8 Sep 2022 01:07:01 -0500 Subject: [PATCH 5/6] Desktop frontend for routing strategies completed Also added the UI for adjusting avoid routing options for desktop --- qt/routing_settings_dialog.cpp | 39 ++++++++++++++++++++++++ qt/routing_settings_dialog.hpp | 2 ++ routing/async_router.cpp | 3 +- routing/edge_estimator.cpp | 55 ++++++++++++++++++++++++++++++---- routing/edge_estimator.hpp | 4 +++ routing/index_graph.cpp | 2 +- 6 files changed, 97 insertions(+), 8 deletions(-) diff --git a/qt/routing_settings_dialog.cpp b/qt/routing_settings_dialog.cpp index 72a3f8a65b..d3ace3e3b1 100644 --- a/qt/routing_settings_dialog.cpp +++ b/qt/routing_settings_dialog.cpp @@ -3,6 +3,7 @@ #include "map/framework.hpp" #include "routing/router.hpp" +#include "routing/edge_estimator.hpp" #include "platform/settings.hpp" @@ -26,12 +27,26 @@ std::string const kUseCachedRoutingSettings = "use_cached_settings_desktop"; std::string const kStartCoordsCachedSettings = "start_coords_desktop"; std::string const kFinishCoordsCachedSettings = "finish_coords_desktop"; std::string const kRouterTypeCachedSettings = "router_type_desktop"; +std::string const kRouterStrategyCachedSettings = "router_strategy"; +std::string const kAvoidRoutingOptionSettings = "avoid_routing_options_car"; int constexpr DefaultRouterIndex() { // Car router by default. return static_cast(routing::RouterType::Vehicle); } + +int constexpr DefaultStrategyIndex() +{ + // Routing strategy by default + return static_cast(routing::EdgeEstimator::Strategy::Fastest); +} + +int constexpr DefaultAvoidOptionIndex() +{ + // Avoid routing option by default + return static_cast(routing::RoutingOptions::Road::Usual); +} } // namespace // static @@ -135,6 +150,20 @@ RoutingSettings::RoutingSettings(QWidget * parent, Framework & framework) m_routerType->insertItem(static_cast(RouterType::Transit), "transit"); form->addRow("Choose router:", m_routerType); + m_routerStrategy = new QComboBox(frame); + m_routerStrategy->insertItem(static_cast(EdgeEstimator::Strategy::Fastest), "fastest"); + m_routerStrategy->insertItem(static_cast(EdgeEstimator::Strategy::Shortest), "shortest"); + m_routerStrategy->insertItem(static_cast(EdgeEstimator::Strategy::FewerTurns), "fewer turns"); + form->addRow("Choose strategy:", m_routerStrategy); + + m_avoidRoutingOptions = new QComboBox(frame); + m_avoidRoutingOptions->insertItem(static_cast(RoutingOptions::Road::Dirty), "dirty"); + m_avoidRoutingOptions->insertItem(static_cast(RoutingOptions::Road::Ferry), "ferry"); + m_avoidRoutingOptions->insertItem(static_cast(RoutingOptions::Road::Motorway), "motorway"); + m_avoidRoutingOptions->insertItem(static_cast(RoutingOptions::Road::Toll), "toll"); + m_avoidRoutingOptions->insertItem(static_cast(RoutingOptions::Road::Usual), "usual"); + form->addRow("Choose avoid option:", m_avoidRoutingOptions); + m_showTurnsCheckbox = new QCheckBox({}, frame); form->addRow("Show turns:", m_showTurnsCheckbox); @@ -191,6 +220,8 @@ bool RoutingSettings::SaveSettings() settings::Set(kUseDebugGuideSettings, m_useDebugGuideCheckbox->isChecked()); settings::Set(kUseCachedRoutingSettings, m_saveSessionCheckbox->isChecked()); settings::Set(kRouterTypeCachedSettings, m_routerType->currentIndex()); + settings::Set(kRouterStrategyCachedSettings, m_routerStrategy->currentIndex()); + settings::Set(kAvoidRoutingOptionSettings, m_avoidRoutingOptions->currentIndex()); return ValidateAndSaveCoordsFromInput(); } @@ -208,6 +239,14 @@ void RoutingSettings::LoadSettings() settings::TryGet(kRouterTypeCachedSettings, routerType); m_routerType->setCurrentIndex(routerType); + int routerStrategy = DefaultStrategyIndex(); + settings::TryGet(kRouterStrategyCachedSettings, routerStrategy); + m_routerStrategy->setCurrentIndex(routerStrategy); + + int avoidRoutingOption = DefaultAvoidOptionIndex(); + settings::TryGet(kAvoidRoutingOptionSettings, avoidRoutingOption); + m_avoidRoutingOptions->setCurrentIndex(avoidRoutingOption); + bool showTurns = false; settings::TryGet(kShowTurnsSettings, showTurns); m_showTurnsCheckbox->setChecked(showTurns); diff --git a/qt/routing_settings_dialog.hpp b/qt/routing_settings_dialog.hpp index 0d17b16196..e97d9962b4 100644 --- a/qt/routing_settings_dialog.hpp +++ b/qt/routing_settings_dialog.hpp @@ -40,6 +40,8 @@ private: QLineEdit * m_finishInput; QComboBox * m_routerType; + QComboBox * m_routerStrategy; + QComboBox * m_avoidRoutingOptions; QCheckBox * m_showTurnsCheckbox; QCheckBox * m_useDebugGuideCheckbox; QCheckBox * m_saveSessionCheckbox; diff --git a/routing/async_router.cpp b/routing/async_router.cpp index 3f0f385f5e..703bc7d1d7 100644 --- a/routing/async_router.cpp +++ b/routing/async_router.cpp @@ -348,7 +348,8 @@ void AsyncRouter::CalculateRoute() RoutingOptions const routingOptions = RoutingOptions::LoadCarOptionsFromSettings(); router->SetEstimatorOptions(routingOptions.GetOptions()); - router->SetEstimatorStrategy(EdgeEstimator::Strategy::Fastest); + EdgeEstimator::Strategy routingStrategy = EdgeEstimator::LoadRoutingStrategyFromSettings(); + router->SetEstimatorStrategy(routingStrategy); // Run basic request. code = router->CalculateRoute(checkpoints, startDirection, adjustToPrevRoute, diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index 918e559ddd..b12f462c1f 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -1,5 +1,7 @@ #include "routing/edge_estimator.hpp" +#include "platform/settings.hpp" + #include "routing/geometry.hpp" #include "routing/latlon_with_altitude.hpp" #include "routing/routing_exceptions.hpp" @@ -123,6 +125,19 @@ double GetCarClimbPenalty(EdgeEstimator::Purpose /* purpose */, double /* tangen } // EdgeEstimator ----------------------------------------------------------------------------------- + +string const EdgeEstimator::kRoutingStrategySettings = "router_strategy"; + +//static +EdgeEstimator::Strategy EdgeEstimator::LoadRoutingStrategyFromSettings() +{ + uint32_t mode = 0; + if (!settings::Get(kRoutingStrategySettings, mode)) + mode = 0; + + return (EdgeEstimator::Strategy) mode; +} + EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH, DataSource * /*dataSourcePtr*/, std::shared_ptr /*numMwmIds*/) : m_maxWeightSpeedMpS(KmphToMps(maxWeightSpeedKMpH)) @@ -247,7 +262,17 @@ public: } // EdgeEstimator overrides: - double GetUTurnPenalty(Purpose /* purpose */) const override { return 0.0 /* seconds */; } + double GetUTurnPenalty(Purpose purpose) const override + { + if (purpose == EdgeEstimator::Purpose::Weight) + { + if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) + { + return 24 * 60 * 60; + } + } + return 0.0 /* seconds */; + } double GetTurnPenalty(Purpose purpose) const override { if (purpose == EdgeEstimator::Purpose::Weight) @@ -297,7 +322,17 @@ public: } // EdgeEstimator overrides: - double GetUTurnPenalty(Purpose /* purpose */) const override { return 20.0 /* seconds */; } + double GetUTurnPenalty(Purpose purpose) const override + { + if (purpose == EdgeEstimator::Purpose::Weight) + { + if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) + { + return 24 * 60 * 60; + } + } + return 20.0 /* seconds */; + } double GetTurnPenalty(Purpose purpose) const override { if (purpose == EdgeEstimator::Purpose::Weight) @@ -307,7 +342,7 @@ public: return 24 * 60 * 60; } } - return 10.0; + return 0.0; } // Based on: https://confluence.mail.ru/display/MAPSME/Ferries double GetFerryLandingPenalty(Purpose purpose) const override @@ -347,7 +382,7 @@ public: // EdgeEstimator overrides: double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override; - double GetUTurnPenalty(Purpose /* purpose */) const override; + double GetUTurnPenalty(Purpose purpose) const override; double GetTurnPenalty(Purpose purpose) const override; double GetFerryLandingPenalty(Purpose purpose) const override; @@ -363,8 +398,16 @@ CarEstimator::CarEstimator(DataSource * dataSourcePtr, std::shared_ptrGetStrategy() == EdgeEstimator::Strategy::FewerTurns) + { + return 24 * 60 * 60; + } + } + // Adds 2 minutes penalty for U-turn. The value is quite arbitrary // and needs to be properly selected after a number of real-world // experiments. @@ -380,7 +423,7 @@ double CarEstimator::GetTurnPenalty(Purpose purpose) const return 24 * 60 * 60; } } - return 60; + return 0.0; } double CarEstimator::GetFerryLandingPenalty(Purpose purpose) const diff --git a/routing/edge_estimator.hpp b/routing/edge_estimator.hpp index 2437184ec3..9ab43c1e87 100644 --- a/routing/edge_estimator.hpp +++ b/routing/edge_estimator.hpp @@ -29,6 +29,8 @@ public: ETA }; + static std::string const kRoutingStrategySettings; + enum class Strategy { Fastest, @@ -40,6 +42,8 @@ public: DataSource * dataSourcePtr = nullptr, std::shared_ptr numMwmIds = nullptr); virtual ~EdgeEstimator() = default; + static Strategy LoadRoutingStrategyFromSettings(); + double CalcHeuristic(ms::LatLon const & from, ms::LatLon const & to) const; // Estimates time in seconds it takes to go from point |from| to point |to| along a leap (fake) // edge |from|-|to| using real features. diff --git a/routing/index_graph.cpp b/routing/index_graph.cpp index c162f3fc36..023b2ebb1f 100644 --- a/routing/index_graph.cpp +++ b/routing/index_graph.cpp @@ -596,7 +596,7 @@ bool IndexGraph::IsTurn(Segment const & u, Segment const & v) const //convert to degree value angle = angle * 180 / 3.141592; - if (abs(angle) >= 45) + if (abs(angle) >= 30) { return true; } -- 2.45.3 From c938efcf0d7e65057cd46b96db177dd1013d8606 Mon Sep 17 00:00:00 2001 From: melonSkin76 Date: Mon, 12 Sep 2022 03:31:50 -0500 Subject: [PATCH 6/6] Android Frontend Finished Also made some minor modifications to the routing calculations in the backend --- .../maps/routing/RoutingOptions.cpp | 22 ++++++- .../res/layout/fragment_driving_options.xml | 42 +++++++++++++ android/res/values/strings.xml | 4 ++ .../maps/routing/RoutingOptions.java | 19 ++++++ .../maps/settings/DrivingOptionsFragment.java | 61 ++++++++++++++++++- .../maps/settings/RoutingStrategyType.java | 8 +++ qt/routing_settings_dialog.cpp | 2 + routing/edge_estimator.cpp | 23 ++++--- routing/edge_estimator.hpp | 1 + routing/index_graph.cpp | 4 +- tools/android/set_up_android.py | 2 +- 11 files changed, 174 insertions(+), 14 deletions(-) create mode 100644 android/src/com/mapswithme/maps/settings/RoutingStrategyType.java diff --git a/android/jni/com/mapswithme/maps/routing/RoutingOptions.cpp b/android/jni/com/mapswithme/maps/routing/RoutingOptions.cpp index 1cf670a297..7d601d20c8 100644 --- a/android/jni/com/mapswithme/maps/routing/RoutingOptions.cpp +++ b/android/jni/com/mapswithme/maps/routing/RoutingOptions.cpp @@ -10,6 +10,12 @@ routing::RoutingOptions::Road makeValue(jint option) return static_cast(road); } +routing::EdgeEstimator::Strategy makeStrategyValue(jint strategy) +{ + int convertedStrat = static_cast(strategy); + return static_cast(convertedStrat); +} + extern "C" { @@ -22,6 +28,14 @@ Java_com_mapswithme_maps_routing_RoutingOptions_nativeHasOption(JNIEnv * env, jc return static_cast(routingOptions.Has(road)); } +JNIEXPORT jint JNICALL +Java_com_mapswithme_maps_routing_RoutingOptions_nativeGetStrategy(JNIEnv * env, jclass clazz) +{ + CHECK(g_framework, ("Framework isn't created yet!")); + routing::EdgeEstimator::Strategy routingStrategy = routing::EdgeEstimator::LoadRoutingStrategyFromSettings(); + return static_cast(routingStrategy); +} + JNIEXPORT void JNICALL Java_com_mapswithme_maps_routing_RoutingOptions_nativeAddOption(JNIEnv * env, jclass clazz, jint option) { @@ -32,7 +46,6 @@ Java_com_mapswithme_maps_routing_RoutingOptions_nativeAddOption(JNIEnv * env, jc routing::RoutingOptions::SaveCarOptionsToSettings(routingOptions); } - JNIEXPORT void JNICALL Java_com_mapswithme_maps_routing_RoutingOptions_nativeRemoveOption(JNIEnv * env, jclass clazz, jint option) { @@ -42,4 +55,11 @@ Java_com_mapswithme_maps_routing_RoutingOptions_nativeRemoveOption(JNIEnv * env, routingOptions.Remove(road); routing::RoutingOptions::SaveCarOptionsToSettings(routingOptions); } + +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_routing_RoutingOptions_nativeSetStrategy(JNIEnv * env, jclass clazz, jint strategy) +{ + CHECK(g_framework, ("Framework isn't created yet!")); + routing::EdgeEstimator::SaveRoutingStrategyToSettings(makeStrategyValue(strategy)); +} } diff --git a/android/res/layout/fragment_driving_options.xml b/android/res/layout/fragment_driving_options.xml index acfaa9c0d5..67febd740e 100644 --- a/android/res/layout/fragment_driving_options.xml +++ b/android/res/layout/fragment_driving_options.xml @@ -110,4 +110,46 @@ android:layout_width="wrap_content" android:layout_height="match_parent"/> + + + + + + + diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index f9508a9d45..a70bc9a550 100644 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -651,10 +651,14 @@ Online editing Routing options Avoid on every route + Routing Strategy Toll roads Unpaved roads Ferry crossings Motorways + Fastest + Shortest + Fewer turns Unable to calculate route Unfortunately, we couldn\'t find a route, probably due to the options you have chosen. Please change the settings and try again. Define roads to avoid diff --git a/android/src/com/mapswithme/maps/routing/RoutingOptions.java b/android/src/com/mapswithme/maps/routing/RoutingOptions.java index fcb240e9cb..99d47f8dfa 100644 --- a/android/src/com/mapswithme/maps/routing/RoutingOptions.java +++ b/android/src/com/mapswithme/maps/routing/RoutingOptions.java @@ -3,6 +3,7 @@ package com.mapswithme.maps.routing; import androidx.annotation.NonNull; import com.mapswithme.maps.settings.RoadType; +import com.mapswithme.maps.settings.RoutingStrategyType; import java.util.HashSet; import java.util.Set; @@ -24,9 +25,21 @@ public class RoutingOptions return nativeHasOption(roadType.ordinal()); } + public static int getStrategy() + { + return nativeGetStrategy(); + } + + public static void setStrategy(@NonNull RoutingStrategyType routingStrategyType) + { + nativeSetStrategy(routingStrategyType.ordinal()); + } + private static native void nativeAddOption(int option); private static native void nativeRemoveOption(int option); private static native boolean nativeHasOption(int option); + private static native int nativeGetStrategy(); + private static native void nativeSetStrategy(int strategy); public static boolean hasAnyOptions() { @@ -49,4 +62,10 @@ public class RoutingOptions } return roadTypes; } + + public static RoutingStrategyType getActiveRoutingStrategyType() + { + int strategyType = getStrategy(); + return RoutingStrategyType.values()[strategyType]; + } } diff --git a/android/src/com/mapswithme/maps/settings/DrivingOptionsFragment.java b/android/src/com/mapswithme/maps/settings/DrivingOptionsFragment.java index 9bdc251b5a..ef9d6b4855 100644 --- a/android/src/com/mapswithme/maps/settings/DrivingOptionsFragment.java +++ b/android/src/com/mapswithme/maps/settings/DrivingOptionsFragment.java @@ -6,6 +6,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; +import android.widget.RadioGroup; import android.widget.Switch; import androidx.annotation.NonNull; @@ -25,8 +26,11 @@ import java.util.Set; public class DrivingOptionsFragment extends BaseMwmToolbarFragment { public static final String BUNDLE_ROAD_TYPES = "road_types"; + public static final String BUNDLE_ROUTING_STRATEGY_TYPE = "routing_strategy_type"; @NonNull private Set mRoadTypes = Collections.emptySet(); + @NonNull + private RoutingStrategyType mStrategy = RoutingStrategyType.Fastest; @Nullable @Override @@ -38,6 +42,9 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment mRoadTypes = savedInstanceState != null && savedInstanceState.containsKey(BUNDLE_ROAD_TYPES) ? makeRouteTypes(savedInstanceState) : RoutingOptions.getActiveRoadTypes(); + mStrategy = savedInstanceState != null && savedInstanceState.containsKey(BUNDLE_ROUTING_STRATEGY_TYPE) + ? makeRoutingStrategyType(savedInstanceState) + : RoutingOptions.getActiveRoutingStrategyType(); return root; } @@ -53,6 +60,13 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment return result; } + @NonNull + private RoutingStrategyType makeRoutingStrategyType(@NonNull Bundle bundle) + { + RoutingStrategyType result = Objects.requireNonNull((RoutingStrategyType)bundle.getSerializable(BUNDLE_ROUTING_STRATEGY_TYPE)); + return result; + } + @Override public void onSaveInstanceState(@NonNull Bundle outState) { @@ -63,12 +77,15 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment savedRoadTypes.add(each.ordinal()); } outState.putIntegerArrayList(BUNDLE_ROAD_TYPES, savedRoadTypes); + + outState.putSerializable(BUNDLE_ROUTING_STRATEGY_TYPE, mStrategy); } private boolean areSettingsNotChanged() { Set lastActiveRoadTypes = RoutingOptions.getActiveRoadTypes(); - return mRoadTypes.equals(lastActiveRoadTypes); + RoutingStrategyType lastActiveStrategyType = RoutingOptions.getActiveRoutingStrategyType(); + return mRoadTypes.equals(lastActiveRoadTypes) && mStrategy.equals(lastActiveStrategyType); } @Override @@ -104,6 +121,26 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment CompoundButton.OnCheckedChangeListener dirtyBtnListener = new ToggleRoutingOptionListener(RoadType.Dirty); dirtyRoadsBtn.setOnCheckedChangeListener(dirtyBtnListener); + + RadioGroup strategyRadioGroup = root.findViewById(R.id.routing_strategy_types); + RoutingStrategyType currentStrategy = RoutingOptions.getActiveRoutingStrategyType(); + int currentCheckedStrategyId; + switch (currentStrategy) + { + case Shortest: + currentCheckedStrategyId = R.id.use_strategy_shortest; + break; + case FewerTurns: + currentCheckedStrategyId = R.id.use_strategy_fewerTurns; + break; + default: + currentCheckedStrategyId = R.id.use_strategy_fastest; + break; + } + strategyRadioGroup.check(currentCheckedStrategyId); + RadioGroup.OnCheckedChangeListener strategyRadioGroupListener = + new ToggleRoutingStrategyListener(); + strategyRadioGroup.setOnCheckedChangeListener(strategyRadioGroupListener); } private static class ToggleRoutingOptionListener implements CompoundButton.OnCheckedChangeListener @@ -125,4 +162,26 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment RoutingOptions.removeOption(mRoadType); } } + + private static class ToggleRoutingStrategyListener implements RadioGroup.OnCheckedChangeListener + { + private ToggleRoutingStrategyListener() {} + + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) + { + switch (checkedId) + { + case R.id.use_strategy_fastest: + RoutingOptions.setStrategy(RoutingStrategyType.Fastest); + break; + case R.id.use_strategy_shortest: + RoutingOptions.setStrategy(RoutingStrategyType.Shortest); + break; + case R.id.use_strategy_fewerTurns: + RoutingOptions.setStrategy(RoutingStrategyType.FewerTurns); + break; + } + } + } } diff --git a/android/src/com/mapswithme/maps/settings/RoutingStrategyType.java b/android/src/com/mapswithme/maps/settings/RoutingStrategyType.java new file mode 100644 index 0000000000..8e5a063f6b --- /dev/null +++ b/android/src/com/mapswithme/maps/settings/RoutingStrategyType.java @@ -0,0 +1,8 @@ +package com.mapswithme.maps.settings; + +public enum RoutingStrategyType +{ + Fastest, + Shortest, + FewerTurns +} diff --git a/qt/routing_settings_dialog.cpp b/qt/routing_settings_dialog.cpp index d3ace3e3b1..3e64132969 100644 --- a/qt/routing_settings_dialog.cpp +++ b/qt/routing_settings_dialog.cpp @@ -110,6 +110,8 @@ void RoutingSettings::LoadSession(Framework & framework) settings::Delete(kStartCoordsCachedSettings); settings::Delete(kFinishCoordsCachedSettings); settings::Delete(kRouterTypeCachedSettings); + settings::Delete(kRouterStrategyCachedSettings); + settings::Delete(kAvoidRoutingOptionSettings); } } diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index b12f462c1f..5c1191bc35 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -128,16 +128,23 @@ double GetCarClimbPenalty(EdgeEstimator::Purpose /* purpose */, double /* tangen string const EdgeEstimator::kRoutingStrategySettings = "router_strategy"; -//static +// static EdgeEstimator::Strategy EdgeEstimator::LoadRoutingStrategyFromSettings() { - uint32_t mode = 0; + int mode = 0; if (!settings::Get(kRoutingStrategySettings, mode)) mode = 0; return (EdgeEstimator::Strategy) mode; } +// static +void EdgeEstimator::SaveRoutingStrategyToSettings(Strategy strategy) +{ + settings::Set(kRoutingStrategySettings, + strings::to_string(static_cast(strategy))); +} + EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH, DataSource * /*dataSourcePtr*/, std::shared_ptr /*numMwmIds*/) : m_maxWeightSpeedMpS(KmphToMps(maxWeightSpeedKMpH)) @@ -268,7 +275,7 @@ public: { if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) { - return 24 * 60 * 60; + return 60 * 60; } } return 0.0 /* seconds */; @@ -279,7 +286,7 @@ public: { if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) { - return 24 * 60 * 60; + return 60 * 60; } } return 0.0; @@ -328,7 +335,7 @@ public: { if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) { - return 24 * 60 * 60; + return 60 * 60; } } return 20.0 /* seconds */; @@ -339,7 +346,7 @@ public: { if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) { - return 24 * 60 * 60; + return 60 * 60; } } return 0.0; @@ -404,7 +411,7 @@ double CarEstimator::GetUTurnPenalty(Purpose purpose) const { if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) { - return 24 * 60 * 60; + return 60 * 60; } } @@ -420,7 +427,7 @@ double CarEstimator::GetTurnPenalty(Purpose purpose) const { if (this->GetStrategy() == EdgeEstimator::Strategy::FewerTurns) { - return 24 * 60 * 60; + return 60 * 60; } } return 0.0; diff --git a/routing/edge_estimator.hpp b/routing/edge_estimator.hpp index 9ab43c1e87..8079f14ef0 100644 --- a/routing/edge_estimator.hpp +++ b/routing/edge_estimator.hpp @@ -43,6 +43,7 @@ public: virtual ~EdgeEstimator() = default; static Strategy LoadRoutingStrategyFromSettings(); + static void SaveRoutingStrategyToSettings(Strategy strategy); double CalcHeuristic(ms::LatLon const & from, ms::LatLon const & to) const; // Estimates time in seconds it takes to go from point |from| to point |to| along a leap (fake) diff --git a/routing/index_graph.cpp b/routing/index_graph.cpp index 023b2ebb1f..1a2ff38916 100644 --- a/routing/index_graph.cpp +++ b/routing/index_graph.cpp @@ -576,8 +576,6 @@ bool IndexGraph::IsTurn(Segment const & u, Segment const & v) const if (!(endPointU == startPointV)) { - LOG(LDEBUG, ("Turn checking: u and v are not connected")); - return false; } @@ -596,7 +594,7 @@ bool IndexGraph::IsTurn(Segment const & u, Segment const & v) const //convert to degree value angle = angle * 180 / 3.141592; - if (abs(angle) >= 30) + if (abs(angle) >= 15) { return true; } diff --git a/tools/android/set_up_android.py b/tools/android/set_up_android.py index ed5dc34931..73718315db 100755 --- a/tools/android/set_up_android.py +++ b/tools/android/set_up_android.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/local/bin/python import os, sys, shutil, collections from optparse import OptionParser -- 2.45.3