Cllocationmanager and Accuracy Issues - Any Experiences

CLLocationManager and accuracy issues - any experiences?

I don't remember which project it was exactly that I got the following code from, but this has worked for me really well (I do remember it was from a WWDC 2010 video). In my code, I left the comments from the original project in tact so hopefully this will help.

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// test the age of the location measurement to determine if the measurement is cached
// in most cases you will not want to rely on cached measurements
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];

if (locationAge > 5.0) return;

// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;

// test the measurement to see if it is more accurate than the previous measurement
if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
// store the location as the "best effort"
self.bestEffortAtLocation = newLocation;

// test the measurement to see if it meets the desired accuracy
//
// IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue
// accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of
// acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout.
//
if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
// we have a measurement that meets our requirements, so we can stop updating the location
//
// IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible.
//
[self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")];

// we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];
}
}
}

Hope this helps!

Via GetLocationViewController.m in Apple's "Locate Me" sample project, available at:

https://developer.apple.com/library/content/samplecode/LocateMe/Introduction/Intro.html

Detect when optimal location accuracy is reached with CLLocationManager

IN the CLLocationManagerDelegate method locationManager:didUpdateLocations: look at the horizontalAccuracy of CLLocation. This will give you the radius in meters.

As stated in documentation:

The radius of uncertainty for the location, measured in meters.
(read-only)

The location manager will keep trying in getting the best accuracy as possible, so you will have to decide when the location is accurate enough.

[iOS][Background][CLLocationManager]Bad map accuracy

Fixed you have to use only one way to locate your device with the CLLocationManager or the MapView. ;)

Why is CLLocationManager so lazy when set with a low accuracy?

The more granular settings will attempt to locate you via Cell and Wi-Fi triangulation only, which isn't exact. kCLLocationAccuracyBest is going to turn on the GPS module and use it, which should get within a few feet. It's not a bug, you got the accuracy you asked for in both cases.

The difference is because the GPS burns the battery a lot more than triangulation, which is why it's not used if you just need to place the device within a rough area.

CLLocationManager not returning correct location

Its bit older post and I am having basic knowledge in CLLocationManager stuff, but still I am trying to address the problem. I understand from your above code that CLLocationManager is recreated everytime. CLLocationManager is like a singleton class you don't need to recreate everytime. You just need to call [locationManager startUpdatingLocation]; .

Also everytime you are calling [geocoder reverseGeocodeLocation:xxx]. Probably you need to find accuracy before you do this so that it will not get called again and again.

Why is CLLocationManager so lazy when set with a low accuracy?

The more granular settings will attempt to locate you via Cell and Wi-Fi triangulation only, which isn't exact. kCLLocationAccuracyBest is going to turn on the GPS module and use it, which should get within a few feet. It's not a bug, you got the accuracy you asked for in both cases.

The difference is because the GPS burns the battery a lot more than triangulation, which is why it's not used if you just need to place the device within a rough area.

CLLocationManager responsiveness

OK, a couple of things could improve your lag. First of all, use kCLLocationAccuracyBestForNavigation always. There is no real battery usage difference between that and kCLLocationAccuracyBest, they both use the GPS at top speed. The main difference is in the post-processing that Apple does.

Second, there is no need to filter for speed == 0. Apple already does that filtering: if your speed from the GPS drops below a certain threshold (about 4 km/h), the OS assumes you are standing still, and it substitutes the same location value for all subsequent samples. It does that until it thinks you are moving again. I assume they do that to avoid "jittering" on the map when you are standing still. In fact, speed drops to 0 already for the last real value of a sequence of "standing-still" values, so if you filter on speed == 0 than you are missing one real GPS sample.

Unfortunately, they is no way to avoid that filtering and get real GPS samples. I talked to Apple about it, and their response was that they are not going to change the behaviour. kCLLocationAccuracyBestForNavigation does less aggressive filtering than kCLLocationAccuracyBest, so it's best to use that.

Third, you probably are already doing this, but make sure that you call "setNeedsDisplay" on your view right from the "didUpdateFromLocation:", to make sure that the map is actually redrawn.

If you do all that, you should have a lag of about 1 second. If you want to improve on the 1 second than you can try to use predictive techniques. From the last two locations, and the given speed, you can calculate where the next location is likely to be, and already display that location. I have had mixed results with that. It works well for fast movement that does not change speed suddenly, like driving a car. It works less well for slower movement like walking or biking.

Heading accuracy is coming up negative

A negative headingAccuracy value simply means that the compass cannot get a good reading at the moment. Perhaps the phone is near some strong magnetic field or you need to wave it in a figure 8 to calibrate the compass. It doesn't mean your code is incorrect.

Just ignore the heading updates where the headingAccuracy < 0, and only use the other values you get. This is normal behaviour.

startMonitoringSignificantLocationChanges Lack of Accuracy

From the CLLocationManager docs:

This interface [e.g, startMonitoringSignificantLocationChanges] delivers new events only when it detects changes to the device’s associated cell towers, resulting in less frequent updates and significantly lower power usage.

As such, it's unlikely that startMonitoringSignificantLocationChanges can be used to check for locations at the level of accuracy you're looking for -- it's rare that a cell tower can localize you that well. You may want to try using startMonitoringForRegion:desiredAccuracy: instead; it also works in the background, and will do a lot of the dirty work of hit-testing the region for you.



Related Topics



Leave a reply



Submit