He estado buscando una solución sólida que me permita crear un mapa web y superponer polígonos vectoriales sin tardar una eternidad en cargar dichos datos con el objetivo de permitirme hacer que cada polígono muestre un color diferente en un evento de hover.
Por lo que sé, hay 3 opciones específicas para lograr esto a través de lienzo, SVG, Flash.
Flash parece ser la mejor solución si funciona en los iphones/ipads de Apple, ya que parece proporcionar la representación más rápida y la visualización más limpia. Canvas parece ser la segunda mejor opción, pero tarda MUCHO tiempo si tienes cientos de polígonos que se muestran en un mapa, mientras que SVG tarda aún más en renderizar.
I casi perdí la esperanza de encontrar una solución a este problema pero hoy me he encontrado con una empresa llamada GISCloud http://www.giscloud.com (actualmente en fase beta con inscripción gratuita).
Esta empresa ha conseguido, de alguna manera, una forma increíble de representar cientos de vectores en un mapa casi en tiempo real. Me sorprendió su enfoque y mi pregunta a la comunidad se refiere a cómo podemos replicar su enfoque para utilizarlo con tecnologías existentes como leaflet, openlayers, wax...
Compruébelo usted mismo viendo esta increíble demostración: http://www.giscloud.com/map/284/africa
Asegúrate de pasar el ratón por encima de cualquiera de los polígonos de la página y prueba los controles de zoom para ver que estos polígonos son efectivamente vectores.
Lo que he notado mirando las peticiones con firebug es que el mapa solicita archivos json específicos. Parece que dependiendo del nivel de zoom/área hay múltiples archivos json que se solicitan.
También debo mencionar aquí que una vez que giscloud carga los datos en la página al pasar por encima de un vector cambia inmediatamente el color sin crear una nueva solicitud.
EJEMPLOS:
- http://cft1.giscloud.com/t/1316509973/map284/layer1156/3/3/3.json
- http://cft1.giscloud.com/t/1316509973/map284/layer1156/3/5/3.json
- http://cft1.giscloud.com/t/1316509973/map284/layer1156/3/4/4.json
- http://cft1.giscloud.com/t/1316509973/map284/layer1156/3/3/4.json
- http://cft1.giscloud.com/t/1316509973/map284/layer1156/3/5/4.json
Estoy asumiendo que la estructura de la url sigue la lógica estándar del servicio de mosaico (por ejemplo, la 3ª a la última carpeta es el nivel de zoom...).
En cualquier caso he analizado los datos reales de estos archivos json y parece que la lógica que están utilizando sigue algún tipo de lógica por la que crean sus vectores sólo en base a estos valores de datos:
- ancho/altura: definen la anchura y la altura de los datos que se sirven en cada solicitud json
- píxeles: aquí se definen valores de píxeles que estoy asumiendo que de alguna manera se relaciona con algunas coordenadas generales de píxeles x/y para ¿niveles de puntos generalizados? Supongo que de alguna manera tienen una forma de simplificar automáticamente la región en función del nivel de zoom. I Supongo que al utilizar coordenadas de píxeles, están reduciendo drásticamente el tamaño de los datos. reduciendo drásticamente el tamaño de los datos que necesitan ser cargados en comparación con los datos de latitud y longitud.
- estilos: aquí se definen dos valores RGB css de RGB. "F" que representa el color del archivo del polígono y "S" que representa el color del borde del polígono.
- geom: Aquí es donde supongo que de alguna manera están definiendo específicamente cada polígono dentro de la baldosa que se está cargando donde se están definiendo esos datos basados en el mapa ventana del contenedor del mapa. Lo que también es interesante es que cada entrada tiene un valor "S" valor que estoy asumiendo que se utiliza como un atributo opcional o característica y al final de cada entrada hay un área que parece definir una parece definir un ID específico por vector junto con el ID de la capa que supongo que se utiliza para unir de alguna manera los datos de cada solicitud de baldosas json que se llama.
También estoy asumiendo que de alguna manera han descubierto una forma de determinar y dividir automáticamente los datos que necesitan ser cargados para cada azulejo dependiendo del tamaño de los datos que necesitarían ser cargados para el azulejo solicitado.
A continuación, un desglose extraído de una de estas solicitudes:
{"width":256,"height":256,"tile":
{"pixels":
[0,6461,-1,0,5,148,0,509,-1,10715,-1,1,-1,251,-1,1,-1,1,-1,251,-2,3,-1,255,-1,249,-2,5,-2,247,-1,509,-3,251,-1,2,-2,253,-2,252,-2,254,-1,255,-1,254,-1,255,-1,1276,-2,13,-1,233,-1,2,-1,253,-1,1,-1,255,-1,247,-1,1306,-1,1533,-1,1269,-1,1276,-1,2303,-1]},
"styles":
[{"f":"rgb(99,230,101)","s":"rgb(5,148,0)","lw":"0"}],
"geom":
[
{"s":0,"p":[4,143,5,144,3,146,1,146,2,143,4,143],"c":"layer1156_5098"},
{"s":0,"p":[-2,143,0,140,2,141,2,144,1,146,-2,144,-2,143],"c":"layer1156_5067"},
{"s":0,"p":[7,143,5,144,4,143,2,143,2,141,5,138,6,139,5,141,7,143],"c":"layer1156_5051"},
{"s":0,"p":[10,141,11,137,12,137,14,137,12,142,9,143,9,142,10,141],"c":"layer1156_5041"},
{"s":0,"p":[1,136,0,140,-2,143,-2,136,1,136],"c":"layer1156_5038"},
{"s":0,"p":[8,143,5,141,5,137,8,136,10,137,10,141,8,143],"c":"layer1156_5033"},
{"s":0,"p":[5,137,2,141,0,140,1,136,1,136,2,135,3,136,5,137],"c":"layer1156_5028"},
{"s":0,"p":[10,134,12,136,11,138,8,135,10,134],"c":"layer1156_5020"},
{"s":0,"p":[-2,133,0,136,-2,136,-2,133],"c":"layer1156_5005"},
{...}
...
]
}
¿Cómo podemos replicar el mismo (o similar) tipo de velocidad utilizando postgis (que es lo que parece que están utilizando también)?