mirror of
https://codeberg.org/comaps/comaps
synced 2026-01-04 20:03:45 +00:00
[android] Fix most accurate location provider
Signed-off-by: gekeleda <mail@davidgekeler.eu>
This commit is contained in:
committed by
Konstantin Pastbin
parent
6073cd1ca3
commit
f3fd814d07
@@ -27,6 +27,8 @@ import app.organicmaps.sdk.util.NetworkPolicy;
|
||||
import app.organicmaps.sdk.util.log.Logger;
|
||||
import org.chromium.base.ObserverList;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class LocationHelper implements BaseLocationProvider.Listener
|
||||
{
|
||||
private static final long INTERVAL_MS = 500;
|
||||
@@ -56,6 +58,12 @@ public class LocationHelper implements BaseLocationProvider.Listener
|
||||
private Handler mHandler;
|
||||
private Runnable mLocationTimeoutRunnable = this::notifyLocationUpdateTimeout;
|
||||
|
||||
private static final double INTERVAL_PROVIDER_DECISION = 3.0; // seconds
|
||||
private final HashMap<String, Integer> mProviderLocationCounts = new HashMap<>();
|
||||
private final HashMap<String, Float> mProviderAccuracyMeans = new HashMap<>();
|
||||
private double mTimeAtLastProviderChange = Double.NaN;
|
||||
private String mCurrentProvider = null;
|
||||
|
||||
@NonNull
|
||||
private final GnssStatusCompat.Callback mGnssStatusCallback = new GnssStatusCompat.Callback() {
|
||||
@Override
|
||||
@@ -187,7 +195,6 @@ public class LocationHelper implements BaseLocationProvider.Listener
|
||||
@Override
|
||||
public void onLocationChanged(@NonNull Location location)
|
||||
{
|
||||
Logger.d(TAG, "provider = " + mLocationProvider.getClass().getSimpleName() + " location = " + location);
|
||||
|
||||
if (!isActive())
|
||||
{
|
||||
@@ -201,21 +208,68 @@ public class LocationHelper implements BaseLocationProvider.Listener
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSavedLocation != null)
|
||||
{
|
||||
if (!LocationUtils.isLocationBetterThanLast(location, mSavedLocation))
|
||||
{
|
||||
Logger.d(TAG, "The new " + location + " is worse than the last " + mSavedLocation);
|
||||
// if (mSavedLocation != null)
|
||||
// {
|
||||
// if (!LocationUtils.isLocationBetterThanLast(location, mSavedLocation))
|
||||
// {
|
||||
// Logger.d(TAG, "The new " + location + " is worse than the last " + mSavedLocation);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
updateProviderDecision(location);
|
||||
if(mCurrentProvider == null || !mCurrentProvider.equals(location.getProvider())) {
|
||||
Logger.d(TAG, "Rejected update from provider = " + location.getProvider());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.d(TAG, "provider = " + mLocationProvider.getClass().getSimpleName() + " location = " + location);
|
||||
|
||||
mSavedLocation = location;
|
||||
mMyPosition = null;
|
||||
notifyLocationUpdated();
|
||||
}
|
||||
|
||||
// Used by GoogleFusedLocationProvider.
|
||||
private void updateProviderDecision(Location location) {
|
||||
if(Double.isNaN(mTimeAtLastProviderChange))
|
||||
mTimeAtLastProviderChange = location.getElapsedRealtimeNanos() * 1.0E-9;
|
||||
|
||||
String provider = location.getProvider();
|
||||
int count = mProviderLocationCounts.getOrDefault(provider, 0);
|
||||
float average = mProviderAccuracyMeans.getOrDefault(provider, 0.0f);
|
||||
|
||||
float accuracy = location.getAccuracy();
|
||||
float newAverage = (count * average + accuracy) / (count + 1);
|
||||
|
||||
mProviderLocationCounts.put(provider, count + 1);
|
||||
mProviderAccuracyMeans.put(provider, newAverage);
|
||||
|
||||
double currentTime = location.getElapsedRealtimeNanos();
|
||||
double timeDiff = (currentTime - mTimeAtLastProviderChange) * 1.0E-9;
|
||||
|
||||
if(timeDiff > INTERVAL_PROVIDER_DECISION) {
|
||||
mCurrentProvider = getMinAccuracyProvider();
|
||||
Logger.d("ProviderDecision", "Selected: " + mCurrentProvider + ", with acc. " + mProviderAccuracyMeans.get(mCurrentProvider));
|
||||
mTimeAtLastProviderChange = currentTime;
|
||||
mProviderLocationCounts.clear();
|
||||
mProviderAccuracyMeans.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private String getMinAccuracyProvider() {
|
||||
String minAccuracyProvider = null;
|
||||
float minAccuracy = Float.MAX_VALUE;
|
||||
for(String p : mProviderAccuracyMeans.keySet()) {
|
||||
float pAccuracy = mProviderAccuracyMeans.get(p);
|
||||
if(pAccuracy < minAccuracy) {
|
||||
minAccuracy = pAccuracy;
|
||||
minAccuracyProvider = p;
|
||||
}
|
||||
}
|
||||
return minAccuracyProvider;
|
||||
}
|
||||
|
||||
// Used by GoogleFusedLocationProvider.
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
@UiThread
|
||||
|
||||
Reference in New Issue
Block a user