MKMapViewズームとリージョン


85

私はGoogleMaps JavascriptAPIの使用に精通しています。最近、iPhoneプロジェクトでMapKitフレームワークを使い始めましたが、ズームや地図上の地域の設定を理解するのに苦労しています。

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

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

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

ボーナスの質問として、MKMapViewで最小-最大ズームレベルを指定する方法はありますか:)

ありがとう

回答:


134

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

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

  1. 中心(領域の中心点)、および
  2. スパン(中央付近の表示領域のサイズ)。

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

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

  1. 緯度デルタ(地域によって表される垂直距離)、および
  2. 経度デルタ(地域によって表される水平距離)。

簡単な例。これがおもちゃのMKCoordinateRegionです:

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

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

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

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

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

mapView:regionWillChangeAnimated

たとえば、領域のサイズを許可されたズームレベルに戻します。(テーブルビューでは端を越えてスクロールできますが、ゴムバンドが元の位置に戻るようなものです。)ただし、この目的には使用していないため、マイレージは異なる場合があります。

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


@Kelvin、「Googleが特定のズームレベルに使用するスパンサイズをリバースエンジニアリングしてスパンを作成する」方法について詳しく説明してください。私は本当にそれが必要です
Scofield Tran 2015年

118

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


4
トロイのブログ投稿は、mapkitとgoogleマップがどのように機能するかについての深い理解を私に与えてくれました。私はそれを読むことを強くお勧めします。
アーロン

5
git://github.com/jdp-global/MKMapViewZoom.git
johndpope 2011

@JohnMerlinoはいそれはありません
ゾルタンMatók

5

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

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

最大ズームと最小ズームを指定することはできず、ハックする方法もわかりません。MKMapKitは現在かなり弱いので、機能がないことにかなり失望しています。


3

リンククエリ文字列を調べて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
  ...

2

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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.