Работа с картографическими данными в Mapbox GL JS неизбежно опирается на понятие ограничивающего прямоугольника (bounding box, bbox). Любая визуализация, фильтрация или запрос геоданных в пределах текущего экрана карты так или иначе сводится к вычислению и использованию географических границ.
Bounding box представляет собой прямоугольную область, заданную двумя точками: юго-западной и северо-восточной. В терминах долготы и широты это:
Такая структура позволяет быстро ограничивать выборку объектов, оптимизировать отрисовку и выполнять пространственные запросы без сложных геометрических вычислений.
В Mapbox GL JS основным инструментом работы с bbox выступает класс
LngLatBounds.
const bounds = new mapboxgl.LngLatBounds(
[-74.1, 40.7], // юго-запад
[-73.9, 40.8] // северо-восток
);
Этот объект инкапсулирует прямоугольную область на сфере и предоставляет методы для:
Расширение bbox происходит динамически:
bounds.extend([-73.95, 40.75]);
Каждое расширение пересчитывает минимальные и максимальные значения, формируя новый охватывающий прямоугольник.
Одним из ключевых сценариев является получение границ видимой области карты.
const bounds = map.getBounds();
Результат — экземпляр LngLatBounds, соответствующий
текущему экрану.
Практическое применение:
Пример получения координат:
const sw = bounds.getSouthWest();
const ne = bounds.getNorthEast();
console.log(sw.lng, sw.lat);
console.log(ne.lng, ne.lat);
Bounding box часто используется как параметр серверных запросов:
const bbox = map.getBounds().toArray();
fetch(`/api/points?bbox=${bbox.flat().join(',')}`)
.then(res => res.json())
.then(data => {
console.log(data);
});
Формат передачи обычно:
minLng,minLat,maxLng,maxLat
На стороне сервера bbox применяется для:
Mapbox GL JS позволяет извлекать объекты, попадающие в текущую область отображения:
const features = map.queryRenderedFeatures();
Сочетание с bbox:
const bounds = map.getBounds();
const features = map.queryRenderedFeatures({
layers: ['points-layer']
}).filter(feature => {
const [lng, lat] = feature.geometry.coordinates;
return bounds.contains([lng, lat]);
});
Такой подход используется, когда необходимо:
Одно из наиболее практичных применений bbox — управление камерой карты.
map.fitBounds([
[-74.1, 40.7],
[-73.9, 40.8]
]);
Этот метод автоматически:
Дополнительные параметры:
map.fitBounds(bounds, {
padding: 40,
maxZoom: 14,
duration: 1000
});
Envelope представляет собой минимальный прямоугольник, охватывающий геометрию любой формы. В отличие от bbox, который часто задаётся вручную или вычисляется для набора точек, envelope обычно является результатом геометрической операции.
В геопространственных библиотеках, таких как Turf.js, envelope вычисляется автоматически:
import envelope fr om '@turf/envelope';
const feature = {
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [
[
[-74.0, 40.7],
[-73.9, 40.7],
[-73.9, 40.8],
[-74.0, 40.8],
[-74.0, 40.7]
]
]
}
};
const env = envelope(feature);
Результатом является новый GeoJSON Polygon, представляющий bounding box исходной геометрии.
Несмотря на схожесть, эти понятия различаются по происхождению и контексту применения:
bbox:
envelope:
Envelope позволяет быстро получить грубую оценку географического охвата объекта:
const bboxFeature = envelope(geojsonFeature);
map.addSource('bbox', {
type: 'geojson',
data: bboxFeature
});
Типичные сценарии:
При работе с векторными тайлами bbox используется на нескольких уровнях:
Mapbox GL JS автоматически использует bounding box каждого тайла для:
BBox часто служит базой для более сложных операций:
Пересечение (intersection) Определение пересечения объектов с областью:
function intersects(bounds, point) {
return bounds.contains(point);
}
Включение (containment) Проверка принадлежности:
bounds.contains([lng, lat]);
Расширение (union-like behavior) Построение общего охвата:
bounds.extend(otherBounds.getSouthWest());
bounds.extend(otherBounds.getNorthEast());
Использование bbox позволяет существенно снижать вычислительную нагрузку:
Пример серверной фильтрации:
SEL ECT *
FR OM points
WH ERE lng BETWEEN minLng AND maxLng
AND lat BETWEEN minLat AND maxLat;
При перемещении карты bbox обновляется в реальном времени:
map.on('moveend', () => {
const bounds = map.getBounds();
updateData(bounds);
});
Это используется в системах:
GeoJSON-данные часто требуют вычисления envelope для определения области отображения:
const coordinates = geojson.features.flatMap(f => f.geometry.coordinates[0]);
let bounds = new mapboxgl.LngLatBounds();
coordinates.forEach(coord => {
bounds.extend(coord);
});
Результат эквивалентен envelope всей коллекции объектов.
В высоконагруженных приложениях bbox используется совместно с индексами:
Алгоритм:
Такой подход обеспечивает масштабируемость при миллионах объектов.
BBox в координатах широта/долгота имеет ограничения:
Для обхода применяются:
Envelope часто используется как шаг предварительной агрегации:
const clusterBounds = envelope(clusterFeature);
Это позволяет быстро оценивать пространственные группы без полной геометрической обработки.
При обработке потоковых данных bbox может формироваться постепенно:
let bounds = new mapboxgl.LngLatBounds();
stream.forEach(point => {
bounds.extend(point.coordinates);
});
Такой подход используется в:
Bounding box становится базовой абстракцией, вокруг которой строится вся логика взаимодействия с картой:
Envelope, в свою очередь, дополняет эту модель, обеспечивая автоматическое вычисление границ сложных объектов и служа связующим звеном между геометрией и визуализацией.