LngLatBounds класс

В MapLibre GL JS объект, описывающий прямоугольную географическую область, используется как фундаментальная абстракция для работы с картой: вычисление видимой области, фильтрация объектов по экрану, подгонка камеры, построение тайловых запросов и геопространственных операций. Ключевой структурой для этих задач выступает LngLatBounds, представляющий границы в координатах долготы и широты.

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

  • South-West (SW): минимальные значения долготы и широты
  • North-East (NE): максимальные значения долготы и широты

Такая модель позволяет однозначно задать область на глобусе с учётом особенностей координатной системы WGS84.


Конструктор LngLatBounds

Создание экземпляра выполняется через конструктор, принимающий две точки:

const bounds = new maplibregl.LngLatBounds(
  [longitudeWest, latitudeSouth],
  [longitudeEast, latitudeNorth]
);

Если параметры не переданы, создаётся «пустой» объект границ, который впоследствии можно расширять.

Особенности поведения пустого объекта

Пустой LngLatBounds не содержит валидной геометрии до тех пор, пока в него не будут добавлены координаты через extend. Это важно учитывать при вычислениях центра или попытках извлечь углы.


Статические методы создания

fromLngLat

Создаёт границы из одной точки. Фактически инициализирует bounds с одинаковыми SW и NE координатами:

const b = maplibregl.LngLatBounds.fromLngLat([30, 50]);

Используется как стартовая точка для последующего расширения.


fromLngLatLike

Принимает объект или массив, совместимый с LngLatLike:

const b = maplibregl.LngLatBounds.fromLngLatLike({ lng: 30, lat: 50 });

Этот метод удобен при работе с данными из GeoJSON или API.


Расширение границ: метод extend

Базовый механизм

extend — центральный метод, позволяющий динамически увеличивать bounding box:

bounds.extend([lng, lat]);

Каждое новое значение сравнивается с текущими границами:

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

Построение границ по набору точек

const bounds = new maplibregl.LngLatBounds();

coordinates.forEach(coord => bounds.extend(coord));

Такой подход применяется при вычислении охвата GeoJSON-геометрий.


Получение угловых точек

LngLatBounds предоставляет методы для извлечения ключевых углов прямоугольника.

getSouthWest

Возвращает юго-западную точку:

const sw = bounds.getSouthWest();

getNorthEast

Возвращает северо-восточную точку:

const ne = bounds.getNorthEast();

Дополнительные углы

Для полноты геометрии доступны также:

  • getNorthWest()
  • getSouthEast()

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


Центр области: getCenter

Метод вычисляет географический центр bounding box:

const center = bounds.getCenter();

Алгоритм основан на усреднении координат:

  • долгота центра = (west + east) / 2
  • широта центра = (south + north) / 2

Особенности при пересечении антимеридиана

Если границы пересекают ±180° долготы, простое усреднение может давать некорректный результат. В таких случаях библиотека учитывает wrap-around логику, если она активирована или поддерживается контекстом карты.


Проверка пустоты и валидности

isEmpty

Позволяет определить, содержит ли объект реальные координаты:

if (bounds.isEmpty()) {
  // границы ещё не заданы
}

Пустое состояние возникает:

  • после создания без параметров
  • после сброса логики (если применимо)
  • до первого вызова extend

Преобразование в массив

toArray

Возвращает границы в виде массива:

const arr = bounds.toArray();

Формат:

[
  [west, south],
  [east, north]
]

Это удобно для сериализации и передачи данных между системами.


Строковое представление

toString

Возвращает человекочитаемое описание:

console.log(bounds.toString());

Используется в основном для отладки. Формат не предназначен для парсинга.


Проверка пересечений и включений

Хотя основная функциональность LngLatBounds — описание области, он также поддерживает пространственные проверки.

contains (логическая модель)

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

  • долгота должна находиться между west и east
  • широта должна находиться между south и north

Это используется для:

  • фильтрации объектов
  • проверки видимости маркеров
  • оптимизации рендеринга

Взаимодействие с камерой карты

LngLatBounds активно используется в связке с камерой (Map), особенно через метод fitBounds.

map.fitBounds(bounds, {
  padding: 20
});

Логика работы fitBounds

  1. вычисляется центр bounds
  2. подбирается zoom-уровень
  3. учитываются padding и maxBounds
  4. камера плавно перемещается к нужному состоянию

Работа с массивами координат

LngLatBounds часто строится из GeoJSON-данных:

const bounds = new maplibregl.LngLatBounds();

geojson.features.forEach(feature => {
  feature.geometry.coordinates.forEach(coord => {
    bounds.extend(coord);
  });
});

Вложенные структуры

Для сложных геометрий (Polygon, MultiPolygon) требуется рекурсивный обход координат.


Особенности работы с долготой ±180°

Одна из ключевых сложностей географических bounds — пересечение антимеридиана.

Пример:

  • западная граница: 170°
  • восточная граница: -170°

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


Типичные ошибки при использовании

Неправильный порядок координат

Частая проблема:

// ошибка
[newLngLatBounds([lat, lng], [lat, lng])]

// правильно
[newLngLatBounds([lng, lat], [lng, lat])]

Использование неинициализированных bounds

Вызов getCenter() на пустом объекте может привести к некорректным результатам. Перед этим всегда требуется extend.


Игнорирование вложенности координат

GeoJSON может содержать глубоко вложенные массивы координат, и простая итерация не всегда достаточна.


Практические сценарии применения

1. Подгонка карты под объекты

const bounds = new maplibregl.LngLatBounds();

points.forEach(p => bounds.extend(p));

map.fitBounds(bounds);

2. Кластеризация данных по области видимости

Использование bounds позволяет ограничить выборку данных только текущей областью экрана.


3. Проверка попадания объектов в viewport

if (bounds.contains(marker.getLngLat())) {
  // объект видим
}

4. Генерация геозон

LngLatBounds часто используется как базовый строительный блок для административных и пользовательских зон.


Взаимодействие с другими гео-структурами

LngLatBounds тесно связан с:

  • LngLat — точечная координата
  • Map — визуализация и камера
  • GeoJSON geometry — источники данных
  • MercatorCoordinate — проекционные расчёты

Он выступает промежуточным слоем между сырой геометрией и визуальной системой карты.


Производительность и оптимизация

Работа с bounds крайне дешёвая вычислительно, так как:

  • операции линейные O(n)
  • не требуют тригонометрии
  • используют простые сравнения чисел

Однако узким местом может стать количество вызовов extend при обработке больших датасетов. В таких случаях рекомендуется:

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

Поведение в больших системах

В архитектуре геосервисов LngLatBounds часто выступает как:

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

Его простота делает его универсальным элементом между клиентской и серверной логикой геоданных.