diff --git a/android/jni/app/organicmaps/Framework.cpp b/android/jni/app/organicmaps/Framework.cpp index 241e8c3ba7..407e73e852 100644 --- a/android/jni/app/organicmaps/Framework.cpp +++ b/android/jni/app/organicmaps/Framework.cpp @@ -1210,6 +1210,8 @@ Java_app_organicmaps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass) routing::FollowingInfo info; fr->GetRoutingManager().GetRouteFollowingInfo(info); + if (!info.IsValid()) + return nullptr; static jclass const klass = jni::GetGlobalClassRef(env, "app/organicmaps/routing/RoutingInfo"); // Java signature : RoutingInfo(Distance distToTarget, Distance distToTurn, diff --git a/android/src/app/organicmaps/routing/NavigationController.java b/android/src/app/organicmaps/routing/NavigationController.java index 67189a8060..b51831d2ab 100644 --- a/android/src/app/organicmaps/routing/NavigationController.java +++ b/android/src/app/organicmaps/routing/NavigationController.java @@ -9,7 +9,6 @@ import android.content.ServiceConnection; import android.media.MediaPlayer; import android.os.Bundle; import android.os.IBinder; -import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.view.View; import android.widget.ImageView; @@ -179,10 +178,9 @@ public class NavigationController implements Application.ActivityLifecycleCallba mService.stopForeground(true); } - private void updateVehicle(RoutingInfo info) + private void updateVehicle(@NonNull RoutingInfo info) { - SpannableStringBuilder nextTurnDistance = Utils.formatDistance(mFrame.getContext(), info.distToTurn); - mNextTurnDistance.setText(nextTurnDistance); + mNextTurnDistance.setText(Utils.formatDistance(mFrame.getContext(), info.distToTurn)); info.carDirection.setTurnDrawable(mNextTurnImage); if (RoutingInfo.CarDirection.isRoundAbout(info.carDirection)) @@ -206,7 +204,7 @@ public class NavigationController implements Application.ActivityLifecycleCallba } } - private void updatePedestrian(RoutingInfo info) + private void updatePedestrian(@NonNull RoutingInfo info) { mNextTurnDistance.setText(Utils.formatDistance(mFrame.getContext(), info.distToTurn)); diff --git a/android/src/app/organicmaps/util/Distance.java b/android/src/app/organicmaps/util/Distance.java index 69db625b33..10f1cb62d5 100644 --- a/android/src/app/organicmaps/util/Distance.java +++ b/android/src/app/organicmaps/util/Distance.java @@ -43,6 +43,11 @@ public final class Distance mUnits = Units.values()[unitsIndex]; } + public boolean isValid() + { + return mDistance >= 0.0; + } + @NonNull public String getUnitsStr(@NonNull final Context context) { @@ -52,6 +57,9 @@ public final class Distance @NonNull public String toString(@NonNull final Context context) { + if (!isValid()) + return ""; + return mDistanceStr + NON_BREAKING_SPACE + getUnitsStr(context); } @@ -59,6 +67,9 @@ public final class Distance @Override public String toString() { + if (!isValid()) + return ""; + return mDistanceStr + NON_BREAKING_SPACE + mUnits.toString(); } } diff --git a/android/src/app/organicmaps/util/Utils.java b/android/src/app/organicmaps/util/Utils.java index 5481e1f669..fbd46542e2 100644 --- a/android/src/app/organicmaps/util/Utils.java +++ b/android/src/app/organicmaps/util/Utils.java @@ -16,6 +16,7 @@ import android.os.Build; import android.os.Bundle; import android.provider.Settings; import android.text.Html; +import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; @@ -365,7 +366,7 @@ public class Utils } @NonNull - public static SpannableStringBuilder formatDistance(Context context, @NonNull Distance distance) + public static Spannable formatDistance(Context context, @NonNull Distance distance) { final SpannableStringBuilder res = new SpannableStringBuilder(distance.toString(context)); res.setSpan( diff --git a/iphone/Maps/Core/Framework/ProxyObjects/Routing/MWMRoutingManager.mm b/iphone/Maps/Core/Framework/ProxyObjects/Routing/MWMRoutingManager.mm index 62cbf2823a..75d861e139 100644 --- a/iphone/Maps/Core/Framework/ProxyObjects/Routing/MWMRoutingManager.mm +++ b/iphone/Maps/Core/Framework/ProxyObjects/Routing/MWMRoutingManager.mm @@ -77,14 +77,16 @@ } - (MWMRouteInfo *)routeInfo { - if (!self.isRoutingActive) { return nil; } + if (!self.isRoutingActive) + return nil; routing::FollowingInfo info; self.rm.GetRouteFollowingInfo(info); + if (!info.IsValid()) + return nil; CLLocation * lastLocation = [MWMLocationManager lastLocation]; double speedMps = 0; - if (lastLocation && lastLocation.speed >= 0) { + if (lastLocation && lastLocation.speed >= 0) speedMps = lastLocation.speed; - } NSInteger roundExitNumber = 0; if (info.m_turn == routing::turns::CarDirection::EnterRoundAbout || info.m_turn == routing::turns::CarDirection::StayOnRoundAbout || diff --git a/iphone/Maps/Core/Routing/MWMRouter.mm b/iphone/Maps/Core/Routing/MWMRouter.mm index 24f275e4e0..90390bd073 100644 --- a/iphone/Maps/Core/Routing/MWMRouter.mm +++ b/iphone/Maps/Core/Routing/MWMRouter.mm @@ -344,6 +344,8 @@ char const *kRenderAltitudeImagesQueueLabel = "mapsme.mwmrouter.renderAltitudeIm auto const &rm = GetFramework().GetRoutingManager(); routing::FollowingInfo info; rm.GetRouteFollowingInfo(info); + if (!info.IsValid()) + return; auto navManager = [MWMNavigationDashboardManager sharedManager]; if ([MWMRouter type] == MWMRouterTypePublicTransport) [navManager updateTransitInfo:rm.GetTransitRouteInfo()]; diff --git a/platform/distance.cpp b/platform/distance.cpp index c72971d72d..83ede6de4d 100644 --- a/platform/distance.cpp +++ b/platform/distance.cpp @@ -65,14 +65,11 @@ double WithPrecision(double value, uint8_t precision) } } // namespace -Distance::Distance() : Distance(0.0) {} +Distance::Distance() : Distance(-1.0) {} Distance::Distance(double distanceInMeters) : Distance(distanceInMeters, Units::Meters) {} -Distance::Distance(double distance, platform::Distance::Units units) - : m_distance(distance), m_units(units) -{ -} +Distance::Distance(double distance, platform::Distance::Units units) : m_distance(distance), m_units(units) {} Distance Distance::CreateFormatted(double distanceInMeters) { @@ -82,13 +79,14 @@ Distance Distance::CreateFormatted(double distanceInMeters) Distance Distance::CreateAltitudeFormatted(double meters) { Distance elevation = Distance(meters).To( - measurement_utils::GetMeasurementUnits() == measurement_utils::Units::Metric ? Units::Meters - : Units::Feet); + measurement_utils::GetMeasurementUnits() == measurement_utils::Units::Metric ? Units::Meters : Units::Feet); if (elevation.IsLowUnits()) elevation.m_distance = WithPrecision(elevation.m_distance, 0); return elevation; } +bool Distance::IsValid() const { return m_distance >= 0.0; } + bool Distance::IsLowUnits() const { return m_units == Units::Meters || m_units == Units::Feet; } bool Distance::IsHighUnits() const { return !IsLowUnits(); } @@ -110,18 +108,22 @@ Distance Distance::To(Distance::Units units) const Distance Distance::ToPlatformUnitsFormatted() const { - return To(measurement_utils::GetMeasurementUnits() == measurement_utils::Units::Metric - ? Units::Meters - : Units::Feet) + return To(measurement_utils::GetMeasurementUnits() == measurement_utils::Units::Metric ? Units::Meters : Units::Feet) .GetFormattedDistance(); } -double Distance::GetDistance() const { return m_distance; } +double Distance::GetDistance() const +{ + return m_distance; +} Distance::Units Distance::GetUnits() const { return m_units; } std::string Distance::GetDistanceString() const { + if (!IsValid()) + return ""; + std::ostringstream os; os << std::defaultfloat << m_distance; return os.str(); @@ -141,7 +143,8 @@ std::string Distance::GetUnitsString() const Distance Distance::GetFormattedDistance() const { - ASSERT_GREATER_OR_EQUAL(m_distance, 0.0, ("Distance is not valid: ", *this)); + ASSERT(IsValid(), ()); + Distance newDistance = *this; int precision = 0; @@ -182,6 +185,9 @@ Distance Distance::GetFormattedDistance() const std::string Distance::ToString() const { + if (!IsValid()) + return ""; + return GetDistanceString() + " " + GetUnitsString(); } diff --git a/platform/distance.hpp b/platform/distance.hpp index d201d84d6f..4fca5dcb9c 100644 --- a/platform/distance.hpp +++ b/platform/distance.hpp @@ -36,6 +36,8 @@ public: /// \warning GetFormattedDistance() will transform it to high units static Distance CreateAltitudeFormatted(double meters); + bool IsValid() const; + bool IsLowUnits() const; bool IsHighUnits() const; diff --git a/platform/platform_tests/distance_tests.cpp b/platform/platform_tests/distance_tests.cpp index edafb41bc8..32ecc67959 100644 --- a/platform/platform_tests/distance_tests.cpp +++ b/platform/platform_tests/distance_tests.cpp @@ -9,8 +9,7 @@ namespace platform struct ScopedSettings { /// Saves/restores previous units and sets new units for a scope. - explicit ScopedSettings(measurement_utils::Units newUnits) - : m_oldUnits(measurement_utils::Units::Metric) + explicit ScopedSettings(measurement_utils::Units newUnits) : m_oldUnits(measurement_utils::Units::Metric) { m_wasSet = settings::Get(settings::kMeasurementUnits, m_oldUnits); settings::Set(settings::kMeasurementUnits, newUnits); @@ -28,6 +27,15 @@ struct ScopedSettings measurement_utils::Units m_oldUnits; }; +UNIT_TEST(Distance_InititalDistance) +{ + Distance d; + TEST(!d.IsValid(), ()); + TEST_ALMOST_EQUAL_ULPS(d.GetDistance(), -1.0, ()); + TEST_EQUAL(d.GetDistanceString(), "", ()); + TEST_EQUAL(d.ToString(), "", ()); +} + UNIT_TEST(Distance_CreateFormatted) { { @@ -307,7 +315,7 @@ UNIT_TEST(Distance_FormattedDistance) { Distance const formattedDistance = data.distance.GetFormattedDistance(); // Run two times to verify that nothing breaks after second format - for (const auto & d : {formattedDistance, formattedDistance.GetFormattedDistance()}) + for (auto const & d : {formattedDistance, formattedDistance.GetFormattedDistance()}) { TEST_ALMOST_EQUAL_ULPS(d.GetDistance(), data.formattedDistance, (data.distance.ToString())); TEST_EQUAL(d.GetUnits(), data.formattedUnits, (data.distance.ToString())); diff --git a/routing/following_info.hpp b/routing/following_info.hpp index efe2aac98c..04f06905ef 100644 --- a/routing/following_info.hpp +++ b/routing/following_info.hpp @@ -46,6 +46,8 @@ public: } }; + bool IsValid() const { return m_distToTarget.IsValid(); } + /// @name Formatted covered distance. platform::Distance m_distToTarget;