Geobuf представляет собой бинарный формат сериализации геоданных, построенный поверх Protocol Buffers, предназначенный для компактного хранения и передачи структур GeoJSON. Его ключевая задача — уменьшить размер геоданных при сохранении логической структуры GeoJSON, которая широко используется в веб-картографии и, в частности, в связке с Mapbox GL JS.
В отличие от текстового GeoJSON, Geobuf не предназначен для прямого чтения или редактирования человеком. Он ориентирован исключительно на эффективную транспортировку и быструю десериализацию на клиенте.
Geobuf преобразует объекты GeoJSON в бинарное представление с использованием схемы Protocol Buffers. В основе лежит идея сжатия повторяющихся структур и числовой оптимизации геометрии.
Основные принципы кодирования:
"type",
"properties", "coordinates") заменяются на
бинарные поля protobuf;Ключевая особенность — упор на геометрические данные, которые составляют основную массу GeoJSON-документов.
Типичный цикл работы с Geobuf в веб-картографических приложениях выглядит следующим образом:
Mapbox GL JS не поддерживает Geobuf нативно, поэтому слой декодирования является обязательным.
Geobuf обеспечивает значительное уменьшение размера по сравнению с GeoJSON:
В реальных сценариях снижение может достигать 30–80% в зависимости от структуры данных.
Меньший размер напрямую влияет на:
Protocol Buffers обеспечивают:
Несмотря на эффективность, Geobuf имеет ряд ограничений:
Mapbox GL JS работает с GeoJSON, vector tiles и raster sources. Geobuf требует промежуточного слоя декодирования.
Хотя уменьшается сеть, появляется нагрузка на браузер:
Geobuf невозможно инспектировать без декодирования, что усложняет:
Основные инструменты:
geobuf — основная библиотека для
кодирования/декодирования;pbf — низкоуровневый protobuf парсер.Типичная связка выглядит следующим образом:
geobuf.decode(buffer, new Pbf(buffer))geobuf.encode(geojson, new Pbf())Так как Mapbox GL JS принимает GeoJSON, требуется декодирование перед передачей в источник.
Пример загрузки Geobuf:
import mapboxgl from "mapbox-gl";
import geobuf from "geobuf";
import Pbf from "pbf";
async function loadGeobufSource(url, map) {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
const geojson = geobuf.decode(new Pbf(new Uint8Array(arrayBuffer)));
map.addSource("geobuf-source", {
type: "geojson",
data: geojson
});
}
После декодирования данные становятся полностью совместимыми с системой слоёв Mapbox GL JS:
map.addLayer({
id: "points-layer",
type: "circle",
source: "geobuf-source",
paint: {
"circle-radius": 5,
"circle-color": "#ff5500"
}
});
Декодирование Geobuf может быть вынесено в отдельный поток, чтобы избежать блокировки UI:
// worker.js
importScripts("geobuf.js", "pbf.js");
onmess age = function (e) {
const buffer = e.data;
const geojson = geobuf.decode(new Pbf(buffer));
postMessage(geojson);
};
Основной поток:
const worker = new Worker("worker.js");
fetch("/data.geobuf")
.then(r => r.arrayBuffer())
.then(buffer => {
worker.postMessage(buffer, [buffer]);
});
worker.onmess age = function (e) {
map.addSource("data", {
type: "geojson",
data: e.data
});
};
Такой подход особенно эффективен при работе с десятками мегабайт геоданных.
Генерация Geobuf чаще всего выполняется на сервере для снижения нагрузки на клиента.
Пример на Node.js:
import geobuf from "geobuf";
import Pbf from "pbf";
import fs from "fs";
const geojson = JSON.parse(fs.readFileSync("data.json", "utf8"));
const buffer = geobuf.encode(geojson, new Pbf());
fs.writeFileSync("data.geobuf", Buffer.from(buffer));
В связке с PostGIS возможна генерация GeoJSON через SQL-запрос и последующее кодирование в Geobuf на backend-слое.
Geobuf часто занимает промежуточную позицию между GeoJSON и vector tiles.
Mapbox GL JS позволяет динамически обновлять источник GeoJSON, что критично для Geobuf-потока.
map.getSource("geobuf-source").setData(decodedGeojson);
При потоковой загрузке данных возможны сценарии:
При использовании Geobuf эффективно работают следующие стратегии:
Geobuf хорошо кэшируется как бинарный ресурс без необходимости повторного декодирования при каждом запросе.
Ключевые факторы производительности:
В сценариях с десятками тысяч объектов Geobuf снижает сетевую нагрузку, но основная стоимость смещается в CPU-декодирование.
Используется предварительно сгенерированный .geobuf файл
и однократное декодирование при загрузке карты.
Geobuf поступает частями, декодируется и обновляет источник через
setData.
Geobuf применяется для вспомогательных слоёв (например, аналитика, heatmap), тогда как основная карта работает на MVT.
Geobuf не является частью нативного пайплайна Mapbox GL JS, однако он эффективно закрывает нишу между серверной генерацией GeoJSON и клиентской визуализацией.
Его использование оправдано в случаях, когда: