Zoom y región de MKMapView

85

Estoy familiarizado con el uso de la API de JavaScript de Google Maps. Recientemente comencé a usar el marco MapKit para un proyecto de iPhone, pero me cuesta trabajo averiguar cómo hacer zoom y configurar una región en el mapa.

En la API de Google Maps, solía usar niveles de zoom enteros como 8, 9, 10 junto con la función sencilla setZoom (). El único método equivalente que puedo ver en el marco MapKit es setRegion: animated. Según tengo entendido, necesito establecer los valores "delta" de latitud y longitud del intervalo de una región para especificar el nivel de zoom. Pero realmente no tengo una idea de lo que representan estos valores (leí la documentación).

Cuando uso un delegado MKMapView y trazo los valores de intervalo en los resultados del método delegado regionDidChange no parecen correlacionarse entre sí. Está bien cuando me alejo y veo que los valores delta del intervalo aumentan como se especifica en la documentación. Pero de repente arrastro el mapa sin hacer zoom y los valores delta se vuelven 0.0.

¿Alguien puede explicar cuál es el punto de referencia para estos span y delta? ¿O hay algún algoritmo para convertir un nivel de zoom entero (como 9) a estos valores delta?

Como pregunta adicional, ¿hay alguna forma de especificar un nivel de zoom mínimo-máximo en un MKMapView :)

Gracias

cocoatoucher
fuente

Respuestas:

134

En primer lugar, MKMapView no usa / tiene un conjunto predefinido de niveles de zoom como lo hace Google Maps.

En cambio, el área visible de un MKMapView se describe mediante MKCoordinateRegion , que consta de dos valores:

  1. centro (el punto central de la región), y
  2. span (el tamaño del área visible alrededor del centro).

El punto central debe ser obvio (es el punto central de la región).

Sin embargo, span (que es un MKCoordinateSpan ) consta de:

  1. latitudeDelta (la distancia vertical representada por la región), y
  2. longitudeDelta (la distancia horizontal representada por la región).

Un breve ejemplo. Aquí hay un juguete MKCoordinateRegion:

  1. centrar:
    • latitud: 0
    • longitud: 0
  2. lapso:
    • Latitud Delta: 8
    • longitudDelta: 6

La región podría describirse utilizando sus coordenadas mínimas y máximas de la siguiente manera:

  1. coordenada mínima (punto inferior izquierdo):
    • latitud: -4
    • longitud: -3
  2. coordenada máxima (punto superior derecho):
    • latitud: 4
    • longitud: 3

Por lo tanto, puede especificar niveles de zoom alrededor de un punto central utilizando un MKCoordinateSpan de tamaño adecuado. Como una aproximación de los niveles de zoom numérico de Google, puede aplicar ingeniería inversa a los tamaños de tramo que utiliza Google para un nivel de zoom dado y crear un tramo, en consecuencia. (Google describe sus regiones de vista de la misma manera que MKMapView, como centro + tramo, para que pueda extraer estos valores de Google Maps).

En cuanto a restringir la región, puede jugar con este método de delegado:

mapView:regionWillChangeAnimated

por ejemplo, cambiando el tamaño de la región a los niveles de zoom permitidos. (Algo parecido a cómo las vistas de tabla le permitirán desplazarse más allá del borde, pero luego volverán a colocar la goma elástica en su lugar). Sin embargo, su kilometraje puede variar, ya que no lo he usado para este propósito.

Por cierto, hay correcciones / mejoras definidas en OS 3.1 para aspectos de MapKit que me estaban dando problemas en 3.0.

Kelvin
fuente
@Kelvin, ¿puede describir con más detalle cómo "aplicar ingeniería inversa a los tamaños de tramo que utiliza Google para un nivel de zoom determinado y crear un tramo"? Realmente lo necesito
Scofield Tran
118

Si prefiere usar niveles de zoom explícitos en lugar de definir un MKCoordinateSpan, escribí una categoría que agrega soporte para especificar el nivel de zoom de un MKMapView. El código se puede encontrar aquí .

Troy Brant
fuente
4
Las publicaciones del blog de Troy me dieron una gran comprensión de cómo funcionan Mapkit y Google Maps. Recomiendo fuertemente leer esto.
Aaron
5
git: //github.com/jdp-global/MKMapViewZoom.git
johndpope
@JohnMerlino sí lo hace
Zoltán Matók
5

El lapso está en grados de latitud y longitud. En cambio, existe un método para construir estructuras MKCoordinateRegion que toma distancia. Puede ser que esté utilizando MKCoordinateRegionMakeWithDistance para especificar el intervalo, y luego, cuando lo marque en regionDidChange, verá en el intervalo lat / long, que es cómo se almacena en una estructura MKCoordinateRegion.

Hasta donde yo sé, los niveles de zoom de números enteros no están disponibles o no son útiles cuando se trabaja con MKMapKit. Personalmente prefiero usar las cifras de tramo, es más flexible.

No puedes especificar el zoom máximo y mínimo, y no conozco una forma de piratearlo. MKMapKit es bastante débil en este momento, estoy bastante decepcionado por la falta de funciones.

Alice Isabelle
fuente
3

Una comparación rápida de los niveles de zoom para una ubicación usando maps.google.com al inspeccionar la cadena de consulta del enlace muestra que los valores de dx y dy span aumentan en un factor de 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
  ...
Ari Braginsky
fuente
2

La categoría de Brant en MKMapView funciona bien. Sin embargo, parece que no se ha actualizado para admitir dispositivos más nuevos con pantallas retina al calcular mapSizeInPixels.

Se puede arreglar reemplazando esta línea:

CGSize mapSizeInPixels = mapView.bounds.size;

Con esta línea:

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