Powiększenie i region MKMapView

85

Jestem zaznajomiony z korzystaniem z Google Maps Javascript API. Niedawno zacząłem używać frameworka MapKit dla projektu iPhone'a, ale mam trudności ze zrozumieniem powiększenia i ustawienia regionu na mapie.

W Google Maps API użyłem całkowitych poziomów powiększenia, takich jak 8, 9, 10 wraz z prostą funkcją setZoom (). Jedyną równoważną metodą, jaką widzę w środowisku MapKit, jest setRegion: animated. Jak rozumiem, muszę ustawić wartości „delta” szerokości i długości geograficznej zakresu obszaru, aby określić poziom powiększenia. Ale naprawdę nie mam pojęcia, co reprezentują te wartości (czytam dokumentację).

Kiedy używam delegata MKMapView i śledzę wartości zakresu w wynikach metody delegata regionDidChange, nie wydaje się, aby były ze sobą skorelowane. Jest w porządku, gdy pomniejszam i widzę, że wartości delta zakresu rosną, jak określono w dokumentacji. Ale nagle przeciągam mapę bez powiększania i wartości delta wynoszą 0,0.

Czy ktoś może wyjaśnić, jaki jest punkt odniesienia do tych rozpiętości i delty? Czy jest jakiś algorytm konwertujący całkowity poziom powiększenia (taki jak 9) na te wartości delta?

Jako pytanie dodatkowe, czy istnieje sposób, aby określić minimalny-maksymalny poziom powiększenia w MKMapView :)

Dzięki

cocoatoucher
źródło

Odpowiedzi:

134

Przede wszystkim MKMapView nie używa / nie ma predefiniowanego zestawu poziomów powiększenia, tak jak robią to Mapy Google.

Zamiast tego widoczny obszar MKMapView jest opisany przy użyciu MKCoordinateRegion , który składa się z dwóch wartości:

  1. środek (środek regionu) i
  2. rozpiętość (wielkość widocznego obszaru wokół środka).

Punkt środkowy powinien być oczywisty (jest to środek regionu).

Jednak span (który jest MKCoordinateSpan ) składa się z:

  1. latitudeDelta (odległość w pionie reprezentowana przez region) i
  2. longitudeDelta (odległość w poziomie reprezentowana przez region).

Krótki przykład. Oto zabawka MKCoordinateRegion:

  1. Centrum:
    • szerokość geograficzna: 0
    • długość geograficzna: 0
  2. Zakres:
    • latitudeDelta: 8
    • longitudeDelta: 6

Region można opisać za pomocą jego minimalnych i maksymalnych współrzędnych w następujący sposób:

  1. minimalna współrzędna (lewy dolny punkt):
    • szerokość geograficzna: -4
    • długość geograficzna: -3
  2. maksymalna współrzędna (prawy górny punkt):
    • szerokość geograficzna: 4
    • długość geograficzna: 3

W związku z tym można określić poziomy powiększenia wokół punktu środkowego, używając odpowiednio wielkości MKCoordinateSpan. Jako przybliżenie numerycznych poziomów powiększenia Google, możesz odwrócić rozmiary zakresu używane przez Google dla danego poziomu powiększenia i odpowiednio utworzyć zakres. (Google opisuje ich regiony widoku w taki sam sposób, jak robi to MKMapView, jako środek + rozpiętość, dzięki czemu można wyciągnąć te wartości z Map Google).

Jeśli chodzi o ograniczenie regionu, możesz grać tą metodą delegata:

mapView:regionWillChangeAnimated

np. zmieniając rozmiar regionu z powrotem do dozwolonych poziomów powiększenia. (Trochę tak, jak w przypadku widoku tabeli, który pozwoli ci przewijać poza krawędź, ale potem gumka z powrotem na miejsce). Jednak twój przebieg może się różnić, ponieważ nie użyłem go do tego celu.

przy okazji, istnieją pewne poprawki / ulepszenia w OS 3.1 w aspektach MapKit, które sprawiały mi problemy w 3.0.

kelwin
źródło
@ Kelvin, czy możesz bardziej szczegółowo opisać, jak „przeprowadzić inżynierię wsteczną rozmiarów rozpiętości używanych przez Google dla danego poziomu powiększenia i utworzyć rozpiętość”. Naprawdę tego potrzebuję
Scofield Tran
118

Jeśli wolisz używać jawnych poziomów powiększenia zamiast definiować MKCoordinateSpan, napisałem kategorię, która dodaje obsługę określania poziomu powiększenia MKMapView. Kod można znaleźć tutaj .

Troy Brant
źródło
4
Posty na blogu Troya dały mi świetne zrozumienie, jak działają mapkit i mapy Google. Gorąco polecam lekturę.
Aaron
5
git: //github.com/jdp-global/MKMapViewZoom.git
johndpope
@JohnMerlino tak, tak
Zoltán Matók
5

Rozpiętość jest wyrażona w stopniach szerokości i długości geograficznej. Istnieje metoda konstruowania struktur MKCoordinateRegion, która zamiast tego przyjmuje odległość. Może się zdarzyć, że używasz MKCoordinateRegionMakeWithDistance do określenia zakresu, a następnie, gdy sprawdzisz go w regionDidChange, zobaczysz szerokość / długą rozpiętość, która jest tak przechowywana w strukturze MKCoordinateRegion.

O ile wiem, całkowite poziomy powiększenia nie są dostępne lub w ogóle przydatne podczas pracy z MKMapKit. Osobiście wolę używać liczb rozpiętości, jest bardziej elastyczny.

Nie możesz określić maksymalnego i minimalnego zoomu, a nie wiem, jak go włamać. MKMapKit jest obecnie dość słaby, jestem dość rozczarowany brakiem funkcji.

Alice Isabelle
źródło
3

Szybkie porównanie poziomów powiększenia dla lokalizacji przy użyciu maps.google.com, sprawdzając kwerendę linków, pokazuje, że wartości dx i dy span rosną dwukrotnie:

 (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
źródło
2

Kategoria Branta w MKMapView działa dobrze. Wygląda jednak na to, że nie został zaktualizowany, aby obsługiwał nowsze urządzenia z ekranami siatkówki podczas obliczania mapSizeInPixels.

Można to naprawić, zastępując tę ​​linię:

CGSize mapSizeInPixels = mapView.bounds.size;

W tej linii:

CGSize mapSizeInPixels = CGSizeMake(mapView.bounds.size.width * [UIScreen mainScreen].scale, mapView.bounds.size.height * [UIScreen mainScreen].scale);
Daniel
źródło