2012-04-17 10 views
9

私は自分のiPhoneを歩いている距離を計算するためにdistanceFromLocation:メソッドを使用しようとしています。これまでのところ、私は混乱した、不正確な、一見無作為の結果を改善するのを手助けするために全面的に調査してきました。これらのコードスニペットでは、theLabelは私のアプリのインターフェースに存在するラベルオブジェクトで、distanceMovedは私が歩いた総距離を格納しようとしている変数で、locManは私の@interfaceファイルで宣言されたロケーションマネージャです。CLLocationメソッドの問題distanceFromLocation:不正確な結果

- (void)viewDidLoad 
{ 
    locMan = [[CLLocationManager alloc] init]; 
    locMan.delegate = self; 
    [locMan startUpdatingLocation]; 
    isInitial = true; 
    distanceMoved = 0.0; 
    [super viewDidLoad]; 
} 

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{ 
    distanceMoved += [newLocation distanceFromLocation: oldLocation]; 
    theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved]; 
} 

私はここで間違ってやっているものを固定するために任意の助けいただければ幸いです。ありがとうございました!

答えて

13
  1. 無効場所結果(精度< 0)、
  2. kCLLocationAccuracyBestに設定された設定精度要件を除外
  3. 、キャッシュされた(古い)位置データをフィルタリング、
  4. 最小距離フィルタを設定し、好ましくは位置ノイズを除去するために少なくとも10メートル。
  5. EDIToldLocationがnilの場合、距離を計算しないでください。

これ以上のことがありますが、十分なhorizo​​nalAccuracy(< 30m)があれば、これはうまくいくはずです。精度の低い結果を除外することはできますが、あなたはもう少し複雑なoldLocationを追跡しなければなりません。

NSLog(下記参照)を追加すると、何が起きているのかを知ることができます。あなたがまだ良い結果を得ていない場合は、NSLogの出力をポストするので、何が起こっているのかを知ることができます。あなたは(上記の方法は現在廃止されているので)didUpdateLocations:を使用して同じことをやってみたかった場合iOS6ため

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{ 
    NSTimeInterval age = -[newLocation.timestamp timeIntervalSinceNow]; 

    if (age > 120) return; // ignore old (cached) updates 

    if (newLocation.horizontalAccuracy < 0) return; // ignore invalid udpates 

    // EDIT: need a valid oldLocation to be able to compute distance 
    if (oldLocation == nil || oldLocation.horizontalAccuracy < 0) return; 

    CLLocationDistance distance = [newLocation distanceFromLocation: oldLocation]; 

    NSLog(@"%6.6f/%6.6f to %6.6f/%6.6f for %2.0fm, accuracy +/-%2.0fm", 
     oldLocation.coordinate.latitude, 
     oldLocation.coordinate.longitude, 
     newLocation.coordinate.latitude, 
     newLocation.coordinate.longitude, 
     distance, 
     newLocation.horizontalAccuracy); 

    distanceMoved += distance; 
    theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved]; 
} 

- (void)viewDidLoad 
{ 
    locMan = [[CLLocationManager alloc] init]; 
    locMan.delegate = self; 
    locMan.desiredAccuracy = kCLLocationAccuracyBest; 
    locMan.distanceFilter = 10; 

    [locMan startUpdatingLocation]; 
    isInitial = true; 
    distanceMoved = 0.0; 
    [super viewDidLoad]; 
} 

EDIT最も簡単な解決策は、次の更新にあなたが持っているように、単にプロパティにそれぞれの場所を保存することです前の場所。oldLocationを保持するクラスのプロパティを宣言します。

@property (nonatomic, retain) CLLocation* oldLocation; 

その後、デリゲートメソッドが呼び出される次回のためoldLocationとして使用するために、各newLocationを保存デリゲートメソッドで:

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocations:(NSArray *)locations 
{ 
    CLLocation* newLocation = [locations lastObject]; 

    NSTimeInterval age = -[newLocation.timestamp timeIntervalSinceNow]; 

    if (age > 120) return; // ignore old (cached) updates 

    if (newLocation.horizontalAccuracy < 0) return; // ignore invalid udpates 

    // EDIT: need a valid oldLocation to be able to compute distance 
    if (self.oldLocation == nil || self.oldLocation.horizontalAccuracy < 0) { 
     self.oldLocation = newLocation; 
     return; 
    } 

    CLLocationDistance distance = [newLocation distanceFromLocation: self.oldLocation]; 

    NSLog(@"%6.6f/%6.6f to %6.6f/%6.6f for %2.0fm, accuracy +/-%2.0fm", 
     self.oldLocation.coordinate.latitude, 
     self.oldLocation.coordinate.longitude, 
     newLocation.coordinate.latitude, 
     newLocation.coordinate.longitude, 
     distance, 
     newLocation.horizontalAccuracy); 

    distanceMoved += distance; 
    theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved]; 

    self.oldLocation = newLocation; // save newLocation for next time 
} 
+0

