[android] Add average speed calculation and change speed view to display it

Signed-off-by: David Gekeler <git@davidgekeler.eu>
This commit is contained in:
David Gekeler
2025-06-06 17:54:13 +02:00
committed by Konstantin Pastbin
parent 24c9802a2a
commit f960b3959f
2 changed files with 60 additions and 3 deletions

View File

@@ -18,6 +18,7 @@ import app.organicmaps.R;
import app.organicmaps.maplayer.MapButtonsViewModel;
import app.organicmaps.sdk.Framework;
import app.organicmaps.sdk.Router;
import app.organicmaps.sdk.location.LocationHelper;
import app.organicmaps.sdk.maplayer.traffic.TrafficManager;
import app.organicmaps.sdk.routing.CarDirection;
import app.organicmaps.sdk.routing.RoutingController;
@@ -267,16 +268,18 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav
private void updateSpeedWidgets(@NonNull final RoutingInfo info)
{
final Location location = MwmApplication.from(mFrame.getContext()).getLocationHelper().getSavedLocation();
final LocationHelper locationHelper = MwmApplication.from(mFrame.getContext()).getLocationHelper();
final Location location = locationHelper.getSavedLocation();
if (location == null)
{
mSpeedLimit.setSpeedLimit(-1, false);
mCurrentSpeed.setCurrentSpeed(-1);
return;
}
final double currentAvgSpeed = locationHelper.getAverageSpeed();
final int fSpeedLimit = StringUtils.nativeFormatSpeed(info.speedLimitMps);
final boolean speedLimitExceeded = fSpeedLimit < StringUtils.nativeFormatSpeed(location.getSpeed());
final boolean speedLimitExceeded = fSpeedLimit < StringUtils.nativeFormatSpeed(currentAvgSpeed);
mSpeedLimit.setSpeedLimit(fSpeedLimit, speedLimitExceeded);
mCurrentSpeed.setCurrentSpeed(location.getSpeed());
mCurrentSpeed.setCurrentSpeed(currentAvgSpeed);
}
}

View File

@@ -26,6 +26,7 @@ import app.organicmaps.sdk.util.LocationUtils;
import app.organicmaps.sdk.util.NetworkPolicy;
import app.organicmaps.sdk.util.log.Logger;
import org.chromium.base.ObserverList;
import java.util.ArrayList;
public class LocationHelper implements BaseLocationProvider.Listener
{
@@ -35,6 +36,8 @@ public class LocationHelper implements BaseLocationProvider.Listener
private static final long AGPS_EXPIRATION_TIME_MS = 16 * 60 * 60 * 1000; // 16 hours
private static final long LOCATION_UPDATE_TIMEOUT_MS = 30 * 1000; // 30 seconds
private static final double SPEED_AVERAGING_TIME = 0.5; // 0.5 seconds
@NonNull
private final Context mContext;
@NonNull
@@ -56,6 +59,10 @@ public class LocationHelper implements BaseLocationProvider.Listener
private Handler mHandler;
private Runnable mLocationTimeoutRunnable = this::notifyLocationUpdateTimeout;
private double mTimeElapsedAtLastAverage = Double.NaN;
private float mLastAverageSpeed = Float.NaN;
private ArrayList<Float> mSpeedHistory = new ArrayList<>();
@NonNull
private final GnssStatusCompat.Callback mGnssStatusCallback = new GnssStatusCompat.Callback() {
@Override
@@ -167,6 +174,8 @@ public class LocationHelper implements BaseLocationProvider.Listener
mSavedLocation.getLongitude(), mSavedLocation.getAccuracy(),
mSavedLocation.getAltitude(), mSavedLocation.getSpeed(),
mSavedLocation.getBearing());
updateSpeedHistory();
}
private void notifyLocationUpdateTimeout()
@@ -479,4 +488,49 @@ public class LocationHelper implements BaseLocationProvider.Listener
Framework.nativeRunFirstLaunchAnimation();
}
}
private void updateSpeedHistory()
{
if (mSavedLocation == null)
{
return;
}
if (Double.isNaN(mTimeElapsedAtLastAverage))
{
mTimeElapsedAtLastAverage = mSavedLocation.getElapsedRealtimeNanos() * 1.0E-9;
}
mSpeedHistory.add(mSavedLocation.getSpeed());
}
public float getAverageSpeed()
{
if (mSavedLocation == null)
{
return Float.NaN;
}
if (Double.isNaN(mTimeElapsedAtLastAverage))
{
updateSpeedHistory();
}
if (mSavedLocation.getElapsedRealtimeNanos() * 1.0E-9 - mTimeElapsedAtLastAverage < SPEED_AVERAGING_TIME)
{
if (!Float.isNaN(mLastAverageSpeed))
{
return mLastAverageSpeed;
}
else
{
return mSavedLocation.getSpeed();
}
}
else
{
mLastAverageSpeed = mSpeedHistory.stream().reduce(0.0F, Float::sum);
mLastAverageSpeed /= mSpeedHistory.size();
mSpeedHistory.clear();
mTimeElapsedAtLastAverage = mSavedLocation.getElapsedRealtimeNanos() * 1.0E-9;
return mLastAverageSpeed;
}
}
}