1

This part of code of CLLocationManager is used to calculate the distance travelled. But the location cache is not removed even after using timeIntervalSinceNow.

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


    if(newLocation != nil && oldLocation != newLocation)
    {
        tempNewLocation = newLocation;
        tempOldLocation = oldLocation;
    }



    NSLog(@"New Location Found");
    NSLog(@"- Latitude: %f", newLocation.coordinate.latitude);
    NSLog(@"- Longitude: %f", newLocation.coordinate.longitude);
    NSLog(@"- Altitude: %f", newLocation.altitude);
    NSLog(@"- Course: %f", newLocation.course);

    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
    NSLog(@"The location age %f",locationAge);
    if (locationAge > 2.0) 
    {
    }
    else
    {
if (tempOldLocation.coordinate.latitude == tempNewLocation.coordinate.latitude   && tempNewLocation.coordinate.longitude == tempOldLocation.coordinate.longitude) 
{
    NSLog(@" Fix location found ");
}
else
{
    if(tempNewLocation.coordinate.latitude == tempOldLocation.coordinate.latitude && tempNewLocation.coordinate.longitude == tempOldLocation.coordinate.longitude)
    {
        NSLog(@"First Time Location Update");
        latitudeLongitude.text = [[ NSString alloc] initWithFormat:@"%g , %g", tempNewLocation.coordinate.latitude, tempNewLocation.coordinate.longitude];


        totalDistance =  0;
        distance.text = @"0 miles";
    }
    else if ([tempNewLocation distanceFromLocation:tempOldLocation] - tempNewLocation.horizontalAccuracy >= 0) 
    {

    totalDistance +=  [tempNewLocation distanceFromLocation:tempOldLocation] - (tempNewLocation.horizontalAccuracy / 2);
}
else{


    totalDistance +=  [tempNewLocation distanceFromLocation:tempOldLocation];
}



 if (totalDistance < 0) {
        distance.text = @"0 miles";

    }
    else
    milesdistance=0.000621371192*totalDistance;



distance.text = [[ NSString alloc] initWithFormat:@"%.1f", milesdistance];


odometerreading.text = [NSString stringWithFormat:@"%09.1f", milesdistance];
mileagerate.text = [[NSUserDefaults standardUserDefaults] valueForKey:@"savedstring"];


float mileagefloat=[self.mileagerate.text floatValue];
amount.text =  [NSString stringWithFormat:@"%.2f",mileagefloat * milesdistance];
amountstatus.text=[NSString stringWithFormat:@"$%.2f",mileagefloat * milesdistance];
newnumber=totalDistance;



}

This code doesnt work for me, and when I start tracking, distance is calculated from the place where I last stopped the tracking.

NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
        NSLog(@"The location age %f",locationAge);
        if (locationAge > 2.0) 

4 Answers4

2

I use a counter that counts how many times didUpdateToLocation is called.
I only use the location received after at least 3 calls.

I know 3 is a magic number but i have found that the first 3 calls are cache or very inaccurate.

Or Arbel
  • 2,965
  • 2
  • 30
  • 40
1

Take a look at the answer to this question, as it includes code from Apple's sample app "LocateMe" and provides a bit more detail as to what you are trying to do:

https://stackoverflow.com/a/12848776/346098

Community
  • 1
  • 1
cleverbit
  • 5,514
  • 5
  • 28
  • 38
  • Hi Richard.. Thanks for your link, but for me the code doesn't seem working. My app is to calculate the distance. When i start the app every time, it calculates from the coordinate where i last stopped it. – Sharanya Ramesh Oct 15 '12 at 12:23
  • From what I understood, you were having trouble figuring out what the user's _current_ location is. What you want to do is to resolve an accurate location first, then store it. Then (after some time) look up a _new_ location and once that's resolved, compare it to your stored (prev) one. The sample code I provided helps you resolve an accurate location (CLLocationManager does not return an accurate location on 1st call. It will updated repeatedly until you stop it OR it resolves a location within the threshold you specify, eg. 1km) – cleverbit Oct 15 '12 at 12:34
  • I should add: you don't want to be doing all of that from within the `locationManager:didUpdateToLocation:` method either, you'll want to split the logic out. – cleverbit Oct 15 '12 at 12:35
  • Thank you Richard. Ill try it. But even after comparing, , the old location cache is not removed, and hence the distance calculation will be from the old location. So, how do i start fresh with the new one? – Sharanya Ramesh Oct 15 '12 at 12:41
  • Well, once you have your 1st and 2nd locations and verified that they are within the bounds of desired resolution (eg. 500m accuracy), then calculate distance. Once you've calculated distance, your first location (old location) value is no longer needed. So simply overwrite it with your new location: `oldLocation = newLocation;` — Then, the next time you get a location update, you can calculate distance between your _new_ `newLocation` and `oldLocation`. Like a bunny hopping: every time he lands, you do the distance calculation, refresh your values, then initiate the next hop! – cleverbit Oct 15 '12 at 12:48
  • I have used this logic, but still it dint work.. Let me try it again.. Thanks Richard.. – Sharanya Ramesh Oct 15 '12 at 12:52
0

You want to check the timestamp property of the new CLLocation object in your delegate method. By the sounds of it are only interested in lat/long that are no older than XXX seconds.

NSTimeInterval timeInSeconds = [newLocation.timestamp timeIntervalSinceNow];
if (timeInSeconds > YOUR_CUSTOM_TIME_IN_SECONDS)
{
    // Do something
}
Rog
  • 18,602
  • 6
  • 76
  • 97
  • I hope i have used the same statement, but what should i do inside the loop? – Sharanya Ramesh Oct 15 '12 at 00:28
  • There's a lot of wrong stuff with your code above. Firstly you are comparing pointers to newLocation and oldLocation to see if they are in the same coordinates, this is never going to work. Sorry but you will need to go back and do some research on object oriented language, pointer comparison etc. Get the basics right first and then come back and someone might be able to help you. – Rog Oct 15 '12 at 01:00
  • Thank you for your help Rog.. Im new to objective C.. I have to work a lot! – Sharanya Ramesh Oct 15 '12 at 01:12
  • This solution doesn't work if user change device's date and time. – Yogendra Patel Jul 24 '19 at 09:29
0

I found the answer for removing cache. For the first time didUpdateToLocation is called, the newlocation fetches the cache value, and the old location is null. And in the second call, newlocation value is swapped to oldlocation and the newlocation is updated. And hence to get the updated value, the function has to be called twice.

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

        static CLLocation *locationanalysis1;
    NSLog(@"New Location Found");
    NSLog(@"- Latitude: %f", newLocation.coordinate.latitude);
    NSLog(@"- Longitude: %f", newLocation.coordinate.longitude);
    NSLog(@"- Altitude: %f", newLocation.altitude);
    NSLog(@"- Course: %f", newLocation.course);

    NSDate *eventDate = newLocation.timestamp; 
    NSTimeInterval howRecent = -[eventDate timeIntervalSinceNow];
    if (howRecent > maximumElapsedTimeForCachedLocation)  {             

            locationanalysis1=newLocation;

        return;
}


    if((locationanalysis1.coordinate.latitude-oldLocation.coordinate.latitude)==0){
        NSLog(@"Old Location in location analysis is %@",oldLocation);


      return;
    }

    NSLog(@"New location accuracy %.0fm", newLocation.horizontalAccuracy);
    if ((newLocation.horizontalAccuracy < 0) || (newLocation.horizontalAccuracy > 10)) return;
    if(oldLocation!=NULL && newLocation!=NULL){

                totalDistance +=  [newLocation distanceFromLocation:oldLocation];
    }else return;
}