Mapas de mosaico personalizados eficientes con niveles de zoom personalizados y factores de zoom

Debo implementar una capa / vista de map de mosaico muy personalizada en iOS5 / 6 (iPhone), que carga mosaicos como imágenes y / o datos (JSON) de un server. Es como google maps, pero en ciertos puntos es muy específico, por lo que no puedo usar fácilmente una solución como:

  1. google maps o
  2. route-me (utilizado por MapBox)
  3. CATiledLayer en combinación con UIScrollView

El caso es que: ninguna de las soluciones por ahí realmente me ayuda, debido a mis especificaciones específicas. Si piensas, hay una solución adecuada, por favor , dime !!!

Si no:
¡Ayúdame a encontrar la mejor solución posible para mi caso!

"¿Pero por qué no puedo usar estas hermosas soluciones?"
Hay algunos límites, que deben ser conocidos:

  1. Solo utilizamos 3 niveles de zoom (0,1 y 2)

  2. Cada ficha tiene un número de 9 subtiles en el siguiente nivel de zoom (= factor de zoom 3 ) ( no como la mayoría de los otros kits con 4 subtiles = zoomfactor 2 )

  3. La primera capa tiene un tamaño inicial de (hablando en píxeles / puntos es la mitad) 768 * 1024.
    La segunda capa es tres veces más ancha y más alta (¡ zoomfactor 3 !!! ) -> 2304 * 3072
    La tercera capa es igualmente más ancha y más alta que la segunda -> 6912 * 9216

  4. Cada mosaico que viene del server es de 256×256 píxeles

  5. Por lo tanto, cada subcapa 9 veces la cantidad de fichas (12 en la 1ª capa, 108 en la 2ª, 972 en la 3ª)

  6. Cada mosaico tiene una image de background (aproximadamente 6 KB de tamaño) (cargada como image del server) e información de primer plano (cargada como JSON para cada mosaico del server, de 10-15 KB de tamaño)
    -> la información de primer plano JSON contiene una image de superposition (como el tráfico en Google) o información de mosaico local para dibujar en el espacio de coorderadas del mosaico local (como annotations, pero por mosaico)

  7. Quiero almacenar en caching todos los mosaicos de background en el disco, ya que nunca cambian.

  8. O quiero almacenar en caching la información de superposition-tile-images / overlay-tile-information para cada mosaico durante un cierto período de time, hasta que se vuelva a cargar

  9. El zoom debe ser con pellizcar y hacer doble toque

Algunas de mis consideraciones:

  1. El almacenamiento en caching no es el problema. Lo hago a través de CoreData o similar

  2. Pensé en un UIScrollView, para mostrar un desplazamiento suave

  3. Me gustaría usar pellizcos, así que cada vez que atravieso el próximo nivel de zoom, tengo que dibujar los siguientes mosaicos de nivel de zoom

  4. El contenido solo debe dibujarse en el área visible (para mí en iPhone 5 320×500)

  5. Las fichas no visibles deben eliminarse para que sean más eficientes en memory. Pero no deben eliminarse instantáneamente, solo si un mosaico está alejado de una cierta cantidad de píxeles / puntos del centro visible. Debería haber un "display-cache", para mostrar instantáneamente fichas, que se cargaron y mostraron. ¿O hay una mejor técnica por ahí?

  6. Puedo cargar el background al instante desde el disco o desde el server de forma asíncrona, ya que sé qué fichas son visibles. Yo también con el azulejo-JSON. Luego extraigo la información JSON para el mosaico ( "es la superposition de una image o información directa, como un nombre de ciudad, que debo dibujar en el mosaico" ) y dibujo o cargué la superposition (desde DB / Disc o Servidor)

  7. ¿Es UIScrollView lo suficientemente eficiente como para manejar el tamaño máximo de la vista de mosaico?

  8. ¿Debería utilizar un CALayer como subcapa para dibujar en él? ¿Debería usar Quartz para dibujar directamente en un gran "canvas"?

Ahora es tu turno !!!

