MKMapView Zoom und Region

85

Ich bin mit der Verwendung der Google Maps Javascript-API vertraut. Vor kurzem habe ich angefangen, das MapKit-Framework für ein iPhone-Projekt zu verwenden, aber es fällt mir schwer, das Zoomen und Festlegen einer Region auf der Karte herauszufinden.

In der Google Maps-API habe ich ganzzahlige Zoomstufen wie 8, 9, 10 zusammen mit der einfachen Funktion setZoom () verwendet. Die einzige äquivalente Methode, die ich im MapKit-Framework sehen kann, ist setRegion: animiert. Soweit ich weiß, muss ich die Breiten- und Längengrade "Delta" einer Region festlegen, um die Zoomstufe festzulegen. Aber ich habe wirklich keine Ahnung, was diese Werte darstellen (ich habe die Dokumentation gelesen).

Wenn ich einen MKMapView-Delegaten verwende und die Bereichswerte in regionDidChange-Delegaten verfolge, scheinen die Ergebnisse der Delegatenmethode nicht miteinander zu korrelieren. Es ist in Ordnung, wenn ich verkleinere und sehe, dass die Span-Delta-Werte wie in der Dokumentation angegeben zunehmen. Aber plötzlich ziehe ich die Karte ohne zu zoomen und Delta-Werte werden 0.0.

Kann jemand bitte erklären, was der Bezugspunkt zu dieser Spanne und diesem Delta ist? Oder gibt es einen Algorithmus, um eine ganzzahlige Zoomstufe (wie 9) in diese Deltawerte umzuwandeln?

Als Bonusfrage gibt es eine Möglichkeit, eine minimale bis maximale Zoomstufe für eine MKMapView festzulegen :)

Vielen Dank

Cocoatoucher
quelle

Antworten:

134

Erstens verwendet MKMapView keine vordefinierten Zoomstufen wie Google Maps.

Stattdessen wird der sichtbare Bereich einer MKMapView mit MKCoordinateRegion beschrieben , die aus zwei Werten besteht:

  1. Zentrum (der Mittelpunkt der Region) und
  2. Spannweite (die Größe des sichtbaren Bereichs um die Mitte).

Der Mittelpunkt sollte offensichtlich sein (es ist der Mittelpunkt der Region.)

Span (das ist ein MKCoordinateSpan ) besteht jedoch aus:

  1. LatitudeDelta (der vertikale Abstand, der durch die Region dargestellt wird) und
  2. longitudeDelta (der horizontale Abstand, der durch die Region dargestellt wird).

Ein kurzes Beispiel. Hier ist ein Spielzeug MKCoordinateRegion:

  1. Center:
    • Breitengrad: 0
    • Längengrad: 0
  2. Spanne:
    • LatitudeDelta: 8
    • longitudeDelta: 6

Die Region könnte mit ihren Min- und Max-Koordinaten wie folgt beschrieben werden:

  1. Min. Koordinate (linker unterer Punkt):
    • Breitengrad: -4
    • Längengrad: -3
  2. maximale Koordinate (oberer rechter Punkt):
    • Breitengrad: 4
    • Längengrad: 3

Sie können also Zoomstufen um einen Mittelpunkt mithilfe eines MKCoordinateSpan mit geeigneter Größe festlegen. Als Annäherung an die numerischen Zoomstufen von Google können Sie die von Google für eine bestimmte Zoomstufe verwendeten Bereichsgrößen rückentwickeln und entsprechend einen Bereich erstellen. (Google beschreibt ihre Ansichtsbereiche genauso wie MKMapView als Center + Span, sodass Sie diese Werte aus Google Maps abrufen können.)

Um die Region einzuschränken, können Sie mit dieser Delegatenmethode spielen:

mapView:regionWillChangeAnimated

Beispiel: Ändern Sie die Größe des Bereichs wieder in die zulässigen Zoomstufen. (So ​​ähnlich wie in Tabellenansichten Sie über die Kante scrollen können, dann aber das Gummiband wieder einrasten lassen.) Ihr Kilometerstand kann jedoch variieren, da ich ihn nicht für diesen Zweck verwendet habe.

Übrigens gibt es in OS 3.1 bestimmte Korrekturen / Verbesserungen an Aspekten von MapKit, die mir in 3.0 Probleme bereiteten.

Kelvin
quelle
@ Kelvin, können Sie detaillierter beschreiben, wie Sie "die von Google für eine bestimmte Zoomstufe verwendeten Bereichsgrößen zurückentwickeln und einen Bereich erstellen". Ich brauche es wirklich
Scofield Tran
118

Wenn Sie explizite Zoomstufen verwenden möchten, anstatt ein MKCoordinateSpan zu definieren, habe ich eine Kategorie geschrieben, die die Angabe der Zoomstufe einer MKMapView unterstützt. Den Code finden Sie hier .

Troy Brant
quelle
4
Troys Blog-Beiträge gaben mir ein gutes Verständnis dafür, wie Mapkit und Google Maps funktionieren. Ich kann es nur empfehlen.
Aaron
5
git: //github.com/jdp-global/MKMapViewZoom.git
johndpope
@ JohnMerlino ja, das tut es
Zoltán Matók
5

Die Spanne ist in Breiten- und Längengraden angegeben. Es gibt eine Methode zum Erstellen von MKCoordinateRegion-Strukturen, die stattdessen Distanz benötigt. Möglicherweise verwenden Sie MKCoordinateRegionMakeWithDistance, um die Spanne anzugeben. Wenn Sie sie dann in regionDidChange überprüfen, sehen Sie die Lat / Long-Spanne, wie sie in einer MKCoordinateRegion-Struktur gespeichert ist.

Soweit ich weiß, sind die ganzzahligen Zoomstufen bei der Arbeit mit MKMapKit nicht verfügbar oder überhaupt nicht nützlich. Ich persönlich bevorzuge die Verwendung der Spannenzahlen, es ist flexibler.

Sie können den maximalen und minimalen Zoom nicht angeben, und ich kenne keine Möglichkeit, ihn zu hacken. MKMapKit ist derzeit ziemlich schwach. Ich bin ziemlich enttäuscht über den Mangel an Funktionen.

Alice Isabelle
quelle
3

Ein schneller Vergleich der Zoomstufen für einen Standort mithilfe von maps.google.com durch Überprüfen des Link-Querystrings zeigt, dass sich die Werte für dx und dy span um den Faktor 2 erhöhen:

 (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
  ...
Ari Braginsky
quelle
2

Brants Kategorie auf MKMapView funktioniert gut. Es scheint jedoch, dass es nicht aktualisiert wurde, um neuere Geräte mit Retina-Bildschirmen bei der Berechnung von mapSizeInPixels zu unterstützen.

Es kann durch Ersetzen dieser Zeile behoben werden:

CGSize mapSizeInPixels = mapView.bounds.size;

Mit dieser Zeile:

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