GeoJSON terlalu besar - apa yang harus dilakukan?


19

Saya menggunakan leaflet.js untuk memungkinkan pengguna web memilih suatu wilayah. Wilayah yang valid adalah negara bagian AS, negara Kanada, dan negara dunia (kecuali AS dan Kanada). Saya membuat shapefile sendiri menggunakan Qgis dan menyimpannya sebagai geojson. Saya menyederhanakan geometri sebanyak yang saya bisa.

Shapefile yang dihasilkan adalah 400kb, tetapi geojson lebih dari satu megabyte. Ini lebih besar dari yang saya inginkan. Saya perlu mengurangi overhead jaringan yang terlibat dalam mentransfer informasi ini.

Apa cara yang tepat untuk melakukan ini? Opsi yang dapat saya bayangkan adalah:

  1. Sajikan file geojson yang di-gzip, buka kemasannya di klien.
  2. Parse shapefile pada klien ke geojson
  3. Hasilkan ubin saya sendiri dari shapefile dan sajikan

Jika ada yang bisa memberi tahu saya opsi mana yang terbaik (atau tidak ada di atas) saya akan sangat menghargainya!


Saya perhatikan bahwa Anda mengatakan Anda mencoba menyederhanakan geometri, tetapi sudahkah Anda mencoba menggunakan algoritma penyederhanaan GIS dan memeriksa hasilnya? Mungkin juga membantu untuk melihat bagian JSON mana yang paling banyak mengambil ruang.
BradHards

1
Pastikan GeoJSON tidak cukup dicetak, menghapus semua ruang putih yang tidak perlu akan membantu membuat file lebih kecil - tidak harus dengan jumlah besar tetapi semua membantu!
CHenderson

Jawaban:


13

Sebelum menyusuri jalan yang lebih sulit, pilihan paling sederhana adalah mengurangi geometri. Apa dataset sumber Anda? Bagaimana Anda menyederhanakannya? Berapa ini mengurangi ukuran file geojson?

Jika Anda yakin bahwa Anda telah melakukan semua yang Anda bisa di atas, maka buah terendah pilihan Anda adalah

  1. Sajikan file geojson yang di-gzip, buka kemasannya di klien.

Semua browser modern melakukan pembongkaran data yang di-gzip secara otomatis, jadi hanya menyiapkan server web Anda untuk mengemas data sebelum mengirim. Ini biasanya relatif lurus ke depan, dengan banyak materi di luar sana untuk Apache , IIS atau Nginx

Kiat saya adalah untuk mencoba ini dulu, tes, lalu jika latensi / respons / ukuran data tidak dapat diterima, maka pindah ke opsi lain. Saya juga akan berhati-hati mencoba mengoptimalkan sebelum waktunya, saya akan mencari untuk menentukan mengapa Anda perlu mengurangi ukuran data, dan begitu Anda memiliki alasan (dan angka) yang sulit untuk melakukannya, maka secara iteratif menerapkan perubahan dan menguji ulang untuk melihat apa Keuntungan yang Anda dapatkan.


13

Mapshaper.org adalah alat online gratis yang berguna yang memungkinkan Anda untuk mengunggah file geojson, menampilkannya sebagai peta, lalu memilih salah satu dari tiga alogrithim penyederhanaan yang dapat Anda sesuaikan kekuatannya dengan slider.

Ini memperbarui peta dan menyoroti dalam warna merah di setiap tempat di mana ada kehilangan integritas seperti tumpang tindih antara dua wilayah. Ada tombol 'memperbaiki' yang biasanya (tetapi tidak selalu) memperbaiki masalah seperti itu.

Anda dapat menemukan tingkat penyederhanaan yang dapat diterima dan mengekspor file geojson yang baru disederhanakan.

Jelas ini tergantung pada tingkat detail yang Anda butuhkan, tetapi hasilnya bisa mengesankan. Misalnya, ini peta Skotlandia dari file geojson 40mb:

masukkan deskripsi gambar di sini

Aplikasi 99% menguranginya menjadi file 441 kb tanpa tumpang tindih dan kehilangan detail yang tidak terlihat pada tingkat zoom ini:

masukkan deskripsi gambar di sini

Aplikasi 99,95% (hingga 29 kb) menunjukkan penyederhanaan jalur seperti apa yang sedang diterapkan (dan masih berhasil menghindari tumpang tindih, dan sangat cocok untuk penggunaan seperti kloropleth tingkat nasional):

masukkan deskripsi gambar di sini


Saya menggunakan alat ini sepanjang waktu. Itu sangat baik!
Mike Furlender

1
Anda adalah penyelamat !!
Khizar

6

Saya ingin tahu apakah Anda dapat menggunakan kompresi yang ditemukan dalam jawaban ini yang berbicara tentang mengompresi GeoJSON dengan topojson .

Saya tidak tahu apakah Leaflet masih dapat membaca GeoJSON - sesuatu untuk dicoba =)

Lebih lanjut tentang topojson: https://github.com/mbostock/topojson/


Leaflet.GeoJSON tidak mem-parsing data arc, jadi pendekatan ini tidak akan berfungsi
smcphill

Leaflet tidak bisa secara asli tetapi Anda bisa menggunakan topojson di sisi klien untuk melakukannya, contoh topojson di leaflet , meskipun contoh itu kebetulan menggunakan d3 untuk merendernya.
Calvin

1
Saya punya file geoJson 27MB. Pergi ke mapshaper.org dan setelah menyederhanakan (1,0%) dan ekspor topojson menjadi 122kb. Setelah itu menambahkan kode Leaflet topoJson dari github.com/shramov/leaflet-plugins/blob/master/layer/vector/… ke aplikasi saya dan melakukan hal berikut: L.TOPOJSON baru ("myExported.topojson"). ToGeoJson ().
StackUnder

3

Saya setuju dengan @Kelso di atas untuk menyederhanakan geometri Anda.

Jika Anda tidak memiliki akses ke server Anda untuk mengempiskan data dengan gzip dengan mudah, Anda bisa melihat pustaka MessagePack untuk membuat serial geoJSON Anda menjadi data biner (saya percaya ini adalah implementasi dari spesifikasi BSON yang digunakan oleh hal-hal seperti MongoDB untuk menyimpan data, tetapi saya bisa saja salah) . Ada perpustakaan dalam Python dan javascript (antara lain) yang dapat Anda gunakan untuk membuat serial / deserialise data.


2
MessagePack tidak terkait dengan BSON (sebenarnya lebih baik dalam banyak kasus sesuai dengan stackoverflow.com/questions/6355497/ ... .Info lebih menarik tentang messagepack dan secara khusus geojson dapat ditemukan di nelsonslog.wordpress.com/2012/06/22/checking -out-msgpack .
Kelso

Terima kasih untuk @elso - perbarui jawabannya. Dan artikel bagus juga!
om_henners

1

Saya sarankan hanya membuat array prosedural Anda sendiri dari objek Leaflet Polygon. Saya setuju dengan GeoJSON terlalu besar. Nama kunci objek sangat deskriptif tapi mungkin terlalu panjang. Saya melakukan hal semacam ini:

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

Sangat mudah. Ini jauh lebih ringan daripada GeoJSON seperti ini:

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

    //etc...

Dan Ulangi untuk setiap poligon ... ugh ... terlalu imo. Menambahkan banyak byte ke JS Anda. Seperti yang saya katakan, nama kuncinya bagus dan deskriptif ... tetapi mereka panjang dan menambahkan banyak bye yang tidak perlu ke JS Anda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.