From 90c12003bd57a80ecda27043e9ae83b6328c188f Mon Sep 17 00:00:00 2001 From: x7z4w Date: Fri, 26 Sep 2025 13:20:57 +0000 Subject: [PATCH] [routing] Avoid paved roads Signed-off-by: x7z4w --- .../settings/DrivingOptionsScreen.java | 3 +- .../settings/DrivingOptionsFragment.java | 45 ++++++++++++++++--- .../res/layout/fragment_driving_options.xml | 22 +++++++++ android/app/src/main/res/values/strings.xml | 1 + .../organicmaps/sdk/settings/RoadType.java | 3 +- libs/routing/routing_options.cpp | 13 +++++- libs/routing/routing_options.hpp | 3 +- 7 files changed, 80 insertions(+), 10 deletions(-) diff --git a/android/app/src/main/java/app/organicmaps/car/screens/settings/DrivingOptionsScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/settings/DrivingOptionsScreen.java index 90624f414..f7c6a0154 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/settings/DrivingOptionsScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/settings/DrivingOptionsScreen.java @@ -32,7 +32,8 @@ public class DrivingOptionsScreen extends BaseMapScreen new DrivingOption(RoadType.Dirty, R.string.avoid_unpaved), new DrivingOption(RoadType.Ferry, R.string.avoid_ferry), new DrivingOption(RoadType.Motorway, R.string.avoid_motorways), - new DrivingOption(RoadType.Steps, R.string.avoid_steps)}; + new DrivingOption(RoadType.Steps, R.string.avoid_steps), + new DrivingOption(RoadType.Paved, R.string.avoid_paved)}; @NonNull private final Map mInitialDrivingOptionsState = new HashMap<>(); diff --git a/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsFragment.java b/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsFragment.java index aee0aa2ce..6e1a213e4 100644 --- a/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsFragment.java +++ b/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsFragment.java @@ -90,28 +90,36 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment { SwitchCompat tollsBtn = root.findViewById(R.id.avoid_tolls_btn); tollsBtn.setChecked(RoutingOptions.hasOption(RoadType.Toll)); - CompoundButton.OnCheckedChangeListener tollBtnListener = new ToggleRoutingOptionListener(RoadType.Toll); + CompoundButton.OnCheckedChangeListener tollBtnListener = new ToggleRoutingOptionListener(RoadType.Toll, root); tollsBtn.setOnCheckedChangeListener(tollBtnListener); SwitchCompat motorwaysBtn = root.findViewById(R.id.avoid_motorways_btn); motorwaysBtn.setChecked(RoutingOptions.hasOption(RoadType.Motorway)); - CompoundButton.OnCheckedChangeListener motorwayBtnListener = new ToggleRoutingOptionListener(RoadType.Motorway); + CompoundButton.OnCheckedChangeListener motorwayBtnListener = + new ToggleRoutingOptionListener(RoadType.Motorway, root); motorwaysBtn.setOnCheckedChangeListener(motorwayBtnListener); SwitchCompat ferriesBtn = root.findViewById(R.id.avoid_ferries_btn); ferriesBtn.setChecked(RoutingOptions.hasOption(RoadType.Ferry)); - CompoundButton.OnCheckedChangeListener ferryBtnListener = new ToggleRoutingOptionListener(RoadType.Ferry); + CompoundButton.OnCheckedChangeListener ferryBtnListener = new ToggleRoutingOptionListener(RoadType.Ferry, root); ferriesBtn.setOnCheckedChangeListener(ferryBtnListener); SwitchCompat dirtyRoadsBtn = root.findViewById(R.id.avoid_dirty_roads_btn); dirtyRoadsBtn.setChecked(RoutingOptions.hasOption(RoadType.Dirty)); - CompoundButton.OnCheckedChangeListener dirtyBtnListener = new ToggleRoutingOptionListener(RoadType.Dirty); + dirtyRoadsBtn.setEnabled(!RoutingOptions.hasOption(RoadType.Paved) || RoutingOptions.hasOption(RoadType.Dirty)); + CompoundButton.OnCheckedChangeListener dirtyBtnListener = new ToggleRoutingOptionListener(RoadType.Dirty, root); dirtyRoadsBtn.setOnCheckedChangeListener(dirtyBtnListener); SwitchCompat stepsBtn = root.findViewById(R.id.avoid_steps_btn); stepsBtn.setChecked(RoutingOptions.hasOption(RoadType.Steps)); - CompoundButton.OnCheckedChangeListener stepsBtnListener = new ToggleRoutingOptionListener(RoadType.Steps); + CompoundButton.OnCheckedChangeListener stepsBtnListener = new ToggleRoutingOptionListener(RoadType.Steps, root); stepsBtn.setOnCheckedChangeListener(stepsBtnListener); + + SwitchCompat pavedBtn = root.findViewById(R.id.avoid_paved_roads_btn); + pavedBtn.setChecked(RoutingOptions.hasOption(RoadType.Paved)); + pavedBtn.setEnabled(!RoutingOptions.hasOption(RoadType.Dirty) || RoutingOptions.hasOption(RoadType.Paved)); + CompoundButton.OnCheckedChangeListener pavedBtnListener = new ToggleRoutingOptionListener(RoadType.Paved, root); + pavedBtn.setOnCheckedChangeListener(pavedBtnListener); } private static class ToggleRoutingOptionListener implements CompoundButton.OnCheckedChangeListener @@ -119,9 +127,13 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment @NonNull private final RoadType mRoadType; - private ToggleRoutingOptionListener(@NonNull RoadType roadType) + @NonNull + private final View mRoot; + + private ToggleRoutingOptionListener(@NonNull RoadType roadType, @NonNull View root) { mRoadType = roadType; + mRoot = root; } @Override @@ -131,6 +143,27 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment RoutingOptions.addOption(mRoadType); else RoutingOptions.removeOption(mRoadType); + + SwitchCompat dirtyRoadsBtn = mRoot.findViewById(R.id.avoid_dirty_roads_btn); + SwitchCompat pavedBtn = mRoot.findViewById(R.id.avoid_paved_roads_btn); + if (mRoadType == RoadType.Dirty) + { + pavedBtn.setEnabled(!isChecked); + if (isChecked) + { + pavedBtn.setChecked(false); + dirtyRoadsBtn.setEnabled(true); + } + } + else if (mRoadType == RoadType.Paved) + { + dirtyRoadsBtn.setEnabled(!isChecked); + if (isChecked) + { + dirtyRoadsBtn.setChecked(false); + pavedBtn.setEnabled(true); + } + } } } } diff --git a/android/app/src/main/res/layout/fragment_driving_options.xml b/android/app/src/main/res/layout/fragment_driving_options.xml index 5495b81e7..fab1279a8 100644 --- a/android/app/src/main/res/layout/fragment_driving_options.xml +++ b/android/app/src/main/res/layout/fragment_driving_options.xml @@ -59,6 +59,28 @@ android:padding="@dimen/margin_half_double_plus"/> + + + + + Avoid ferries Avoid freeways Avoid stairs + Avoid paved roads Unable to calculate route A route could not be found. This may be caused by your routing options or incomplete OpenStreetMap data. Please change your routing options and retry. Define roads to avoid diff --git a/android/sdk/src/main/java/app/organicmaps/sdk/settings/RoadType.java b/android/sdk/src/main/java/app/organicmaps/sdk/settings/RoadType.java index 976702e68..5abde19e4 100644 --- a/android/sdk/src/main/java/app/organicmaps/sdk/settings/RoadType.java +++ b/android/sdk/src/main/java/app/organicmaps/sdk/settings/RoadType.java @@ -7,5 +7,6 @@ public enum RoadType Motorway, Ferry, Dirty, - Steps + Steps, + Paved } diff --git a/libs/routing/routing_options.cpp b/libs/routing/routing_options.cpp index b2eaa3fbe..af0ab010a 100644 --- a/libs/routing/routing_options.cpp +++ b/libs/routing/routing_options.cpp @@ -36,6 +36,10 @@ void RoutingOptions::SaveCarOptionsToSettings(RoutingOptions options) void RoutingOptions::Add(RoutingOptions::Road type) { + if (type == RoutingOptions::Road::Paved) + Remove(RoutingOptions::Road::Dirty); + else if (type == RoutingOptions::Road::Dirty) + Remove(RoutingOptions::Road::Paved); m_options |= static_cast(type); } @@ -67,7 +71,9 @@ RoutingOptionsClassifier::RoutingOptionsClassifier() {{"psurface", "unpaved_bad"}, RoutingOptions::Road::Dirty}, {{"psurface", "unpaved_good"}, RoutingOptions::Road::Dirty}, {{"highway", "steps"}, RoutingOptions::Road::Steps}, - {{"highway", "ladder"}, RoutingOptions::Road::Steps}}; + {{"highway", "ladder"}, RoutingOptions::Road::Steps}, + {{"psurface", "paved_good"}, RoutingOptions::Road::Paved}, + {{"psurface", "paved_bad"}, RoutingOptions::Road::Paved}}; m_data.Reserve(std::size(types)); for (auto const & data : types) @@ -108,6 +114,9 @@ RoutingOptions::Road ChooseMainRoutingOptionRoad(RoutingOptions options, bool is if (options.Has(RoutingOptions::Road::Steps)) return RoutingOptions::Road::Steps; + if (options.Has(RoutingOptions::Road::Paved)) + return RoutingOptions::Road::Paved; + return RoutingOptions::Road::Usual; } @@ -132,6 +141,7 @@ string DebugPrint(RoutingOptions const & routingOptions) append(RoutingOptions::Road::Ferry); append(RoutingOptions::Road::Dirty); append(RoutingOptions::Road::Steps); + append(RoutingOptions::Road::Paved); if (wasAppended) ss << " | "; @@ -150,6 +160,7 @@ string DebugPrint(RoutingOptions::Road type) case RoutingOptions::Road::Ferry: return "ferry"; case RoutingOptions::Road::Dirty: return "dirty"; case RoutingOptions::Road::Steps: return "steps"; + case RoutingOptions::Road::Paved: return "paved"; case RoutingOptions::Road::Usual: return "usual"; case RoutingOptions::Road::Max: return "max"; } diff --git a/libs/routing/routing_options.hpp b/libs/routing/routing_options.hpp index b7e53b667..8c510f3af 100644 --- a/libs/routing/routing_options.hpp +++ b/libs/routing/routing_options.hpp @@ -19,8 +19,9 @@ public: Ferry = 1u << 3, Dirty = 1u << 4, Steps = 1u << 5, + Paved = 1u << 6, - Max = (1u << 5) + 1 + Max = (1u << 6) + 1 }; using RoadType = std::underlying_type_t;