-
Notifications
You must be signed in to change notification settings - Fork 134
/
DistanceAccuracyLocationFilter.java
58 lines (51 loc) · 2.58 KB
/
DistanceAccuracyLocationFilter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.here.hikingdiary.locationfilter;
import com.here.sdk.core.GeoCoordinates;
import com.here.sdk.core.Location;
/*
* The DistanceAccuracyLocationFilter class implements the LocationFilterInterface and provides a filtering strategy based on accuracy
* and distance from last accepted location. This class works on two filter mechanisms.
* AccuracyFilter - Filters the location data based on the accuracy of the GPS readings, and only includes the readings with a certain level of accuracy.
* DistanceFilter - Filters the location data based on the locations that are within the specified distance from the last accepted location.
*/
public class DistanceAccuracyLocationFilter implements LocationFilterInterface {
// These two parameters define if incoming location updates are considered to be good enough.
// In the field, the GPS signal can be very unreliable, so we need to filter out inaccurate signals.
private static final double ACCURACY_RADIUS_THRESHOLD_IN_METERS = 10.0;
private static final double DISTANCE_THRESHOLD_IN_METERS = 15.0;
private GeoCoordinates lastAcceptedGeoCoordinates;
@Override
public boolean checkIfLocationCanBeUsed(Location location) {
if (isAccuracyGoodEnough(location) && isDistanceFarEnough(location)) {
lastAcceptedGeoCoordinates = location.coordinates;
return true;
}
return false;
}
// Checks if the accuracy of the received GPS signal is good enough.
private boolean isAccuracyGoodEnough(Location location) {
Double horizontalAccuracyInMeters = location.horizontalAccuracyInMeters;
if (horizontalAccuracyInMeters == null) {
return false;
}
// If the location lies within the radius of ACCURACY_RADIUS_THRESHOLD_IN_METERS then we accept it.
if (horizontalAccuracyInMeters <= ACCURACY_RADIUS_THRESHOLD_IN_METERS) {
return true;
}
return false;
}
// Checks if last accepted location is farther away than xx meters.
// If it is, the new location will be accepted.
// This way we can filter out signals that are caused by a non-moving user.
private boolean isDistanceFarEnough(Location location) {
if (lastAcceptedGeoCoordinates == null) {
// We always accept the first location.
lastAcceptedGeoCoordinates = location.coordinates;
return true;
}
double distance = location.coordinates.distanceTo(lastAcceptedGeoCoordinates);
if (distance >= DISTANCE_THRESHOLD_IN_METERS) {
return true;
}
return false;
}
}