Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait until location is completely found? (Core Location)

I have a problem within my app. I'm trying to find the user's location to the best preciseness in order to determine their zip-code. Currently I have a button that, when pressed, starts a method named locateMe.

-(IBAction)locateMe; {
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];

Then I've implemented didUpdateToLocation:

-(void)locationManager:(CLLocationManager *)manager 
       didUpdateToLocation:(CLLocation *)newLocation
       fromLocation:(CLLocation *)oldLocation; { 

       NSLog(@"Found location! %f,%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
 }

I had previously done much more complicated stuff in didUpdateToLocation but as I tested some things I realized that the first location it found was not precise in the least. So, I put the NSLog call in there and it gave me an output similar to below...

Found location! 39.594093,-98.614834
Found location! 39.601372,-98.592171
Found location! 39.601372,-98.592171
Found location! 39.611444,-98.538196
Found location! 39.611444,-98.538196

As you can see, it first gives me a value which is not correct, which was causing problems within my app because it wasn't giving the correct location.

So, here's my question. Is there any way I can wait for the location manager to finish finding the most precise location?

Thanks in advance!

EDIT: I'm wanting something like this:

if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
}

But it never gets called!

like image 546
sudo rm -rf Avatar asked Dec 27 '10 16:12

sudo rm -rf


2 Answers

I don't see how you expect this to work. There's no guarantee that you will ever obtain a location with a specific level of accuracy. You're assuming that you will eventually get a location that has the reported accuracy you desire and that won't necessarily happen. LocationManager will send you a sequence of location updates which are generally, but certainly not always, increasingly accurate. Unfortunately you can't demand that the device receive a signal strong enough for it to give you a position of arbitrary accuracy and there's no way the device can predict the future to say "this is the most accurate position I'm going to get".

You might try storing all the locations reported over some time interval or until the reported accuracy seems to stabilize and accept that after several seconds you're probably not going to get a significantly more accurate position. You could then use the last reported position, or the most accurate, or a weighted center point of all of them, or whatever you think makes sense.

Given that you say this is going to be used to perform a reverse geocoding to get a zipcode I have to wonder why this is a concern. Even the most granular position is probably going to hit the user's current zipcode and even the most accurate will never be exactly right in every case so you'll want to allow users to correct it anyway if this is visible to your users.

like image 164
Jonah Avatar answered Sep 22 '22 21:09

Jonah


Core Location often call didUpdateToLocation with location detected durning previous session. So you can just skip first location that it send to you. And if you're calculating user speed based on this data you should to be aware of that behavior. Pedestrians at 100mph is usual in that case. :)

If you're submitting comments or photos with geo coordinates - start receiving geo coordinates when user did enter to write a comment screen. while he will type a message - detected location become pretty accurate.

like image 35
Evgen Bodunov Avatar answered Sep 22 '22 21:09

Evgen Bodunov