I am using Location Services
in a few of my apps. I have a method that I use in my locationManager:didUpdateToLocation:fromLocation:
method to filter out bad, inaccurate or too far away locations. And to minimize gps "jitter". Here is what I use:
/**
* Check if we have a valid location
*
* @version $Revision: 0.1
*/
+ (BOOL)isValidLocation:(CLLocation *)newLocation withOldLocation:(CLLocation *)oldLocation {
// Filter out nil locations
if (!newLocation) return NO;
// Filter out points by invalid accuracy
if (newLocation.horizontalAccuracy < 0) return NO;
if (newLocation.horizontalAccuracy > 66) return NO;
// Filter out points by invalid accuracy
#if !TARGET_IPHONE_SIMULATOR
if (newLocation.verticalAccuracy < 0) return NO;
#endif
// Filter out points that are out of order
NSTimeInterval secondsSinceLastPoint = [newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp];
if (secondsSinceLastPoint < 0) return NO;
// Make sure the update is new not cached
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return NO;
// Check to see if old and new are the same
if ((oldLocation.coordinate.latitude == newLocation.coordinate.latitude) && (oldLocation.coordinate.longitude == newLocation.coordinate.longitude))
return NO;
return YES;
}//end
Does anyone have any improvements on this method to make it more accurate? Is 66 too high of a horizontalAccuracy
and will receive lots of invalid locations? Should I lower this?
Is there a way to get rid of the "jitter" that gps on the iPhone gives?
You can checkout this
https://medium.com/@mizutori/make-it-even-better-than-nike-how-to-filter-locations-tracking-highly-accurate-location-in-774be045f8d6
The main idea is to filer the data in method didUpdateLocation:
The filter method is just like this:
func filterAndAddLocation(_ location: CLLocation) -> Bool {
let age = -location.timestamp.timeIntervalSinceNow
if age > 10 {
return false
}
if location.horizontalAccuracy < 0 {
return false
}
if location.horizontalAccuracy > 100 {
return false
}
locationDataArray.append(location)
return true
}
In addition to these there is one more I use:
if(self.lastKnownLocation)
{
CLLocationDistance dist = [newLocation distanceFromLocation:self.lastKnownLocation];
if(dist > newLocation.horizontalAccuracy)
{
//.....
}
}
Where self.lastKnownLocation
is actually the last valid location I have and it's a:
@property(nonatomic, copy) CLLocation *lastKnownLocation;
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if (!newLocation)
{
NSLog(@"Filter out points by invalid accuracy");
return;
}
// Filter out points by invalid accuracy
if (newLocation.horizontalAccuracy < 0)
{
return;
}
if(oldLocation.coordinate.latitude>90 && oldLocation.coordinate.latitude<-90 && oldLocation.coordinate.longitude>180 && oldLocation.coordinate.longitude<-180)
{
NSLog(@"old");
return;
}
if(newLocation.coordinate.latitude>90 || newLocation.coordinate.latitude<-90 || newLocation.coordinate.longitude>180 || newLocation.coordinate.longitude<-180)
{
NSLog(@"new");
return;
}
///////
NSDate *eventDate=newLocation.timestamp;
NSTimeInterval eventinterval=[eventDate timeIntervalSinceNow];
if (abs(eventinterval)<30.0)
{
if (newLocation.horizontalAccuracy>=0 && newLocation.horizontalAccuracy<20)
{
**//finally you are getting right updated value here....**
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With