GeoJSON quá cồng kềnh - phải làm gì?


18

Tôi đang sử dụng leaflet.js để cho phép người dùng web chọn một khu vực. Các khu vực hợp lệ là các tiểu bang của Hoa Kỳ, các cơ sở của Canada và các nước trên thế giới (trừ Hoa Kỳ và Canada). Tôi đã tự tạo một shapefile bằng cách sử dụng Qgis và lưu nó dưới dạng Geojson. Tôi đã đơn giản hóa hình học càng nhiều càng tốt.

Shapefile kết quả là 400kb, nhưng Geojson là hơn một megabyte. Điều này là lớn hơn tôi muốn. Tôi cần giảm chi phí mạng liên quan đến việc chuyển thông tin này.

Cách đúng đắn để làm điều này là gì? Các tùy chọn tôi có thể tưởng tượng là:

  1. Phục vụ tệp Geojson được nén, giải nén trên máy khách.
  2. Phân tích shapefile trên máy khách tới Geojson
  3. Tạo gạch của riêng tôi từ shapefile và phục vụ chúng

Nếu bất cứ ai có thể cho tôi biết lựa chọn nào là tốt nhất (hoặc không có gì ở trên) tôi sẽ đánh giá cao nó!


Tôi lưu ý rằng bạn đã nói rằng bạn đã cố gắng đơn giản hóa hình học, nhưng bạn đã thử sử dụng thuật toán đơn giản hóa GIS và kiểm tra kết quả chưa? Nó cũng có thể giúp xem xét phần nào của JSON chiếm nhiều không gian nhất.
BradHards

1
Hãy chắc chắn rằng GeoJSON không được in đẹp, tước hết các khoảng trắng không cần thiết sẽ giúp làm cho tệp nhỏ hơn - không nhất thiết phải bằng một số lượng lớn nhưng tất cả đều giúp ích!
Người dẫn chương trình

Câu trả lời:


13

Trước khi đi xuống bất kỳ con đường tốn nhiều công sức hơn, tùy chọn đơn giản nhất là giảm hình học. Bộ dữ liệu nguồn của bạn là gì? Làm thế nào bạn đơn giản hóa chúng? Làm thế nào nhiều điều này đã làm giảm kích thước tập tin Geojson?

Nếu bạn tự tin rằng bạn đã làm tất cả những gì bạn có thể ở trên, thì quả treo thấp nhất trong các lựa chọn của bạn là

  1. Phục vụ tệp Geojson được nén, giải nén trên máy khách.

Tất cả các trình duyệt hiện đại đều tự động giải nén dữ liệu được nén, vì vậy đây chỉ là trường hợp thiết lập máy chủ web của bạn để đóng gói dữ liệu trước khi gửi. Đây thường là một tương đối đơn giản, với nhiều tài liệu xung quanh cho Apache , IIS hoặc Nginx

Mẹo của tôi sẽ là thử cái này trước, kiểm tra, sau đó nếu độ trễ / phản hồi / kích thước dữ liệu không được chấp nhận, sau đó chuyển sang các tùy chọn khác. Tôi cũng sẽ cảnh giác khi cố gắng tối ưu hóa sớm, tôi sẽ tìm cách xác định lý do tại sao bạn cần giảm kích thước dữ liệu và một khi bạn có lý do cứng (và số) để làm như vậy, sau đó lặp lại thực hiện các thay đổi và kiểm tra lại để xem điều gì đạt được bạn đang nhận được.


13

Mapshaper.org là một công cụ trực tuyến miễn phí tiện dụng cho phép bạn tải lên tệp Geojson, hiển thị dưới dạng bản đồ, sau đó chọn một trong ba thuật toán đơn giản hóa mà bạn có thể điều chỉnh cường độ bằng một thanh trượt.

Nó cập nhật bản đồ và các điểm nổi bật màu đỏ ở bất kỳ nơi nào có sự mất toàn vẹn như sự chồng chéo giữa hai khu vực. Có nút 'sửa chữa' thường (nhưng không phải luôn luôn) khắc phục các sự cố như vậy.

Bạn có thể tìm thấy một mức độ đơn giản hóa có thể chấp nhận được và xuất tệp Geojson mới được đơn giản hóa.

