Jugando con las "tiles" de Google Maps

Seguro que todos aquellos que hayáis usado el API de Google Maps estaréis sorprendidos en la potencia y el resultado de esta herramienta del gigante norteamericano. Últimamente en el departamento de programación de 2mdc hemos estado trabajando en una nueva funcionalidad. Se trata de integrar datos numéricos en forma gráfica

Artículos recientes

Seguro que todos aquellos que hayáis usado el API de Google Maps estaréis sorprendidos en la potencia y el resultado de esta herramienta del gigante norteamericano.

Últimamente en el departamento de programación de 2mdc hemos estado trabajando en una nueva funcionalidad. Se trata de integrar datos numéricos en forma gráfica sobre el mapa de Google.

Supongamos que tenemos una tabla (en nuestro caso una sobre Mysql) con registros de centros de investigación asociados con su latitud y longitud geográficas. Nuestro objetivo es montar un mapa utilizando una capa superpuesta que nos indique de forma gráfica la densidad de centros en ciertas áreas.

Antes de seguir explicaremos como funcionan los mapas de Google de forma somera:

Cuando cargamos un mapa, centrado sobre cierto punto y a cierto nivel de zoom, se nos muestran una o varios ?tiles? o teselas que se van cargando dinámicamente según cambiamos el zoom o desplazamos el mapa de posición. Estas teselas tiene siempre una dimensiones de 256 x 256 píxeles.

El nivel de zoom hace que varíe el número de teselas que componen el mapa completo de la tierra. Así tenemos que a nivel cero de zoom Google nos divide el orbe terrestre en 1 sólo ?tile?, en zoom 1 tenemos 4, etc siguiendo la progresión: nº tiles = 2 ^ (2 * nivel zoom) .

Las teselas están ordenadas de izquierda a derecha y de arriba a abajo siguiendo valores enteros, así pues la primera tendrá situado su primer píxel a -180º de longitud y 90 grados latitud norte (esto no es del todo cierto ya que Google corta la proyección a valor de Y=π radianes o φ=85,0511º)

La proyección cartográfica que utiliza Google es la Mercator, que mantiene equidistantes los paralelos pero no así los meridianos al proyectarlos sobre el plano. Esto quiere decir que la distancia real sobre un mapa Google del meridiano 15 al 30 no será igual a la que existe del 30 al 45. Aun cuando son en ambos casos 15º de separación. Existe una formula para transformar latitudes geográficas reales a latitudes sobre el mapa ?plano? y son las siguientes:

φ = arc tang(senh (y) )
λ = x

Una vez aclarados estos conceptos clave pasamos al ?cómo? de nuestra pequeña aplicación.

Cómo hemos dicho antes el API de Google es muy flexible y nos proporciona métodos para superponer capas o ?layers? en nuestro mapa. El objeto de la clase GTileLayer es el que nos dará la posibilidad de superponer de forma cómoda un gráfico sobre la zona adecuada de nuestro mapa.

Para ello especificamos su método getTileUrl el cual llamará a un script (en nuestro caso PHP) que mediante la librería GD nos devolverá un gráfico PNG a superponer exactamente sobre cada ?tile? de 256 por 256 píxeles.

Los únicos parámetros que pasaremos serán la coordenada X e Y de la tesela en cuestión y el nivel de zoom actual del mapa.

Según lo propuesto hasta ahora, por cada tesela, por cada invocación a nuestro script PHP con un valor X e Y de ?tile?, podemos hacer una inspección entre nuestros registros de la tabla. Podemos consultarlo vía SELECT * FROM tabla WHERE latitud BETWEN latitud1 AND latitud2 AND longitud BETWEEN longitud1 AND longitud2, ver cuantos resultados existen y pintar un punto que indique esa cantidad.

Lo malo de todo lo anterior es que 256 píxeles en una pantalla normal de ordenador da poca resolución y detalle. Un mapa típico de pongamos 750 x 500 abarca sólo 6 teselas lo que es muy insuficiente.

Para resolver esto, y puesto que el tamaño de la tesela la dicta Google, nuestro script PHP subdivide según nuestras preferencias el ?tile? en cuadriculas iguales y pinta en cada una de ellas un punto en función de cuantos registros se hayan dentro de esa subdivisión de la tesela. En nuestro ejemplo hemos optado por 16 dando lugar a 256 subdivisiones dentro de cada tesela.

Aquí tenéis los Códigos del HTML con el mapa y el PHP que se invoca en cada carga de ?tiles?:

Descargar ejemplo