GeoJSON trop volumineux - que faire?

19

J'utilise leaflet.js pour permettre aux internautes de sélectionner une région. Les régions valides sont les États américains, les provinces canadiennes et les pays du monde (à l'exception des États-Unis et du Canada). J'ai moi-même construit un fichier de formes à l'aide de Qgis et l'ai enregistré en tant que geojson. J'ai simplifié autant que possible les géométries.

Le fichier de formes résultant est de 400 Ko, mais le geojson dépasse un mégaoctet. C'est plus grand que je ne le souhaiterais. J'ai besoin de réduire les frais généraux du réseau impliqués dans le transfert de ces informations.

Quel est le bon moyen de le faire? Les options que je peux imaginer sont:

  1. Servir le fichier geojson compressé, décompresser sur le client.
  2. Analyser le fichier de formes sur le client pour geojson
  3. Générer mes propres tuiles à partir du fichier de formes et servir celles

Si quelqu'un pouvait me dire quelle option est la meilleure (ou rien de ce qui précède), je l'apprécierais!

Mike Furlender
la source
Je note que vous avez dit que vous avez essayé de simplifier la géométrie, mais avez-vous essayé d'utiliser un algorithme de simplification SIG et de vérifier les résultats? Il peut également être utile de déterminer quelle partie du JSON occupe le plus d'espace.
BradHards
1
Assurez-vous que le GeoJSON n'est pas assez imprimé, en supprimant tout espace blanc inutile aidera à rendre le fichier plus petit - pas nécessairement d'une énorme quantité mais tout cela aide!
CHenderson

Réponses:

13

Avant de descendre des chemins plus laborieux, l'option la plus simple est de réduire la géométrie. Quels sont vos jeux de données source? Comment les avez-vous simplifiés? Dans quelle mesure cela a-t-il réduit la taille du fichier geojson?

Si vous êtes sûr d'avoir fait tout ce que vous pouvez sur ce qui précède, alors le fruit le plus bas de vos options est

  1. Servir le fichier geojson compressé, décompresser sur le client.

Tous les navigateurs modernes effectuent le déballage automatique des données compressées, il s'agit donc simplement de configurer votre serveur Web pour emballer les données avant l'envoi. Ceci est normalement relativement simple, avec beaucoup de matériel pour Apache , IIS ou Nginx

Mon conseil serait d'essayer d'abord, de tester, puis si la latence / réponse / taille des données n'est pas acceptable, passer à d'autres options. Je me méfierais également d'essayer d'optimiser prématurément, je chercherais à déterminer pourquoi vous devez réduire la taille des données, et une fois que vous avez des raisons (et des chiffres) difficiles à le faire, puis à mettre en œuvre de manière itérative des changements et à refaire des tests pour voir ce que les gains que vous obtenez.

Kelso
la source
13

Mapshaper.org est un outil en ligne gratuit et pratique qui vous permet de télécharger un fichier geojson, de l'afficher sous forme de carte, puis de choisir l'une des trois alogrithims de simplification dont vous pouvez ajuster la force avec un curseur.

Il met à jour la carte et met en évidence en rouge tous les endroits où il y a une perte d'intégrité comme un chevauchement entre deux régions. Il y a un bouton «corriger» qui résout généralement (mais pas toujours) ces problèmes.

Vous pouvez trouver un niveau de simplification acceptable et exporter le fichier geojson nouvellement simplifié.

Évidemment, cela dépend du niveau de détail dont vous avez besoin, mais les résultats peuvent être impressionnants. Par exemple, voici la carte de l'Écosse à partir d'un fichier geojson de 40 Mo:

entrez la description de l'image ici

Une application à 99% le réduit à un fichier de 441 ko sans chevauchements et perte de détails invisible à ce niveau de zoom:

entrez la description de l'image ici

Une application à 99,95% (jusqu'à 29 Ko) montre quel type de simplification de chemin est appliqué (et parvient toujours à éviter les chevauchements, et convient parfaitement à des utilisations comme le chloroplèth au niveau national):

entrez la description de l'image ici

user56reinstatemonica8
la source
J'utilise cet outil tout le temps. C'est excellent!
Mike Furlender
1
Tu es un sauveur!!
Khizar
6

Je me demande si vous pourriez utiliser la compression trouvée dans cette réponse qui parle de compresser le GeoJSON avec topojson .

Je ne sais pas si Leaflet pourra toujours lire le GeoJSON - quelque chose à essayer =)

En savoir plus sur topojson: https://github.com/mbostock/topojson/

SaultDon
la source
Leaflet.GeoJSON n'analyse pas les données d'arc, donc cette approche ne fonctionnera pas
smcphill
Leaflet ne peut pas nativement mais vous pouvez utiliser topojson côté client pour le faire, exemple de topojson sur leaflet , bien que cet exemple arrive à utiliser d3 pour le rendre.
Calvin
1
J'avais un fichier geoJson de 27 Mo. Je suis allé sur mapshaper.org et après avoir simplifié (1.0%) et exporté topojson, il est devenu 122kb. Après cela, j'ai ajouté le code topoJson Leaflet de github.com/shramov/leaflet-plugins/blob/master/layer/vector/… à mon application et fait ce qui suit: nouveau L.TOPOJSON ("myExported.topojson"). ToGeoJson ().
StackUnder
3

Je suis d'accord avec @Kelso ci-dessus sur la simplification de votre géométrie.

Si vous n'avez pas accès à votre serveur pour dégonfler facilement les données avec gzip, vous pouvez jeter un œil à la bibliothèque MessagePack pour sérialiser votre geoJSON en données binaires (je crois que c'est une implémentation de la spécification BSON qui est utilisée par des choses comme MongoDB pour stocker des données, mais je peux me tromper) . Il existe des bibliothèques en Python et javascript (entre autres) que vous pouvez utiliser pour sérialiser / désérialiser les données.

om_henners
la source
2
MessagePack n'est pas lié à BSON (c'est en fait mieux dans de nombreux cas selon stackoverflow.com/questions/6355497/… . Plus d'informations intéressantes sur messagepack et spécifiquement geojson peuvent être trouvées sur nelsonslog.wordpress.com/2012/06/22/checking -out-msgpack .
Kelso
Merci pour cela @Kelso - a mis à jour la réponse. Et bon article aussi!
om_henners
1

Je suggérerais simplement de créer votre propre tableau procédural d'objets Leaflet Polygon. Je suis d'accord avec GeoJSON étant trop grand. Les noms de clé d'objet sont très descriptifs mais peuvent aussi être inutilement longs. Je fais ce genre de chose:

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

C'est simple. Il est beaucoup plus léger que GeoJSON comme ceci:

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

    //etc...

Et répétez pour chaque polygone ... ugh ... trop gonflé imo. Ajoute beaucoup d'octets à votre JS. Comme je l'ai dit, les noms des clés sont agréables et descriptifs ... mais ils sont longs et ajoutent beaucoup de byes inutiles à votre JS.

Jake Wilson
la source