Rõ ràng điều này phụ thuộc vào mức độ chi tiết bạn cần, nhưng kết quả có thể ấn tượng. Ví dụ: đây là bản đồ Scotland từ tệp Geojson 40mb:

nhập mô tả hình ảnh ở đây

Một ứng dụng 99% giảm nó thành tệp 441 kb mà không bị chồng chéo và mất chi tiết không nhìn thấy được ở mức thu phóng này:

nhập mô tả hình ảnh ở đây

Một ứng dụng 99,95% (giảm xuống 29kb) cho thấy loại đơn giản hóa đường dẫn nào đang được áp dụng (và vẫn quản lý để tránh chồng chéo, và hoàn toàn phù hợp cho các mục đích sử dụng như chloropleth cấp quốc gia):

nhập mô tả hình ảnh ở đây


Tôi sử dụng công cụ này tất cả các thời gian. Thật xuất sắc!
Mike Furlender

1
Bạn là một cứu cánh !!
Khizar

6

Tôi tự hỏi nếu bạn có thể sử dụng nén được tìm thấy trong câu trả lời này nói về việc nén GeoJSON với topojson .

Tôi không biết nếu Leaflet vẫn có thể đọc GeoJSON - thứ gì đó để thử =)

Tìm hiểu thêm về topojson: https://github.com/mbostock/topojson/


Leaflet.GeoJSON không phân tích dữ liệu vòng cung, vì vậy phương pháp này sẽ không hiệu quả
smcphill

Tờ rơi không thể tự nhiên nhưng bạn có thể sử dụng topojson ở phía máy khách để làm điều đó, ví dụ về topojson trên tờ rơi , mặc dù ví dụ đó xảy ra để sử dụng d3 để hiển thị nó.
Calvin

1
Tôi đã có một tệp GeoJson 27mb. Đã đi đến mapshaper.org và sau khi đơn giản hóa (1,0%) và xuất khẩu topojson, nó đã trở thành 122kb. Sau đó, đã thêm mã TopletJson Leaflet từ github.com/shramov/leaflet-plugins/blob/master/layer/vector/iêu vào ứng dụng của tôi và đã làm như sau: L.TOPOJSON mới ("myExported.topojson") .GeoJson ().
StackUnder

3

Tôi đồng ý với @Kelso ở trên về việc đơn giản hóa hình học của bạn.

Nếu bạn không có quyền truy cập vào máy chủ của mình để khử dữ liệu bằng gzip một cách dễ dàng, bạn có thể xem thư viện MessagePack để tuần tự hóa GeoJSON của bạn thành dữ liệu nhị phân (Tôi tin rằng đó là cách triển khai thông số BSON được sử dụng bởi những thứ như MongoDB lưu trữ dữ liệu, nhưng tôi có thể sai) . Có các thư viện trong Pythonjavascript (trong số những thư viện khác) mà bạn có thể sử dụng để tuần tự hóa / giải tuần tự dữ liệu.


2
MessagePack không liên quan đến BSON (thực sự tốt hơn trong nhiều trường hợp theo stackoverflow.com/questions/6355497/ .. Thông tin thú vị khác về gói tin và cụ thể là Geojson có thể được tìm thấy tại nelsonslog.wordpress.com/2012/06/22/checking -out-Spypack .
Kelso

Cảm ơn vì điều đó @Kelso - đã cập nhật câu trả lời. Và bài viết tốt quá!
om_henners

1

Tôi sẽ đề nghị chỉ tạo mảng thủ tục của riêng bạn về các đối tượng đa giác Leaflet. Tôi đồng ý với GeoJSON là quá lớn. Các tên khóa đối tượng rất mô tả nhưng cũng có thể dài không cần thiết. Tôi làm điều này

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

Thật đơn giản. Nó nhẹ hơn nhiều so với GeoJSON như thế này:

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

    //etc...

Và Lặp lại cho mọi đa giác đơn lẻ ... ugh ... quá imo quá. Thêm rất nhiều byte vào JS của bạn. Như tôi đã nói, các tên khóa rất hay và mô tả ... nhưng chúng dài và thêm rất nhiều tạm biệt không cần thiết vào JS của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.