60 votos

¿Crear polígonos vectoriales con un rendimiento de renderizado como el de GISCloud?

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:

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)?

23voto

Swinders Puntos 1042

Directamente del desarrollador Dino Ravnic en una reciente correo de la lista de correo :

No es un gran secreto cómo lo hicimos, así que estaría encantado de compartirlo la clave está en dos cosas:

  1. eliminar de una baldosa todos los vectores que son demasiado pequeños para ser visibles es decir, su área calculada en píxeles es inferior a 1px. vector y en su lugar colocamos un píxel, de ahí que exista la propiedad propiedad "pixels" en nuestro tile json

  2. vectores que serán realmente visibles se están generalizando y luego se escriben en un mosaico con sus coordenadas en píxeles

En la parte del cliente, renderizamos en el lienzo esos píxeles estáticos y visibles vectores visibles. Encima de los vectores implementamos el manejo de eventos del ratón para para lograr el hovering, es decir, la interactividad, y eso es todo.

Nuestro motor de mapas backend hace todo el trabajo pesado porque no usamos no utilizamos ningún tipo de precaching y todos los mosaicos se generan sobre la marcha. importante para nosotros tener un mapa que se pueda actualizar rápidamente.

Así que parece que el lado del cliente es la parte fácil. Es impresionante que los datos se rendericen sin ningún tipo de caché.

También menciona un servicio de alojamiento que puede ser de su interés. Puede que quiera sopesar el coste de intentar recrear esto con el coste de utilizar un servicio ya hecho.

14voto

helloandre Puntos 5784

Parece que es muy similar La pregunta fue formulada recientemente en el foro OSGeo Open Layers con los desarrolladores de GIS Cloud describiendo su enfoque, que es una interesante mezcla de geometrías GeoJSON y píxeles estáticos. En realidad, generan todos los mosaicos vectoriales sobre la marcha, en lugar de utilizar una caché preconstruida de archivos GeoJSON.

Esri ha aplicado un enfoque similar, utilizando ArcGIS Server y capas de características que puede generalizar las geometrías sobre la marcha y enviarlas por cable como JSON.

Para un método directo que puedes implementar ahora, puedes construir mosaicos vectoriales con Tilestache (que tiene Apoyo a PostGIS )y consumirlos en Polymaps . Polymaps utiliza SVG, pero el el rendimiento es bastante bueno y las reglas CSS para estilizar los elementos del mapa, por lo que la representación de las características depende totalmente de ti. Aquí es una entrada del blog que trabaja sobre algo similar a lo que estás preguntando.

6voto

Paul G Puntos 1615

No sé exactamente qué solución utiliza esta empresa (tal vez podrías preguntarles directamente) pero tengo una idea.

La solución clave para mejorar la velocidad de transferencia y renderización en red de los datos vectoriales es generalizarlos en función del nivel de zoom: Transferir y renderizar a un nivel de zoom alto miles de objetos diseñados para un nivel de zoom mucho más bajo suele consumir mucho tiempo (y además es inútil porque la visualización final no suele ser legible - véase por ejemplo esta imagen ). Para implementarlo, su base de datos del servidor postgis tiene que ser multiescala : Para cada nivel de zoom, debe haber una representación del objeto adecuada para este nivel de zoom. Estas diferentes representaciones pueden ser calculadas automáticamente utilizando técnicas de generalización . Además, los datos vectoriales enviados por el servidor al cliente no deben depender sólo de la extensión espacial, sino también del nivel de zoom: El servidor envía los datos adecuados en función del nivel de zoom. Este es el enfoque defendido en este excelente documento :-)

6voto

McDowell Puntos 62645

He jugado con OpenLayers usando Canvas y he obtenido resultados razonables.

Como se ha mencionado en las otras respuestas: para entregar y mostrar vectores al vuelo, es necesario generalizarlos para cada nivel de zoom y cada conjunto de datos. Además, se puede utilizar la codificación de polilíneas de Google para reducir considerablemente el tamaño.

Utilicé un mecanismo de entrega sencillo. Cada geometría era una función de JavaScript dentro de una respuesta HTTP de JavaScript. No es tan avanzado como la entrega de vectores basada en azulejos, pero es simple y de código abierto.

No he podido probar Google Maps v3 con Canvas, pero he visto un par de Demostraciones del New York Times que impresionó.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X