GeoJSON zu sperrig - was tun?

18

Ich verwende leaflet.js , um Webbenutzern die Auswahl einer Region zu ermöglichen. Gültige Regionen sind US-Bundesstaaten, kanadische Provinzen und Weltländer (außer USA und Kanada). Ich habe selbst ein Shapefile mit Qgis erstellt und es als Geojson gespeichert. Ich habe die Geometrien so weit wie möglich vereinfacht.

Das resultierende Shapefile hat eine Größe von 400 KB, der Geojson ist jedoch größer als ein Megabyte. Das ist größer als ich möchte. Ich muss den Netzwerkaufwand für die Übertragung dieser Informationen reduzieren.

Was ist der richtige Weg, um dies zu tun? Die Optionen, die ich mir vorstellen kann, sind:

  1. Servieren Sie die Geojson-Datei, entpacken Sie sie auf dem Client.
  2. Analysieren Sie das Shapefile auf dem Client in Geojson
  3. Generiere meine eigenen Kacheln aus dem Shapefile und bediene sie

Wenn mir jemand sagen könnte, welche Option die beste ist (oder keine der oben genannten), würde ich es begrüßen!

Mike Furlender
quelle
Ich stelle fest, dass Sie sagten, Sie hätten versucht, die Geometrie zu vereinfachen, aber haben Sie versucht, einen GIS-Vereinfachungsalgorithmus zu verwenden und die Ergebnisse zu überprüfen? Es kann auch hilfreich sein, zu prüfen, welcher Teil des JSON den meisten Speicherplatz belegt.
BradHards
1
Vergewissern Sie sich, dass der GeoJSON nicht hübsch gedruckt ist. Entfernen Sie alle unnötigen Leerzeichen, um die Datei zu verkleinern - nicht unbedingt um eine große Menge, aber es hilft alles!
CHenderson

Antworten:

13

Bevor Sie mühsamere Wege beschreiten, besteht die einfachste Möglichkeit darin, die Geometrie zu reduzieren. Was sind Ihre Quelldatensätze? Wie haben Sie sie vereinfacht? Um wie viel hat sich dadurch die Größe der Geojson-Datei verringert?

Wenn Sie zuversichtlich sind, dass Sie alles getan haben, was Sie können, dann ist die niedrigste hängende Frucht Ihrer Optionen

  1. Servieren Sie die Geojson-Datei gzip, entpacken Sie sie auf dem Client.

Alle modernen Browser entpacken komprimierte Daten automatisch. Sie müssen also lediglich Ihren Webserver so einrichten, dass die Daten vor dem Senden gepackt werden. Dies ist normalerweise relativ einfach, mit viel Material für Apache , IIS oder Nginx

Mein Tipp wäre, zuerst dies zu versuchen, dann zu testen, wenn Latenz / Antwort / Datengröße nicht akzeptabel ist, dann zu anderen Optionen zu wechseln. Ich wäre auch vorsichtig, wenn ich versuchen würde, vorzeitig zu optimieren. Ich würde versuchen, herauszufinden, warum Sie die Datengröße reduzieren müssen, und wenn Sie harte Gründe (und Zahlen) dafür haben, dann würde ich iterativ Änderungen implementieren und erneut testen, um zu sehen, was passiert Gewinne, die Sie bekommen.

Kelso
quelle
13

Mapshaper.org ist ein praktisches kostenloses Online-Tool, mit dem Sie eine Geojson-Datei hochladen, als Karte anzeigen und dann einen von drei Vereinfachungsalogrithmen auswählen können, deren Stärke Sie mit einem Schieberegler anpassen können.

Es aktualisiert die Karte und hebt alle Stellen rot hervor, an denen es zu einem Integritätsverlust kommt, z. B. zu einer Überlappung zwischen zwei Regionen. Es gibt eine Schaltfläche zum Beheben von Problemen, die normalerweise (aber nicht immer) solche Probleme behebt.

Sie können einen akzeptablen Vereinfachungsgrad finden und die neu vereinfachte Geojson-Datei exportieren.

