GeoJSON слишком громоздкий - что делать?

19

Я использую leaflet.js, чтобы позволить пользователям сети выбирать регион. Допустимыми регионами являются штаты США, Канады и страны мира (за исключением США и Канады). Я сам создал шейп-файл, используя Qgis, и сохранил его как геойсон. Я максимально упростил геометрию.

Результирующий шейп-файл имеет размер 400 КБ, но размер геоджона превышает мегабайт. Это больше, чем хотелось бы. Мне нужно уменьшить нагрузку на сеть, связанную с передачей этой информации.

Как правильно это сделать? Возможные варианты:

  1. Подайте файл geojson в gzipped, распакуйте на клиенте.
  2. Разобрать шейп-файл на клиенте для геойсона
  3. Создайте мои собственные плитки из шейп-файла и обслуживайте тех,

Если бы кто-нибудь мог сказать мне, какой вариант является лучшим (или ни один из вышеперечисленных), я был бы признателен за это!

Майк Фурлендер
источник
Отмечу, что вы сказали, что пытались упростить геометрию, но пытались ли вы использовать алгоритм упрощения ГИС и проверять результаты? Это также может помочь определить, какая часть JSON занимает больше места.
BradHards
1
Удостоверьтесь, что GeoJSON не очень хорошо напечатан, удаление всего ненужного пробела поможет уменьшить размер файла - не обязательно на огромное количество, но все это помогает!
Чендерсон

Ответы:

13

Прежде чем идти по более трудоемким путям, самый простой вариант - уменьшить геометрию. Каковы ваши исходные наборы данных? Как вы их упростили? Насколько это уменьшило размер файла geojson?

Если вы уверены в том, что сделали все, что могли, с учетом вышесказанного, то самый низкий из возможных вариантов:

  1. Подайте файл geojson в gzipped, распакуйте на клиенте.

Все современные браузеры выполняют распаковку сжатых данных автоматически, так что это всего лишь случай настройки вашего веб-сервера для упаковки данных перед отправкой. Как правило, это относительно просто, с большим количеством материала для Apache , IIS или Nginx

Мой совет - сначала попробуйте, протестируйте, затем, если задержка / ответ / размер данных неприемлемы, затем перейдите к другим параметрам. Я также опасался бы преждевременной оптимизации, я постарался бы определить, почему вам нужно уменьшить размер данных, и как только у вас есть веские причины (и цифры) для этого, а затем итеративно вносить изменения и повторно тестировать, чтобы увидеть, что выгоды, которые вы получаете.

Келсо
источник
13

Mapshaper.org - это удобный бесплатный онлайн-инструмент, который позволяет вам загрузить файл геоджона, отобразить его в виде карты, а затем выбрать один из трех упрощенных логарифмов, которые вы можете настроить с помощью ползунка.

Он обновляет карту и выделяет красным цветом любые места, где наблюдается потеря целостности, например, перекрытие между двумя регионами. Есть кнопка «исправить», которая обычно (но не всегда) устраняет такие проблемы.

Вы можете найти приемлемый уровень упрощения и экспортировать недавно упрощенный файл geojson.

Очевидно, это зависит от того, какой уровень детализации вам необходим, но результаты могут быть впечатляющими. Например, вот карта Шотландии из файла geojson размером 40 Мб:

введите описание изображения здесь

Приложение на 99% уменьшает его до файла 441 КБ без наложений и потери детализации, которые не видны при таком уровне масштабирования:

введите описание изображения здесь

Приложение на 99,95% (до 29 КБ) показывает, какой тип упрощения пути применяется (и все же удается избежать перекрытий, и идеально подходит для таких применений, как хлороплет на национальном уровне):

введите описание изображения здесь

user56reinstatemonica8
источник
Я использую этот инструмент все время. Это отлично!
Майк Фурлендер,
1
Вы спасатель!
Хизар
6

Интересно, можете ли вы использовать сжатие, найденное в этом ответе, в котором говорится о сжатии GeoJSON с помощью topojson .

Я не знаю, сможет ли Leaflet по-прежнему читать GeoJSON - что-то попробовать =)

Подробнее о топойсоне: https://github.com/mbostock/topojson/

SaultDon
источник
Leaflet.GeoJSON не анализирует данные дуги, поэтому этот подход не сработает
smcphill
Leaflet не может изначально, но вы можете использовать topojson на стороне клиента, чтобы сделать это, например topojson на листовке , хотя в этом примере для его визуализации используется d3.
Calvin
1
У меня был файл geoJson на 27 Мб. Зашел на mapshaper.org и после упрощения (1,0%) и экспорта топойсон стал 122кб. После этого я добавил в мою программу код листовки topoJson из github.com/shramov/leaflet-plugins/blob/master/layer/vector/… и сделал следующее: new L.TOPOJSON ("myExported.topojson"). ToGeoJson ().
StackUnder
3

Я согласен с @Kelso выше по поводу упрощения вашей геометрии.

Если у вас нет доступа к вашему серверу для простой дефляции данных с помощью gzip, вы можете взглянуть на библиотеку MessagePack для сериализации вашего geoJSON в двоичные данные (я считаю, что это реализация спецификации BSON, которая используется такими вещами, как MongoDB для хранить данные, но я могу ошибаться) . Есть библиотеки на Python и javascript (среди прочих), которые вы можете использовать для сериализации / десериализации данных.

om_henners
источник
2
MessagePack не связан с BSON (на самом деле он лучше во многих случаях, согласно stackoverflow.com/questions/6355497/… . Более интересную информацию о пакете сообщений и, в частности, о geojson, можно найти по адресу nelsonslog.wordpress.com/2012/06/22/checking. -out-msgpack .
Келсо
Спасибо за это @Kelso - обновил ответ. И хорошая статья тоже!
om_henners
1

Я бы предложил создать собственный процедурный массив объектов многоугольника Leaflet. Я согласен с тем, что GeoJSON слишком велик. Имена ключей объекта очень наглядны, но, возможно, излишне длинны. Я делаю такие вещи:

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

Это просто. Это намного легче, чем GeoJSON, вот так:

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

    //etc...

И повторяю для каждого многоугольника ... тьфу ... слишком раздутый имо. Добавляет много байтов в ваш JS. Как я уже сказал, имена ключей хороши и наглядны ... но они длинные и добавляют много ненужных прощаний вашему JS.

Джейк Уилсон
источник