私はちょうどこの正確なコードを使用しましたが、私は距離フィルタを1に変更しました。何らかの理由で、私の距離移動が-1で始まります。ここでは、約2m先まで歩いた後の出力を示します。 2012-04-17 17:58:05.341 LocationManagerTest2 [422:707] 0.000000/0.000000〜39.856110/-74.940113 -1m、精度+/- 10m 2012-04 -17 17:58:10.248 LocationManagerTest2 [422:707] 39.856110/-74.940113は39.856165/-74.940107に6メートルのために、精度+/- 50メートル 2012-04-17 17:58:11.248 LocationManagerTest2 [422:707] 39.856165/- 74.940107〜39.856223/-74.940010 10m、精度+/- 50m distanceMovedが約15mに達しました - あまりにも多く – bnasty

+0

私はこのコードを数回前に使ってみましたが、いくつかの一見正確な結果が得られました。 – bnasty

+0

の距離が-1だったのは、あなたのoldLocationが0だった場所で、おそらくoldLocationのパラメータがnilだったことを意味します。そのためのチェックを追加する必要があります(上記の私の編集を参照してください)。あなたはhorizo​​ntalAccuracyが50mであると報告するとき、高い精度を期待できません!つまり、GPSには十分な信号がありません。これは、報告された位置がどの方向にも50メートル離れている可能性があることを意味します。 – progrmr

0

ロケーションマネージャの精度を設定していません。リンゴのドキュメントを読むと、それは精度=ベストフォルナビージングのようなものです。か何か。それは地獄のように電池を消耗させるはずですが、この種の目的を意図しています。

編集:ちょうど私が手元にあったことを思い出しました。

// Create the Location Manager 
locationManager = [[CLLocationManager alloc] init]; 

// Configure the Location Manager 
locationManager.delegate = self; 
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; 
+0

私が試しました希望の精度のためにすべての異なる定数を設定しますが、まだ運がありません。今、私のアプリは、0.000000の代わりに何らかの理由で-1.00000でdistanceMovedで始まります。問題はおそらく私のCore Locationフレームワークまたは私のiPhone自体の中にあるでしょうか? – bnasty

+0

古いものと新しいものをNSlogがどのように変化しているか見るためにNSlogしてください。私は何が起こっているのかを知ることができます。 IVEは、ロケーションマネージャでたくさん働いていたと私はuがそれを設定いけない場合、正しくそれは奇妙なもの – Pochi

+0

緯度と経度の座標は毎回のように位置が更新され、正しいように見えるん、前回から新しい場所がされていることを覚えていますか古い場所として保存されます。何らかの理由で、2つの場所間の距離が非常に高い数値として計算されています。 – bnasty

0
CLLocationDistance distance = [secondLocation distanceFromLocation:firstLocation]; // distance is expressed in meters 

CLLocationDistance kilometers = distance/1000.0; 
// or you can also use this.. 
CLLocationDistance meters = distance; 

NSString *distanceString = [[NSString alloc] initWithFormat: @"%f", kilometers]; 

flot totaldistancecovered = [distanceString floatValue]; 

//Now,you can use this float value for addition... 
// distanceMoved should be float type variable which is declare in .h file... 

distanceMoved = distanceMoved + totaldistancecovered ; 
theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved]; 

これはあなたを助けることを願っています。..

+0

'CLLocationDistance'は単に' double'のtypedefであるため、文字列に変換してから数学をやり直す理由はありません。 – pr1001

0

あなたが最初にすべきことは、あなたがロケーションマネージャから受け取る最初の更新のタイムスタンプをチェックすることにより、最初の更新を放電され、それは通常キャッシュします最後の既知の位置。第二に、正確さを覚えておいてください。初期値は常に広い範囲にあります。

関連する問題