Dies hängt natürlich davon ab, welche Detailstufe Sie benötigen, aber die Ergebnisse können beeindruckend sein. Hier ist beispielsweise eine Karte von Schottland aus einer 40-MB-Geojson-Datei:

Bildbeschreibung hier eingeben

Eine 99% -Anwendung reduziert es auf eine 441-KB-Datei ohne Überlappungen und Detailverlust, die in dieser Zoomstufe nicht sichtbar ist:

Bildbeschreibung hier eingeben

Eine 99,95% -Anwendung (bis zu 29 KB) zeigt, welche Art von Pfadvereinfachung angewendet wird (und dennoch Überschneidungen vermeidet und sich perfekt für Anwendungen wie Chloropleth auf nationaler Ebene eignet):

Bildbeschreibung hier eingeben

user56reinstatemonica8
quelle
Ich benutze dieses Tool die ganze Zeit. Es ist exzellent!
Mike Furlender
1
Du bist ein Lebensretter!!
Khizar
6

Ich frage mich, ob Sie die in dieser Antwort enthaltene Komprimierung nutzen können, in der es um die Komprimierung des GeoJSON mit Topojson geht .

Ich weiß nicht, ob Leaflet das GeoJSON noch lesen kann - etwas zum Ausprobieren =)

Weitere Informationen zu topojson: https://github.com/mbostock/topojson/

SaultDon
quelle
Leaflet.GeoJSON analysiert keine Bogendaten, daher funktioniert dieser Ansatz nicht
smcphill
Leaflet kann nicht nativ sein, aber Sie können topojson auf der Client-Seite verwenden, um dies zu tun, zum Beispiel topojson in leaflet , obwohl dieses Beispiel zufällig d3 verwendet, um es zu rendern.
Calvin
1
Ich hatte eine 27-MB-GeoJson-Datei. Ging zu mapshaper.org und nach Vereinfachung (1,0%) und Topojson Export wurde es 122kb. Danach habe ich den topoJson-Leaflet-Code von github.com/shramov/leaflet-plugins/blob/master/layer/vector/… zu meiner App hinzugefügt und Folgendes ausgeführt: new L.TOPOJSON ("myExported.topojson"). ToGeoJson ().
StackUnder
3

Ich stimme mit @Kelso oben über die Vereinfachung Ihrer Geometrie überein.

Wenn Sie keinen Zugriff auf den Server haben , um die Daten mit gzip abzulassen leicht konnte man einen Blick auf die nehmen Message Bibliothek Ihre GeoJSON in binäre Daten zu serialise (ich glaube , es ist eine Implementierung der BSON spec , die durch Dinge wie MongoDB verwendet wird Daten speichern, aber ich könnte mich irren) . Es gibt Bibliotheken in Python und Javascript (unter anderem), mit denen Sie die Daten serialisieren / deserialisieren können.

om_henners
quelle
2
MessagePack hat nichts mit BSON zu tun (laut stackoverflow.com/questions/6355497/… ist es in vielen Fällen sogar besser . Weitere interessante Informationen zu MessagePack und speziell zu Geojson finden Sie unter nelsonslog.wordpress.com/2012/06/22/checking -out-msgpack .
Kelso
Danke dafür @Kelso - hat die Antwort aktualisiert. Und auch ein guter Artikel!
Om_henners
1

Ich würde vorschlagen, nur Ihr eigenes prozedurales Array von Leaflet-Polygon-Objekten zu erstellen. Ich bin damit einverstanden, dass GeoJSON viel zu groß ist. Die Objektschlüsselnamen sind sehr beschreibend, aber möglicherweise auch unnötig lang. Ich mache so etwas:

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 ist ganz einfach. Es ist viel leichter als GeoJSON wie folgt:

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

    //etc...

Und für jedes einzelne Polygon wiederholen ... ugh ... viel zu aufgebläht imo. Fügt Ihrem JS viele Bytes hinzu. Wie ich schon sagte, die Schlüsselnamen sind nett und beschreibend ... aber sie sind lang und fügen Ihrer JS eine Menge unnötiger Tschüss hinzu.

Jake Wilson
quelle