Bbox и envelope

Пространственные границы как основа работы с картой

Работа с картографическими данными в Mapbox GL JS неизбежно опирается на понятие ограничивающего прямоугольника (bounding box, bbox). Любая визуализация, фильтрация или запрос геоданных в пределах текущего экрана карты так или иначе сводится к вычислению и использованию географических границ.

Bounding box представляет собой прямоугольную область, заданную двумя точками: юго-западной и северо-восточной. В терминах долготы и широты это:

  • minLng, minLat
  • maxLng, maxLat

Такая структура позволяет быстро ограничивать выборку объектов, оптимизировать отрисовку и выполнять пространственные запросы без сложных геометрических вычислений.


LngLatBounds как базовая сущность bbox

В Mapbox GL JS основным инструментом работы с bbox выступает класс LngLatBounds.

const bounds = new mapboxgl.LngLatBounds(
  [-74.1, 40.7], // юго-запад
  [-73.9, 40.8]  // северо-восток
);

Этот объект инкапсулирует прямоугольную область на сфере и предоставляет методы для:

  • расширения границ
  • проверки вхождения точки
  • получения координат в разных форматах
  • интеграции с viewport карты

Расширение bbox происходит динамически:

bounds.extend([-73.95, 40.75]);

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


bbox текущего viewport карты

Одним из ключевых сценариев является получение границ видимой области карты.

const bounds = map.getBounds();

Результат — экземпляр LngLatBounds, соответствующий текущему экрану.

Практическое применение:

  • загрузка только видимых объектов
  • кластеризация данных в пределах экрана
  • фильтрация API-запросов по области отображения

Пример получения координат:

const sw = bounds.getSouthWest();
const ne = bounds.getNorthEast();

console.log(sw.lng, sw.lat);
console.log(ne.lng, ne.lat);

Использование bbox для фильтрации данных

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 применяется для:

  • SQL-запросов с ограничением по координатам
  • индексации через R-tree
  • предварительной фильтрации GeoJSON

bbox и queryRenderedFeatures

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

Такой подход используется, когда необходимо:

  • уточнить результаты визуального запроса
  • исключить артефакты рендеринга
  • синхронизировать UI с видимой областью карты

Ограничение карты через fitBounds

Одно из наиболее практичных применений bbox — управление камерой карты.

map.fitBounds([
  [-74.1, 40.7],
  [-73.9, 40.8]
]);

Этот метод автоматически:

  • вычисляет оптимальный zoom
  • центрирует карту
  • учитывает padding и aspect ratio

Дополнительные параметры:

map.fitBounds(bounds, {
  padding: 40,
  maxZoom: 14,
  duration: 1000
});

Envelope как геометрическое обобщение bbox

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

Несмотря на схожесть, эти понятия различаются по происхождению и контексту применения:

bbox:

  • чаще задаётся вручную или возвращается API
  • представляет числовой диапазон координат
  • используется в фильтрации и запросах

envelope:

  • вычисляется из геометрии
  • возвращает GeoJSON-объект
  • применяется в пространственном анализе

Применение envelope для анализа данных

Envelope позволяет быстро получить грубую оценку географического охвата объекта:

const bboxFeature = envelope(geojsonFeature);
map.addSource('bbox', {
  type: 'geojson',
  data: bboxFeature
});

Типичные сценарии:

  • визуализация границ сложных объектов
  • предварительный анализ распределения данных
  • ускорение spatial joins
  • генерация heatmap ограниченных областей

bbox векторных тайлов

При работе с векторными тайлами bbox используется на нескольких уровнях:

  • серверный тайлсет ограничен квадратом
  • слой фильтруется по текущему viewport
  • рендеринг оптимизируется через clip bounds

Mapbox GL JS автоматически использует bounding box каждого тайла для:

  • отсечения невидимых объектов
  • ускорения рендеринга WebGL
  • минимизации загрузки данных

Пространственные операции на основе bbox

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-фильтрацию

Использование bbox позволяет существенно снижать вычислительную нагрузку:

  • сокращение количества проверяемых объектов
  • уменьшение объёма данных из API
  • ускорение отрисовки слоёв

Пример серверной фильтрации:

SEL ECT *
FR OM points
WH ERE lng BETWEEN minLng AND maxLng
  AND lat BETWEEN minLat AND maxLat;

Dynamic bbox при взаимодействии с картой

При перемещении карты bbox обновляется в реальном времени:

map.on('moveend', () => {
  const bounds = map.getBounds();
  updateData(bounds);
});

Это используется в системах:

  • динамической подгрузки маркеров
  • realtime-аналитики
  • адаптивной кластеризации

Envelope как основа генерации bbox из данных

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 и spatial indexing

В высоконагруженных приложениях bbox используется совместно с индексами:

  • R-tree
  • QuadTree
  • tile-based indexing

Алгоритм:

  1. определяется bbox viewport
  2. по индексу выбираются кандидаты
  3. выполняется точная геометрическая проверка
  4. результат рендерится

Такой подход обеспечивает масштабируемость при миллионах объектов.


Географические искажения bbox

BBox в координатах широта/долгота имеет ограничения:

  • искажения на высоких широтах
  • невозможность точного представления криволинейных границ
  • разрыв по линии анти-меридиана

Для обхода применяются:

  • разбиение bbox
  • нормализация координат
  • использование проекций Web Mercator

Envelope и агрегация пространственных данных

Envelope часто используется как шаг предварительной агрегации:

  • объединение точек в кластеры
  • вычисление зон покрытия
  • построение административных границ
const clusterBounds = envelope(clusterFeature);

Это позволяет быстро оценивать пространственные группы без полной геометрической обработки.


Итеративное расширение bbox в аналитике

При обработке потоковых данных bbox может формироваться постепенно:

let bounds = new mapboxgl.LngLatBounds();

stream.forEach(point => {
  bounds.extend(point.coordinates);
});

Такой подход используется в:

  • трекинге объектов
  • логистических системах
  • анализе перемещений

Практическая роль bbox в архитектуре картографических приложений

Bounding box становится базовой абстракцией, вокруг которой строится вся логика взаимодействия с картой:

  • ограничение выборки данных
  • управление камерой
  • пространственные фильтры
  • оптимизация рендеринга
  • предварительный анализ геометрий

Envelope, в свою очередь, дополняет эту модель, обеспечивая автоматическое вычисление границ сложных объектов и служа связующим звеном между геометрией и визуализацией.