web-dev-qa-db-ja.com

MKMapViewのズームと領域

Google Maps Javascript APIの使用に精通しています。最近、iphoneプロジェクトでMapKitフレームワークを使用し始めましたが、ズームと地図上の領域の設定を理解するのに苦労しています。

Google Maps APIでは、8、9、10などの整数ズームレベルと単純な関数setZoom()を使用していました。 MapKitフレームワークで確認できる同等のメソッドは、setRegion:animatedのみです。理解しているように、ズームレベルを指定するには、地域のスパンの緯度と経度の「デルタ」値を設定する必要があります。しかし、これらの値が何を表しているのか本当に分かりません(ドキュメントを読みました)。

MKMapViewデリゲートを使用してregionDidChangeデリゲートメソッドのスパン値をトレースすると、結果は相互に関連していないようです。ズームアウトして、ドキュメントで指定されているようにスパンデルタ値が増加しているのを確認しても問題ありません。しかし、突然ズームせずにマップをドラッグすると、デルタ値が0.0になります。

誰かがこれらのスパンとデルタの基準点を説明してもらえますか?または、整数ズームレベル(9など)をこれらのデルタ値に変換するアルゴリズムはありますか?

おまけの質問として、MKMapViewで最小最大ズームレベルを指定する方法があります:)

ありがとう

85
cocoatoucher

まず、MKMapViewは、Googleマップのように事前定義されたズームレベルのセットを使用しない/使用しません。

代わりに、MKMapViewの表示領域は、2つの値で構成されるMKCoordinateRegionを使用して記述されます。

  1. center(領域の中心点)、および
  2. span(中心付近の可視領域のサイズ)。

中心点は明らかである必要があります(領域の中心点です)。

ただし、スパン(MKCoordinateSpan)は次のもので構成されます。

  1. latitudeDelta(地域によって表される垂直距離)、および
  2. longitudeDelta(領域で表される水平距離)。

簡単な例。おもちゃのMKCoordinateRegionは次のとおりです。

  1. センター:
    • 緯度:0
    • 経度:0
  2. スパン:
    • 緯度デルタ:8
    • 経度デルタ:6

領域は、その最小および最大座標を使用して次のように記述できます。

  1. 最小座標(左下のポイント):
    • 緯度:-4
    • 経度:-3
  2. 最大座標(右上の点):
    • 緯度:4
    • 経度:3

したがって、適切なサイズのMKCoordinateSpanを使用して、中心点の周りのズームレベルを指定できます。 Googleの数値ズームレベルの近似値として、Googleが特定のズームレベルに使用するスパンサイズをリバースエンジニアリングし、それに応じてスパンを作成できます。 (GoogleはMKMapViewと同じ方法でビュー領域を中心+スパンとして記述するため、これらの値をGoogleマップから引き出すことができます。)

リージョンの制限に関しては、次のデリゲートメソッドを使用してプレイできます。

mapView:regionWillChangeAnimated

例えば許可されたズームレベルに領域のサイズを変更します。 (テーブルビューでEdgeを超えてスクロールできるようになりますが、ラバーバンドで元の位置に戻ります。)ただし、この目的には使用していないため、走行距離は異なる場合があります。

ところで、OS 3.1には、MapKitの3.0で問題を引き起こしていた側面に対する明確な修正/改善があります。

134
Kelvin

MKCoordinateSpanを定義する代わりに明示的なズームレベルを使用する場合は、MKMapViewのズームレベルを指定するためのサポートを追加するカテゴリを作成しました。コードは here にあります。

118
Troy Brant

スパンは緯度と経度の度数です。代わりに、距離を取るMKCoordinateRegion構造体を構築する方法があります。 MKCoordinateRegionMakeWithDistanceを使用してスパンを指定している場合、regionDidChangeでチェックすると、lat/longスパンが表示されます。これは、MKCoordinateRegion構造体に格納される方法です。

私の知る限り、MKMapKitを使用する場合、整数ズームレベルは使用できず、まったく役に立ちません。個人的には、より柔軟なスパン数値を使用することを好みます。

最大ズームと最小ズームを指定することはできません。また、ハックする方法もわかりません。MKMapKitは実際には非常に弱く、機能がないことにがっかりしています。

4
Chase Johnson

Maps.google.comを使用してリンククエリ文字列を調べて、場所のズームレベルを簡単に比較すると、dxとdyのスパン値が2倍に増加していることがわかります。

 (0.005334, 0.011834) starting span
 (0.010668, 0.023668) dx: x2, dy: x2 
 (0.021335, 0.047337) dx: x2, dy: x2
 (0.042671, 0.094671) dx: x2, dy: x2
  ...
3
Ari Braginsky

MKMapViewのBrantのカテゴリはうまく機能します。ただし、mapSizeInPixelsの計算時にRetinaスクリーンを備えた新しいデバイスをサポートするように更新されていないようです。

この行を置き換えることで修正できます:

CGSize mapSizeInPixels = mapView.bounds.size;

この行では:

CGSize mapSizeInPixels = CGSizeMake(mapView.bounds.size.width * [UIScreen mainScreen].scale, mapView.bounds.size.height * [UIScreen mainScreen].scale);
2
Daniel