1package eu.siacs.conversations.ui.util;
2
3import android.location.Location;
4
5import org.osmdroid.util.GeoPoint;
6
7import eu.siacs.conversations.Config;
8
9public final class LocationHelper {
10 /**
11 * Parses a lat long string in the form "lat,long".
12 *
13 * @param latlong A string in the form "lat,long"
14 * @return A GeoPoint representing the lat,long string.
15 * @throws NumberFormatException If an invalid lat or long is specified.
16 */
17 public static GeoPoint parseLatLong(final String latlong) throws NumberFormatException {
18 if (latlong == null || latlong.isEmpty()) {
19 return null;
20 }
21
22 final String[] parts = latlong.split(",");
23 if (parts[1].contains("?")) {
24 parts[1] = parts[1].substring(0, parts[1].indexOf("?"));
25 }
26 return new GeoPoint(Double.valueOf(parts[0]), Double.valueOf(parts[1]));
27 }
28
29 private static boolean isSameProvider(final String provider1, final String provider2) {
30 if (provider1 == null) {
31 return provider2 == null;
32 }
33 return provider1.equals(provider2);
34 }
35
36 public static boolean isBetterLocation(final Location location, final Location prevLoc) {
37 if (prevLoc == null) {
38 return true;
39 }
40
41 // Check whether the new location fix is newer or older
42 final long timeDelta = location.getTime() - prevLoc.getTime();
43 final boolean isSignificantlyNewer = timeDelta > Config.Map.LOCATION_FIX_SIGNIFICANT_TIME_DELTA;
44 final boolean isSignificantlyOlder = timeDelta < -Config.Map.LOCATION_FIX_SIGNIFICANT_TIME_DELTA;
45 final boolean isNewer = timeDelta > 0;
46
47 if (isSignificantlyNewer) {
48 return true;
49 } else if (isSignificantlyOlder) {
50 return false;
51 }
52
53 // Check whether the new location fix is more or less accurate
54 final int accuracyDelta = (int) (location.getAccuracy() - prevLoc.getAccuracy());
55 final boolean isLessAccurate = accuracyDelta > 0;
56 final boolean isMoreAccurate = accuracyDelta < 0;
57 final boolean isSignificantlyLessAccurate = accuracyDelta > 200;
58
59 // Check if the old and new location are from the same provider
60 final boolean isFromSameProvider = isSameProvider(location.getProvider(), prevLoc.getProvider());
61
62 // Determine location quality using a combination of timeliness and accuracy
63 if (isMoreAccurate) {
64 return true;
65 } else if (isNewer && !isLessAccurate) {
66 return true;
67 } else return isNewer && !isSignificantlyLessAccurate && isFromSameProvider;
68 }
69}