GeoJSON zbyt masywny - co robić?

19

Korzystam z pliku leaflet.js, aby umożliwić użytkownikom sieci wybrać region. Prawidłowe regiony to stany USA, kanadyjskie opatrzności i kraje świata (z wyjątkiem Stanów Zjednoczonych i Kanady). Sam zbudowałem plik kształtu za pomocą Qgis i zapisałem go jako geojson. Uprościłem geometrie tak bardzo, jak tylko mogłem.

Otrzymany plik kształtu ma rozmiar 400 kb, ale geojson ma ponad megabajt. To jest większe niż chciałbym. Muszę zmniejszyć obciążenie sieci związane z przesyłaniem tych informacji.

Jak to zrobić? Opcje, które mogę sobie wyobrazić to:

  1. Podaj spakowany plik geojson, rozpakuj na kliencie.
  2. Przekształć plik kształtu na kliencie w geojson
  3. Wygeneruj własne kafelki z pliku kształtu i podaj je

Jeśli ktoś mógłby mi powiedzieć, która opcja jest najlepsza (lub żadna z powyższych), byłbym wdzięczny!

Mike Furlender
źródło
Zauważam, że powiedziałeś, że próbowałeś uprościć geometrię, ale czy próbowałeś użyć algorytmu uproszczenia GIS i sprawdzić wyniki? Pomocne może być również sprawdzenie, która część JSON zajmuje najwięcej miejsca.
BradHards
1
Upewnij się, że GeoJSON nie jest ładnie wydrukowany, usunięcie niepotrzebnych białych znaków pomoże zmniejszyć plik - niekoniecznie o ogromną ilość, ale wszystko pomaga!
CHenderson

Odpowiedzi:

13

Przed zejściem bardziej pracochłonnymi ścieżkami najprostszą opcją jest zmniejszenie geometrii. Jakie są twoje źródła danych? Jak je uprościłeś? Jak bardzo to zmniejszyło rozmiar pliku geojson?

Jeśli masz pewność, że zrobiłeś wszystko, co w powyższym przypadku, to najniższy wiszący owoc spośród twoich opcji to

  1. Podaj spakowany plik geojson, rozpakuj na kliencie.

Wszystkie nowoczesne przeglądarki rozpakowują automatycznie rozpakowane dane, więc jest to tylko przypadek skonfigurowania serwera WWW do pakowania danych przed wysłaniem. Zwykle jest to stosunkowo proste, z dużą ilością materiału dla Apache , IIS lub Nginx

Moją wskazówką byłoby wypróbowanie tego w pierwszej kolejności, przetestowanie, a następnie jeśli opóźnienie / odpowiedź / rozmiar danych jest niedopuszczalny, a następnie przejdź do innych opcji. Byłbym też ostrożny przed próbą optymalizacji przedwcześnie, chciałbym ustalić, dlaczego musisz zmniejszyć rozmiar danych, a gdy masz już poważne powody (i liczby), a następnie iteracyjnie wdrażać zmiany i ponownie testować, aby zobaczyć, co zyski, które otrzymujesz.

Kelso
źródło
13

Mapshaper.org to poręczne bezpłatne narzędzie online, które pozwala przesłać plik geojson, wyświetlić go jako mapę, a następnie wybrać jeden z trzech alogrithimów uproszczenia, które można dostosować za pomocą suwaka.

Aktualizuje mapę i wyróżnia na czerwono wszystkie miejsca, w których występuje utrata integralności, np. Nakładanie się dwóch regionów. Istnieje przycisk „napraw”, który zwykle (ale nie zawsze) naprawia takie problemy.

Możesz znaleźć akceptowalny poziom uproszczenia i wyeksportować nowo uproszczony plik geojson.

Oczywiście zależy to od wymaganego poziomu szczegółowości, ale wyniki mogą być imponujące. Na przykład, oto mapa Szkocji z pliku geojson o wielkości 40 MB:

wprowadź opis zdjęcia tutaj

Aplikacja 99% redukuje go do pliku 441 kb bez nakładania się i utraty szczegółów, która jest niewidoczna na tym poziomie powiększenia:

wprowadź opis zdjęcia tutaj

Aplikacja 99,95% (do 29 kb) pokazuje, jakie uproszczenie ścieżki jest stosowane (i nadal udaje się uniknąć nakładania się, i doskonale nadaje się do zastosowań takich jak chloroplet na poziomie krajowym):

wprowadź opis zdjęcia tutaj

user56reinstatemonica8
źródło
Cały czas używam tego narzędzia. To jest świetne!
Mike Furlender
1
Jesteś ratownikiem !!
Khizar
6

Zastanawiam się, czy mógłbyś skorzystać z kompresji znalezionej w tej odpowiedzi, która mówi o kompresji GeoJSON za pomocą topojson .

Nie wiem, czy Ulotka nadal będzie mogła czytać GeoJSON - coś do spróbowania =)

Więcej informacji o topojson: https://github.com/mbostock/topojson/

SaultDon
źródło
Leaflet.GeoJSON nie analizuje danych łuku, więc to podejście nie zadziała
smcphill
Ulotka nie może natywnie, ale możesz to zrobić za pomocą topojson po stronie klienta, przykład topojson na ulotce , chociaż ten przykład używa d3 do jej renderowania.
Calvin
1
Miałem plik geoJson o wielkości 27 MB. Poszedłem do mapshaper.org i po uproszczeniu (1,0%) i eksporcie topojson stał się 122kb. Następnie dodałem do mojej aplikacji kod ulotki topoJson z github.com/shramov/leaflet-plugins/blob/master/layer/vector/... i wykonałem następujące czynności: nowy L.TOPOJSON („myExported.topojson”). ToGeoJson ().
StackUnder
3

Zgadzam się z @Kelso powyżej w sprawie uproszczenia geometrii.

Jeśli nie masz dostępu do swojego serwera, aby łatwo spuścić powietrze z gzip, możesz spojrzeć na bibliotekę MessagePack, aby serializować geoJSON na dane binarne (uważam, że jest to implementacja specyfikacji BSON, która jest używana przez takie rzeczy jak MongoDB do przechowywać dane, ale mogę się mylić) . Istnieją biblioteki w Pythonie i javascript (między innymi), których można użyć do serializacji / deserializacji danych.

om_henners
źródło
2
MessagePack nie jest związany z BSON (w rzeczywistości jest lepszy w wielu przypadkach zgodnie z stackoverflow.com/questions/6355497/...) . Więcej interesujących informacji o pakiecie wiadomości i konkretnie geojsonie można znaleźć na stronie nelsonslog.wordpress.com/2012/06/22/checking wymeldowanie-msgpack .
Kelso
Dzięki za @Kelso - zaktualizowałem odpowiedź. I też dobry artykuł!
om_henners 15.01.2013
1

Proponuję po prostu stworzyć własną tablicę proceduralną obiektów Ulotka Wielokąt. Zgadzam się, że GeoJSON jest zdecydowanie za duży. Nazwy kluczy obiektów są bardzo opisowe, ale mogą być również niepotrzebnie długie. Robię takie rzeczy:

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

To proste. Jest o wiele lżejszy niż GeoJSON w następujący sposób:

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

    //etc...

I powtórz dla każdego wielokąta ... ugh ... zdecydowanie zbyt rozdęty imo. Dodaje dużo bajtów do JS. Jak powiedziałem, kluczowe nazwy są ładne i opisowe ... ale są długie i dodają wiele niepotrzebnych pożegnań do twojego JS.

Jake Wilson
źródło