views:

235

answers:

1

I am using location manager in my application and i'm getting inaccurate location.I'm using below code for getting location

locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;

and in didupdatetolocation method i'm using this code.

LatitudeData = [[NSString alloc] initWithFormat:@"%f",newLocation.coordinate.latitude];
 LongitudeData = [[NSString alloc] initWithFormat:@"%f",newLocation.coordinate.longitude];
 [UIApplication sharedApplication].networkActivityIndicatorVisible=NO;
 [self insertNewLocationInDataBase];

do i need to set distancefilter? how do i get the accurate location? i want to get accurate location then will insert location in database.

+1  A: 

Getting a good result from Core Location in a reasonable amount of time takes some careful finagling.

The issue is that once you start updating, didUpdateToLocation will fire several times. Each time it fires, the location should be more accurate. However, you do not know how many times it will fire, nor do you know how fast a lock to your requested accuracy will occur (if it ever does). As per the documentation, additional events are generated if the minimum threshold distance (as specified by the distanceFilter property) is exceeded or a more accurate location value is determined. Changing the distanceFilter won't give you a better location (unless, of course, you're interested in precise movements).

There are some common setups to help make this simpler, but you'll probably want to fiddle with this depending upon the specific heuristics you desire.

  • Set a timer after you send startUpdating to call a selector (can be as simple as performSelector:afterDelay:). Set your delay to the maximum amount of time you're willing to wait for a reasonable approximation. In that selector's method, I would check to make sure that the location is accurate enough for placement in the database, and insert it. If it isn't, I'd alert the user.
  • In didUpdateToLocation, immediately discard any locations that are too old. The LocationManager will often first return the cached value of its location -- and it may be very old.
  • In didUpdateToLocation, simply save the latest result to an instance variable if it's not to your desired accuracy.
  • In didUpdateToLocation, if the new location is accurate enough, cancel that perform selector after delay, and instead call it immediately.

That's just a rough sketch, but it's a pretty versatile setup that you can easily extend to have the functionality you desire.

Here's the basic outline of how this might work. This is a paired down snippet from one of my view controllers to just show the basics of the relevant parts:

- (void)viewWillAppear:(BOOL)animated {
    [self.locationManager startUpdatingLocation];
    [self performSelector:@selector(finishUpdating) withObject:nil afterDelay:10.0];
    [super viewWillAppear:animated];
}

- (void) locationManager:(CLLocationManager *)manager
     didUpdateToLocation:(CLLocation *)newLocation
            fromLocation:(CLLocation *)oldLocation {
    /* Refuse updates more than a minute old */
    if (abs([newLocation.timestamp timeIntervalSinceNow]) > 60.0) {
        return;
    }
    /* Save the new location to an instance variable */
    self.lastUpdatedLocation = newLocation;

    /* If it's accurate enough, cancel the timer */
    if (newLocation.horizontalAccuracy < 20.0) {
        [NSObject cancelPreviousPerformRequestsWithTarget:self 
                                                 selector:@selector(finishUpdating) 
                                                   object:nil]
        /* And fire it manually instead */
        [self finishUpdating];
    }
}

- (void) finishUpdating {
    /* Check the accuracy of self.lastUpdatedLocation, and either
     * save it or alert the user that it's not accurate enough */
    [self.locationManager stopUpdatingLocation];
}
Matt B.
can you post a sample code for this please?
Rahul Vyas
thank you so much.Now tell me how much time device will take to acquire user location.I have just tested my app.In map view i am not getting blue circle and also when i use location manager it shows wrong location.also delegate method is only called once i don't know why it is not calling regularly?
Rahul Vyas
Also please tell me in your code how do i check the accuracy of self.lastUpdatedLocation? i want the best possible accuracy and then want to save it in database.Please guide me a little more
Rahul Vyas