Check speed limit exceeded on the backend with respect to user locale.

[Android] Pass 'isSpeedLimitExceeded' to RoutingInfo. Use this flag to mark speedometer red.

Signed-off-by: S. Kozyr <s.trump@gmail.com>
This commit is contained in:
Sergiy Kozyr 2024-08-23 09:36:25 +03:00
parent 32da9eda66
commit cd4e9d6b6c
Signed by: strump
GPG key ID: C622E5563CAC205D
11 changed files with 47 additions and 6 deletions

View file

@ -1259,7 +1259,7 @@ Java_app_organicmaps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass)
jni::GetConstructorID(env, klass,
"(Lapp/organicmaps/util/Distance;Lapp/organicmaps/util/Distance;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;DIIIII"
"[Lapp/organicmaps/routing/SingleLaneInfo;DZZ)V");
"[Lapp/organicmaps/routing/SingleLaneInfo;DZZZ)V");
vector<routing::FollowingInfo::SingleLaneInfoClient> const & lanes = info.m_lanes;
jobjectArray jLanes = nullptr;
@ -1287,6 +1287,8 @@ Java_app_organicmaps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass)
}
auto const & rm = frm()->GetRoutingManager();
auto const * gpsInfo = fr->GetLastLocation();
auto const isSpeedLimitExceeded = routing::RoutingSession::IsSpeedLimitExceeded(gpsInfo->m_speed, info.m_speedLimitMps, measurement_utils::GetMeasurementUnits());
auto const isSpeedCamLimitExceeded = rm.IsRoutingActive() ? rm.IsSpeedCamLimitExceeded() : false;
auto const shouldPlaySignal = frm()->GetRoutingManager().GetSpeedCamManager().ShouldPlayBeepSignal();
jobject const result = env->NewObject(
@ -1294,8 +1296,8 @@ Java_app_organicmaps_Framework_nativeGetRouteFollowingInfo(JNIEnv * env, jclass)
ToJavaDistance(env, info.m_distToTurn), jni::ToJavaString(env, info.m_currentStreetName),
jni::ToJavaString(env, info.m_nextStreetName), jni::ToJavaString(env, info.m_nextNextStreetName),
info.m_completionPercent, info.m_turn, info.m_nextTurn, info.m_pedestrianTurn, info.m_exitNum,
info.m_time, jLanes, info.m_speedLimitMps, static_cast<jboolean>(isSpeedCamLimitExceeded),
static_cast<jboolean>(shouldPlaySignal));
info.m_time, jLanes, info.m_speedLimitMps, static_cast<jboolean>(isSpeedLimitExceeded),
static_cast<jboolean>(isSpeedCamLimitExceeded), static_cast<jboolean>(shouldPlaySignal));
ASSERT(result, (jni::DescribeException()));
return result;
}

View file

@ -37,6 +37,7 @@ public class RoutingInfo
// Current speed limit in meters per second.
// If no info about speed limit then speedLimitMps < 0.
public final double speedLimitMps;
public final boolean speedLimitExceeded;
private final boolean speedCamLimitExceeded;
private final boolean shouldPlayWarningSignal;
@ -144,7 +145,7 @@ public class RoutingInfo
public RoutingInfo(Distance distToTarget, Distance distToTurn, String currentStreet, String nextStreet, String nextNextStreet, double completionPercent,
int vehicleTurnOrdinal, int vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum,
int totalTime, SingleLaneInfo[] lanes, double speedLimitMps, boolean speedLimitExceeded,
boolean shouldPlayWarningSignal)
boolean speedCamLimitExceeded, boolean shouldPlayWarningSignal)
{
this.distToTarget = distToTarget;
this.distToTurn = distToTurn;
@ -159,7 +160,8 @@ public class RoutingInfo
this.exitNum = exitNum;
this.pedestrianTurnDirection = PedestrianTurnDirection.values()[pedestrianTurnOrdinal];
this.speedLimitMps = speedLimitMps;
this.speedCamLimitExceeded = speedLimitExceeded;
this.speedLimitExceeded = speedLimitExceeded;
this.speedCamLimitExceeded = speedCamLimitExceeded;
this.shouldPlayWarningSignal = shouldPlayWarningSignal;
}