Apple tiene un ejemplo que muestra el zoom en una sola image muy profunda. Utilizan un CATiledLayer para esto.

El ejemplo se puede encontrar aquí: http://developer.apple.com/library/ios/#samplecode/PhotoScroller/Introduction/Intro.html

El ejemplo funciona con subtiles almacenados en el teléfono, pero tal vez pueda adaptarse a su problema.

He usado mi propia implementación de TiledLayer para este tipo de problemas de mosaico no estándar que CATiledLayer no admite (y porque CATiledLayer todavía tiene algunos errores sin resolver).

Esa implementación ahora está disponible en Github .

Fab1n: esta es la misma implementación que ya le envié por correo electrónico.

Se me ocurrió una solución muy bonita y agradable (implementación personalizada de TiledLayer):

No uso CATiledLayer como contentView de scrollView más. En su lugar, agregué una subclass CALayer y agregué mis cuadros como subcapas. Cada mosaico contiene el bitmap de mosaico como contenido. Al acercar el zoom con la vista de desplazamiento, cambio de fichas manualmente en function del nivel de zoom actual. ¡¡¡Eso es perfecto!!!

Si alguien quiere saber detalles de la implementación -> no hay problema, escribe un comentario y lo publícalo aquí.


EDITAR :

Detalles sobre la implementación:

La implementación de hecho es realmente fácil:

  1. Agregue un UIScrollView a su Vista / Vista de controller
  2. Agregue una UIView (de ahora en adelante referida como tileView ) como contentView a ScrollView – del mismo tamaño que ScrollView (este es el modo completamente desactivado – factor 1)
  3. Activar el zoom (tenía un factor de zoom mínimo de 1 y un máximo de 9)
  4. Cuando coloque una image en tileView , acercar el zoom al nivel 9 dará como una image pixelada muy poco definida, eso es lo que queremos (explicaré por qué)
  5. Si te gustan las imágenes claras y nítidas cuando acercas, deberías agregar instancias de CALayer ( tiles ) con addSublayer: a tileView
  6. Suponiendo que tiene un factor de zoom de 3 (tuve – lo que significa 1 mosaico en la capa 0 – zoomFactor 1 consistirá en 3×3 = 9 mosaicos en la capa 1 – zoomFactor 3 )
    1. En la capa 0, diga que coloca mosaicos 3×4 con 243×243 (3 veces divisibles por 3) píxeles (como subcapas a tileView ). CALayer contents imágenes de mosaico del mismo tamaño que los CALayer contents . Al acercar el zoom, el Factor 3 los hace borrosos (como los antiguos maps de Google)
    2. Cuando golpeas zoomFactor 3, elimina las 12 capas de la superestructura y reemplázalos con 3 capas más pequeñas ( 81×81 píxeles ). Obtienes 9 veces más capas en un todo.
    3. Ahora que tiene capas de mosaico 3 veces más pequeñas, el truco es la propiedad CALayer de CALayer . Incluso si la capa es de 81×81, los contenidos (tu image) siguen siendo de resolución completa , lo que significa que si pones una image de 243×243 píxeles como contenido de tus 81×81 píxeles, la baldosa CALayer, en zoomFactor 3 , ¡parece una baldosa de 243×243 píxeles!

Puedes ir con eso en cualquier zoomFactor (3,9,12) más profundo. Las fichas se vuelven cada vez más pequeñas, pero al configurar la image original como contenido, la ficha se verá nítida y nítida en el zoomFactor exacto en el que se colocan.

Si le gusta que sus fichas se vean nítidas incluso entre los zoomFactors, debe configurar una image 3 veces más alta como .contents . Luego, su azulejo es nítido y nítido incluso corto antes de pasar el siguiente zoomNivel.

Lo único que debe averiguar es que eliminar todos los mosaicos en una capa al pasar el factor zoomLevel no es eficiente . Solo tienes que actualizar las fichas visibles en rect.

No es la mejor de todas las soluciones, pero funciona y si alguien hace una biblioteca bien diseñada, tal vez exista la posibilidad de que sea una solución limpia.