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}