GeoJSON demasiado voluminoso - ¿qué hacer?

17

Estoy usando leaflet.js para permitir que los usuarios web seleccionen una región. Las regiones válidas son estados de EE. UU., Provincias canadienses y países del mundo (excepto EE. UU. Y Canadá). Construí un shapefile usando Qgis y lo guardé como un geojson. Simplifiqué las geometrías tanto como pude.

El archivo de forma resultante es de 400 kb, pero el geojson tiene más de un megabyte. Esto es más grande de lo que me gustaría. Necesito reducir la sobrecarga de red involucrada en la transferencia de esta información.

¿Cuál es la forma correcta de hacer esto? Las opciones que puedo imaginar son:

  1. Servir el archivo geojson gzipped, descomprimir en el cliente.
  2. Analizar el shapefile en el cliente para geojson
  3. Generar mis propios mosaicos desde el shapefile y servirlos

¡Si alguien pudiera decirme qué opción es la mejor (o ninguna de las anteriores) lo apreciaría!

    
pregunta Mike Furlender 14.01.2013 - 05:56

5 respuestas

11

Antes de seguir por caminos más complicados, la opción más sencilla es reducir la geometría. ¿Cuáles son sus fuentes de datos de origen? ¿Cómo los simplificaste? ¿Cuánto redujo esto el tamaño del archivo geojson?

Si está seguro de haber hecho todo lo posible por lo anterior, el resultado más bajo de sus opciones es

  
  1. Servir el archivo geojson gzipped, descomprimir en el cliente.
  2.   

Todos los navegadores modernos desempaquetan los datos comprimidos automáticamente, por lo que es solo un caso de configurar su servidor web para empaquetar los datos antes de enviarlos. Esto suele ser relativamente sencillo, con mucho material por ahí para Apache , IIS o Nginx

Mi consejo sería intentar esto primero, probar, luego si la latencia / respuesta / tamaño de los datos no es aceptable, luego pasar a otras opciones. También desconfiaría de tratar de optimizar de manera prematura, buscaría determinar por qué necesita reducir el tamaño de los datos y, una vez que tenga razones (y números) difíciles para hacerlo, implementar cambios iterativos y volver a realizar pruebas para ver qué ganancias que está obteniendo.

    
respondido por el Kelso 14.01.2013 - 07:13
8

Mapshaper.org es una útil herramienta en línea gratuita que le permite cargar un archivo geojson, mostrarlo como un mapa, luego elegir uno de los tres alogritos de simplificación que puede ajustar la fuerza con un control deslizante.

Actualiza el mapa y resalta en rojo cualquier lugar donde haya una pérdida de integridad, como una superposición entre dos regiones. Hay un botón 'corregir' que generalmente (pero no siempre) soluciona estos problemas.

Puede encontrar un nivel de simplificación que sea aceptable y exportar el archivo geojson recientemente simplificado.

Obviamente, esto depende del nivel de detalle que necesite, pero los resultados pueden ser impresionantes. Por ejemplo, aquí está el mapa de Escocia de un archivo geojson de 40 mb:

Unaaplicacióndel99%loreduceaunarchivode441kbsinsuperposicionesypérdidadedetallesqueesinvisibleenesteniveldezoom:

Unaaplicaciónde99.95%(hasta29kb)muestraquétipodesimplificaciónderutaseestáaplicando(yaúnselasarreglaparaevitarsuperposiciones,yesperfectamenteadecuadaparausoscomocloropletasanivelnacional):

    
respondido por el user568458 24.07.2016 - 19:45
6

Me pregunto si podría utilizar la compresión encontrada en esta respuesta que habla de comprimiendo el GeoJSON con topojson .

No sé si Leaflet todavía podrá leer el GeoJSON - algo para probar =)

Más sobre topojson: enlace

    
respondido por el SaultDon 15.01.2013 - 06:56
3

Estoy de acuerdo con @Kelso arriba en simplificar tu geometría.

Si no tiene acceso a su servidor para desinflar los datos con gzip fácilmente, puede consultar la biblioteca MessagePack para serializar su geoJSON en datos binarios (creo que es una implementación de la BSON spec que utilizan MongoDB para almacenar datos, pero podría estar equivocado) . Hay bibliotecas en Python y javascript (entre otros) que puede usar para serializar / deserializar los datos.

    
respondido por el om_henners 14.01.2013 - 07:33
1

Sugeriría simplemente crear su propia matriz de procedimientos de objetos de polígono de folletos. Estoy de acuerdo con que GeoJSON es demasiado grande. Los nombres de las claves de los objetos son muy descriptivos pero quizás innecesariamente largos también. Hago este tipo de cosas:

objects = [];
objects.push( new L.polygon([[1,1],[1,2],[3,4]],options );
objects.push( new L.polygon([[4,7],[8,27],[35,66]],options );
objects.push( new L.polygon([[3,5],[56,24],[13,49]],options );
objects.push( new L.polygon([[13,7],[7,68],[23,9]],options );
layerGroup = L.layerGroup(objects).addTo(map);

Es sencillo. Es mucho más liviano que GeoJSON como este:

{ "type": "FeatureCollection",
  "features": [
    { "type": "Feature",
      "geometry": {"type": "Polygon",
      "coordinates": [1,1],[1,2],[3,4]},
      },

    //etc...

Y repita para cada polígono ... ugh ... demasiado hinchado imo. Agrega muchos bytes a tu JS. Como dije, los nombres de las teclas son agradables y descriptivos ... pero son largos y agregan muchos byes innecesarios a tu JS.

    
respondido por el Jake Wilson 16.04.2013 - 08:14

Lea otras preguntas en las etiquetas