Корректировка неверных расстояний

Я разрабатываю приложение, которое вычисляет расстояние, пройденное пользователем. Для этого я использую класс 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) @ 22.06.2010 19:21:59 +0530 расстояние 0.000000

точность 0 oldd ‹+28.62114850, +77.37001021> +/- 80.00m (скорость -1.00 м/с / курс -1.00) @ 22.06.2010 19:21:59 +0530 new ‹+28.61670485, +77.37068155> +/- 80.0 м (скорость -1.00 м/с / курс -1.00) @ 22.06.2010 19:22:00 +0530 расстояние 498.211345

точность 0 oldd ‹+28.61670485, +77.37068155> +/- 80.00m (скорость -1.00 м/с / курс -1.00) @ 22.06.2010 19:22:00 +0530 new ‹+28.62112748, +77.36998540> +/- 80.0 м (скорость -1.00 м/с / курс -1.00) @ 2010-06-22 19:23:02 +0530 расстояние 994.432508


person Siddharth    schedule 22.06.2010    source источник


Ответы (2)


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

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

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

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

EDIT Добавлен пример кода, как игнорировать старые данные о местоположении. Вы сами решаете, сколько лет игнорировать, здесь я использовал 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
    ...
}
person progrmr    schedule 23.06.2010
comment
Спасибо progrmr, но не могли бы вы сказать мне, как именно удалить кэшированные данные с помощью временных меток ........ и если вышеприведенный подход к вычислению расстояния неверен, то как мне действовать ...... есть ли другой способ для вычисления расстояния ..... потому что я видел много приложений в магазине приложений, которые выполняют ту же работу, что и вычисление расстояния, скорости и т. д. Пожалуйста, дайте мне ваши ценные предложения. - person Siddharth; 23.06.2010
comment
Я добавил пример кода, чтобы показать, как удалить старые кэшированные данные, но вы уже делаете это в своем коде. - person progrmr; 23.06.2010

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

if (locationAge > 5.0) return;

Как заявил progrm, ключевая проблема здесь почти наверняка заключается в том, что вы полагаетесь на первоначальные оценки местоположения, которые имеют низкую точность, и поэтому местоположение, кажется, быстро перемещается, поскольку оно получает более точное определение вашего местоположения. Что вам нужно сделать, так это сначала убедиться, что 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;
}

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

person Duncan Babbage    schedule 27.09.2011