View file

@ -222,7 +222,7 @@ public class NavMenu
else
mSpeedValue.setText(speedAndUnits.first);
if (info.speedLimitMps > 0.0 && last.getSpeed() > info.speedLimitMps)
if (info.speedLimitExceeded)
{
if (info.isSpeedCamLimitExceeded())
mSpeedValue.setTextColor(ContextCompat.getColor(mActivity, R.color.white_primary));

View file

@ -149,6 +149,11 @@ void Extrapolator::OnLocationUpdate(location::GpsInfo const & gpsInfo)
RunTaskOnBackgroundThread(false /* delayed */);
}
location::GpsInfo const * Extrapolator::GetLastLocation()
{
return &m_lastGpsInfo;
}
void Extrapolator::Enable(bool enabled)
{
lock_guard<mutex> guard(m_mutex);

View file

@ -52,6 +52,7 @@ public:
void OnLocationUpdate(location::GpsInfo const & gpsInfo);
// @TODO(bykoianko) Gyroscope information should be taken into account as well for calculation
// extrapolated position.
location::GpsInfo const * GetLastLocation();
void Enable(bool enabled);

View file

@ -190,6 +190,11 @@ void Framework::OnCompassUpdate(CompassInfo const & info)
m_drapeEngine->SetCompassInfo(rInfo);
}
GpsInfo const * Framework::GetLastLocation()
{
return m_routingManager.GetLastLocation();
}
void Framework::SwitchMyPositionNextMode()
{
if (m_drapeEngine != nullptr)

View file

@ -382,6 +382,7 @@ public:
void OnLocationError(location::TLocationError error);
void OnLocationUpdate(location::GpsInfo const & info);
void OnCompassUpdate(location::CompassInfo const & info);
location::GpsInfo const * GetLastLocation();
void SwitchMyPositionNextMode();
/// Should be set before Drape initialization. Guarantees that fn is called in main thread context.
void SetMyPositionModeListener(location::TMyPositionModeChanged && fn);

View file

@ -472,6 +472,11 @@ void RoutingManager::OnLocationUpdate(location::GpsInfo const & info)
m_extrapolator.OnLocationUpdate(info);
}
location::GpsInfo const * RoutingManager::GetLastLocation()
{
return m_extrapolator.GetLastLocation();
}
RouterType RoutingManager::GetBestRouter(m2::PointD const & startPoint,
m2::PointD const & finalPoint) const
{

View file

@ -252,6 +252,7 @@ public:
void OnRemoveRoute(routing::RouterResultCode code);
void OnRoutePointPassed(RouteMarkType type, size_t intermediateIndex);
void OnLocationUpdate(location::GpsInfo const & info);
location::GpsInfo const * GetLastLocation();
routing::SpeedCameraManager & GetSpeedCamManager() { return m_routingSession.GetSpeedCamManager(); }
bool IsSpeedCamLimitExceeded() const;

View file

@ -465,6 +465,20 @@ double RoutingSession::GetCompletionPercent() const
return percent;
}
bool RoutingSession::IsSpeedLimitExceeded(double currentSpeedMps, double speedLimitMps,
const measurement_utils::Units units)
{
if (currentSpeedMps <= 0 || speedLimitMps <= 0)
return false;
// First convert meters/s to localized units
double currentSpeedLocal = measurement_utils::MpsToUnits(currentSpeedMps, units);
double speedLimitLocal = measurement_utils::MpsToUnits(speedLimitMps, units);
// Floor speed and limit speed before comparison
return static_cast<int>(currentSpeedLocal) > static_cast<int>(speedLimitLocal);
}
void RoutingSession::PassCheckpoints()
{
CHECK_THREAD_CHECKER(m_threadChecker, ());

View file

@ -174,6 +174,11 @@ public:
double GetCompletionPercent() const;
// Convert speed and speed limit from meters/sec to miles/h or km/h.
// If current speed is the less or equal to max allowed speed then return false.
// We do comparison using floored speed values because on UI user see such values.
static bool IsSpeedLimitExceeded(double currentSpeedMps, double speedLimitMps, measurement_utils::Units units);
private:
struct DoReadyCallback
{