Класс LatLngBounds

Назначение и концепция

LatLngBounds представляет прямоугольную географическую область, заданную двумя точками: юго-западной и северо-восточной. Этот объект используется для описания рамок карты, ограничений отображения, фильтрации объектов и вычисления видимой области.

Геометрически границы интерпретируются как осевая ограничивающая рамка (axis-aligned bounding box) в системе широты и долготы.

Основная идея:

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

Создание объекта LatLngBounds

Конструктор

L.latLngBounds(southWest, northEast)

Параметры:

  • southWest — юго-западная точка
  • northEast — северо-восточная точка

Пример:

const sw = L.latLng(55.70, 37.50);
const ne = L.latLng(55.80, 37.70);

const bounds = L.latLngBounds(sw, ne);

При некорректном порядке координат Leaflet автоматически нормализует границы, корректируя минимальные и максимальные значения.


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

const bounds = L.latLngBounds([
  [55.70, 37.50],
  [55.75, 37.60],
  [55.80, 37.70]
]);

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


Базовые свойства и проверки

isValid

bounds.isValid()

Проверяет, содержит ли объект корректные координаты.

Возвращает:

  • true — если границы определены
  • false — если объект пустой

Пример:

const empty = L.latLngBounds();
empty.isValid(); // false

isEmpty (через отсутствие точек)

В Leaflet нет отдельного публичного isEmpty, но поведение эквивалентно isValid() при отсутствии данных.


Геометрические операции

contains

bounds.contains(latlng)

Проверяет, находится ли точка внутри границ.

const bounds = L.latLngBounds(
  L.latLng(55.70, 37.50),
  L.latLng(55.80, 37.70)
);

bounds.contains([55.75, 37.60]); // true
bounds.contains([55.90, 37.60]); // false

Логика:

  • широта должна быть в диапазоне [south, north]
  • долгота должна быть в диапазоне [west, east]

intersects

bounds1.intersects(bounds2)

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

const a = L.latLngBounds([55.70, 37.50], [55.80, 37.70]);
const b = L.latLngBounds([55.75, 37.60], [55.85, 37.80]);

a.intersects(b); // true

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

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

extend

bounds.extend(latlng)
bounds.extend(otherBounds)

Расширяет границы так, чтобы включить новую точку или другую область.

const bounds = L.latLngBounds([55.70, 37.50], [55.75, 37.60]);

bounds.extend([55.80, 37.80]);

После вызова:

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

При расширении другим bounds:

bounds.extend(otherBounds);

Центр и углы

getCenter

bounds.getCenter()

Возвращает центр прямоугольника.

Формула:

  • latitude = (south + north) / 2
  • longitude = (west + east) / 2
const center = bounds.getCenter();

getSouthWest / getNorthEast

bounds.getSouthWest()
bounds.getNorthEast()

Возвращают соответствующие угловые точки.

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

getNorthWest / getSouthEast

bounds.getNorthWest()
bounds.getSouthEast()

Дополнительные углы прямоугольника.


Преобразование и представление

toBBoxString

bounds.toBBoxString()

Возвращает строку формата:

west,south,east,north

Пример:

"37.50,55.70,37.70,55.80"

Используется в:

  • запросах к WMS/WMTS серверам
  • API геосервисов
  • фильтрации данных на сервере

Изменение и расширение области

pad

bounds.pad(factor)

Увеличивает границы на процент от текущего размера.

const padded = bounds.pad(0.2);

Где:

  • 0.2 означает увеличение на 20%

Механика:

  • центр остаётся прежним
  • границы расширяются равномерно

Сравнение объектов

equals

bounds.equals(otherBounds)

Проверяет полное совпадение границ.

bounds.equals(L.latLngBounds([55, 37], [56, 38]));

Сравнение включает:

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

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

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

const bounds = L.latLngBounds(
  L.latLng(55.60, 37.30),
  L.latLng(55.90, 37.90)
);

map.setMaxBounds(bounds);

Результат:

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

Автоцентрирование по объектам

const group = L.featureGroup([marker1, marker2, marker3]);
map.fitBounds(group.getBounds());

Механизм:

  • вычисляется общий LatLngBounds
  • карта масштабируется и центрируется

Фильтрация объектов в пределах области

const visible = points.filter(p =>
  bounds.contains([p.lat, p.lng])
);

Особенности поведения

Антимеридиан и долгота

При работе с долготой:

  • диапазон обычно [-180, 180]
  • пересечение 180° требует осторожности

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


Пустые границы

Новый объект без параметров:

const b = L.latLngBounds();

Поведение:

  • isValid() === false
  • методы getCenter() могут возвращать некорректные значения до добавления точек

Взаимодействие с другими сущностями Leaflet

Marker

Каждый маркер имеет координаты, которые могут расширять bounds:

bounds.extend(marker.getLatLng());

Polygon / Polyline

const bounds = polygon.getBounds();

или

const bounds = polyline.getBounds();

Map

map.getBounds()

Возвращает текущую видимую область карты как LatLngBounds.


Типичные сценарии использования

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