Корреляция неверных расстояний - PullRequest
4 голосов
/ 22 июня 2010

Я разрабатываю приложение, которое вычисляет расстояние, пройденное пользователем.Я использую класс CLLocationManager для этого, но сначала я получаю кэшированные данные, а также переменная расстояния увеличивается с внезапной скоростью.Пожалуйста, помогите мне ... Я использовал следующий код ....

Примечание: расстояние является статической переменной.здесь

  - (void)viewDidLoad {
    [super viewDidLoad];
//bestEffortAtLocation = nil;
oldLocat = [[CLLocation alloc]init];
newLocat = [[CLLocation alloc]init];
locationManager =[[CLLocationManager alloc]init];
locationManager.delegate = self;
locationManager.distanceFilter =  kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];

  }

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




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


NSLog(@"accuracy %d",newLocation.horizontalAccuracy);

// 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];
//NSLog(@"time %d",locationAge);

if (locationAge > 5.0) return;



self.oldLocat = oldLocation;
self.newLocat = newLocation;


double latDegrees = newLocation.coordinate.latitude;
NSString *lat = [NSString stringWithFormat:@"%1.5f°",latDegrees];
latLabel.text = lat;
double longDegrees = newLocation.coordinate.longitude;
NSString *longt = [NSString stringWithFormat:@"%1.5f°",longDegrees];
longLabel.text = longt;
[self computeDistanceFrom:oldLocat tO:newLocat];

   }

    -(void)computeDistanceFrom:(CLLocation *)oldL tO:(CLLocation *)newL
 {
NSLog(@"oldd %@",oldL);
NSLog(@"new %@",newL);


distance = distance + [oldL getDistanceFrom:newL];
NSLog(@"distance %f",distance);

}

На консоли отображаются следующие данные .......

точность 0 oldd (null) new <+28.62114850, +77.37001021> +/-80,00 м (скорость -1,00 м / с / курс -1,00) @ 2010-06-22 19:21:59 +0530 расстояние 0,000000

точность 0 стар. <+28,62114850, +77,37001021> +/- 80,00 м (скорость-1,00 м / с / курс -1,00) @ 2010-06-22 19:21:59 +0530 новых <+28,61670485, +77,37068155> +/- 80,00 м (скорость -1,00 м / с / курс -1,00) @ 2010-06-2219:22:00 +0530 дистанция 498.211345

точность 0 oldd <+28.61670485, +77.37068155> +/- 80.00 м (скорость -1.00 мс / курс -1.00) @ 2010-06-22 19:22:00 +0530 новый <+28.62112748, +77.36998540> +/- 80,00 м (скорость -1,00 м / с / курс -1,00) @ 2010-06-22 19:23:02 +0530 расстояние 994,432508

Ответы [ 2 ]

7 голосов
/ 23 июня 2010

Нормально изначально получить кешированное местоположение из ранее.Вы можете игнорировать старые кэшированные данные, посмотрев отметку времени CLLocation .

Вы печатаете с неправильной точностью, используйте% f, а не% d, тип double, а не int.

Местоположение может быстро измениться при первом запуске GPS, поскольку у вас есть местоположение с низкой точностью из триангуляции ячейкизатем, когда вы получаете GPS-прием, вы получаете более высокую точность определения местоположения.Они могут быть далеко друг от друга (1000 м), и кажется, что вы продвинулись далеко за несколько секунд, но изменилась только точность.

Не используйте два местоположения, которые имеют очень разную точность для вычисления пройденного расстояния.

РЕДАКТИРОВАТЬ Добавлен пример кода, как игнорировать старые данные местоположения.Вы сами решаете, сколько лет игнорировать, я использовал здесь 60 секунд:

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

    NSTimeInterval ageInSeconds = -[newLocation.timestamp timeIntervalSinceNow];
    if (ageInSeconds > 60.0) return;   // data is too long ago, don't use it

    // process newLocation
    ...
}
2 голосов
/ 27 сентября 2011

Вы уже гарантируете, что обновления вашего местоположения менее пяти секунд. Вот что делает эта строка кода:

if (locationAge > 5.0) return;

Как заявляет progrmr, ключевая проблема здесь почти наверняка заключается в том, что вы полагаетесь на первоначальные оценки местоположения, которые имеют низкую точность, и поэтому кажется, что местоположение быстро перемещается, поскольку оно лучше фиксирует ваше местоположение. Сначала вам нужно убедиться, что oldLocation устанавливается только тогда, когда у вас есть точное начальное исправление местоположения, а затем сравнивать newLocations с этим oldLocation, только если они также имеют приемлемое разрешение.

Например, у вас может быть что-то вроде этого:

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

    // Ignore location updates that are less than 10m accuracy, or where the horizontalAccuracy < 0
    // which indicates an invalid measurement.
    NSLog(@"New location accuracy %.0fm", newLocation.horizontalAccuracy);
    if ((newLocation.horizontalAccuracy < 0) || (newLocation.horizontalAccuracy > 10)) return;

    // Ignore location updates that are more than five seconds old, to avoid responding to
    // cached measurements.
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
    if (locationAge > 5) return;

    if (self.oldLocat == NULL)
    {    
        // For the first acceptable measurement, simply set oldLocat and exit.
        self.oldLocat = newLocation;
        return;
    }

    // A second location has been identified. Calculate distance travelled.
    // Do not set self.oldLocat from the oldLocation provided in this update, as we wish to
    // use the last place we calculated distance from, not merely the last place that was
    // provided in a location update. 
    CLLocationDistance distance = [newLocation distanceFromLocation:self.oldLocat];
    NSLog(@"Distance: %.0fm", distance);

    // This new location is now our old location.
    self.oldLocat = newLocation;
}

Обратите внимание, что с помощью приведенного выше кода вам не требуется метод computeDistanceFrom: tO:, а также свойство self.newLocat фактически не требуется, по крайней мере в этом разделе кода.

...