10

アプリケーションを新しく起動するか、久しぶりに再開すると、MKMapView の userLocation の概念が間違っていて、海の真ん中にいることがわかります。

次のコードを使用しています。

self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;
[mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];

アプリを長時間再開したり、まったく新しいスタートを切った後に発生します....

4

7 に答える 7

21

これは予想される動作です。ユーザーの位置は、iPhone が GPS を使用して常に追跡するとは限りません (バッテリーを大量に消費します)。そのため、マップが表示されるとすぐに、MKMapViewインスタンスは最後に認識した「最適な」ユーザー位置を表示し、追跡を有効にすることで精度を向上させます (これはシームレスなプロセスであり、気にする必要はありません)。

プロトコルMKMapViewを実装することで、マップ上のユーザーの位置が更新されるタイミングを監視できMKMapViewDelegateます。実装するだけです:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation      {
    CLLocationAccuracy accuracy = userLocation.location.horizontalAccuracy;
    if (accuracy ......) {
    } 
}

(アップルのドキュメントの詳細はこちら)

上記の例のコードは、mapView によって現在表示されている位置の精度をチェックし、それに応じて反応します。

[編集]
最初に海の真ん中にユーザーの位置を表示するのが本当に気になる場合は、十分に正確な/新鮮な位置を取得するまで、ユーザーの位置を非表示にすることができます。
これを行うには、(前のデリゲート コールバックのおかげで) 正確な位置を取得するまで、最初に のshowsUserLocationプロパティを にMKMapView設定し、次に に設定します。 そうすることで、正確でない、または表示するには古すぎる場所を表示することを避けることができます (古い場所かどうかを確認するためのプロパティが にあります)。NOYES
timestampCLLocation

注: あなた側でインスタンスを作成する必要はありませんCLLocationManager。MKMapView は内部でインスタンスを作成し、このデリゲート セレクターを介して受信した場所を公開します。

于 2011-11-03T08:10:30.427 に答える
4

CLLocationManager を直接使用する場合、通常は最初のコールバックでキャッシュされた場所を取得します。古いですが、通常は良い場所です。その後、Wi-Fi、セルタワー (利用可能な場合) を使用して、より良い場所を提供する追加のコールバックをすばやく取得します。1000m 未満の精度を要求した場合、(さらに数秒後に) GPS 三角測量が取得されます。

それらのいずれも、海の真ん中にあるほど不正確であってはなりません。このコード行は次のように思われます。

self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;

userLocationまたはlocationisの間、座標にアクセスしていnilます。userLocationまたはが nil の場合location、これは 0 座標を返します。lat=0、lon=0 の場所は、アフリカ沖の大西洋にあります。location座標を取得する前に nil でないことを確認するためのチェックを追加できます。

if (self.mapView.userLocation.location) {
    self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;
    [mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];           
}

MKMapViewDelegate へのコールバックを待ってmapView:didUpdateUserLocation:、有効な場所がいつ利用できるかを知ることもできます。の実装では、無効な位置を示す horizo ​​ntalAccuracydidUpdateUserLocation: < 0 を持つ位置を破棄する必要があります。

-(void)mapView:(MKMapView*)mapView didUpdateUserLocation:(MKUserLocation*)userLocation
{
    if (userLocation.location.horizontalAccuracy > 0) {
        [mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];           
    }
}
于 2011-11-07T19:32:49.523 に答える
1

ここで私がすることは-

  1. 場所の更新を開始する
  2. 場所の更新で、場所の年齢を確認し、古すぎる場合は待機します
  3. 新しい更新を受け取ると、マップ上で更新します

非常に正確な位置情報が必要な場合は、精度にもチェックを入れ、それを超えると待機できないタイムアウトを設定し、精度の低い修正を使用します。

于 2011-11-04T18:45:46.243 に答える
1

残念ながら、これは GPS チップの機能です。常にオンになっているわけではないため、通常、データは最初の数分間は正しくありません。あなたの最善の策は、おそらくアプリによって記録された最後の位置を NSUserDefaults に保存し、精度が目的の位置になるのを待ってからライブデータに切り替えるか、精度が目的の位置になるまで MkMapView を非表示にすることです。その時点でそれを表示します(その間にロード画面を表示できます)

于 2011-02-09T06:52:13.277 に答える
1

Jeremy Massel が書いたように、アプリの開始/続行で最初の悪い位置を整理する必要があります。数か月前に素晴らしいブログ投稿を見つけました。

http://troybrant.net/blog/2010/02/detecting-bad-corelocation-data/

于 2011-11-02T16:11:39.193 に答える
0

実際の位置からどのくらい離れていますか?アプリケーションが開始または再開されたばかりの場合、ユーザーの場所は通常、最初は常に間違っています。アプリケーションが実行されると、ますます正確になります。CLLocationManager でユーザーの位置の精度を取得する方法があります。そこで得られる値の種類を確認してください。

于 2011-02-09T06:52:34.250 に答える
0

私のアプリでは、次の方法を使用しました。

最初に - デフォルトの位置を設定することをお勧めします (たとえば、アプリケーションは都市に関するもので、ズームインして都市全体を表示します) (最初に - 最初にアプリを開いたとき、データがダウンロードされていない場合)

2 番目 - ユーザーが既にマップを使用している場合 - 座標を保存し、他に利用可能なデータがない場合にそれら (+ スパン (ズーム) レベル) を表示できます。

3番目 - データの場合:

1.)データベースに既にいくつかの座標がある場合 - 最初のマップを開くとき (アプリケーションが閉じられているとき) - ズームアウト/ズームインしてマップ上のすべてのピンを表示します。

2.)まだマップにいて、最新情報 (新しい場所または何かが変更された) を受け取ったばかりの場合、次の 2 つの可能性があります。

2.1.)ユーザーがどの場所にもズームインしていない場合 - マップはズームイン/アウトしてすべての場所を表示します。

2.2.)ユーザーがズームインした場合 - 場所は更新されますが、マップはズームアウトしません

もちろん-いくつかのフィルターボタンもあります(例:検索、ユーザーの場所など-場所をフィルターし、ズームアウト/インしてフィルターされた結果を表示します)

于 2011-11-02T18:31:14.817 に答える