4

ユーザーの移動距離を計算するアプリケーションを開発しています。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);

}

コンソールに次のデータが表示されています......。

精度0oldd(null)new <+28.62114850、+77.37001021> +/- 80.00m(速度-1.00 mps /コース-1.00)@ 2010-06-2219:21:59+0530距離0.000000

精度0古い<+28.62114850、+ 77.37001021> +/- 80.00m(速度-1.00 mps /コース-1.00)@ 2010-06-22 19:21:59+0530新しい<+28.61670485、+ 77.37068155> +/- 80.00 m(速度-1.00 mps /コース-1.00)@ 2010-06-2219:22:00+0530距離498.211345

精度0古い<+28.61670485、+ 77.37068155> +/- 80.00m(速度-1.00 mps /コース-1.00)@ 2010-06-22 19:22:00+0530新しい<+28.62112748、+ 77.36998540> +/- 80.00 m(速度-1.00 mps /コース-1.00)@ 2010-06-2219:23:02+0530距離994.432508

4

2 に答える 2

8

以前からキャッシュされた場所を最初に取得するのは通常のことです。CLLocationのタイムスタンプを確認することで、古いキャッシュデータを無視できます。

精度を正しく印刷していません。%dではなく%fを使用してください。タイプは、intではなくdoubleです。

セルの三角測量による位置の精度が低いため、GPSが最初に起動したときに位置がすぐに変わる可能性があります。その後、GPSを取得すると、より精度の高い位置が得られます。それらは遠く離れている可能性があり(1000m)、数秒で遠くに移動したように見えますが、精度のみが変更されています。

移動距離の計算に精度が大きく異なる2つの場所を使用しないでください。

編集古い位置データを無視する方法のコードサンプルを追加しました。無視する年齢を決定します。ここでは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
    ...
}
于 2010-06-23T03:38:45.820 に答える
2

位置情報の更新が5秒未満であることをすでに確認しています。これが、このコード行の機能です。

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は実際には必要ありません。

于 2011-09-27T11:12:55.667 に答える