LngLat и LngLatBounds

LngLat — базовый класс в MapLibre GL JS, предназначенный для строгого представления географических координат в формате долготы и широты. Он инкапсулирует работу с координатными парами и обеспечивает предсказуемую нормализацию значений, что критически важно при работе с веб-картами, проекциями и вычислениями расстояний на сфере.

Класс LngLat используется для хранения координат в формате:

  • longitude (lng) — долгота, ось X
  • latitude (lat) — широта, ось Y

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

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

import { LngLat } from 'maplibre-gl';

const coord = new LngLat(30.5, 50.45);

Альтернативная форма:

const coord = new LngLat({ lng: 30.5, lat: 50.45 });

Нормализация координат

LngLat автоматически нормализует входные значения:

  • долгота приводится к диапазону [-180, 180]
  • широта ограничивается диапазоном [-90, 90]

Пример поведения:

new LngLat(190, 95);

Результат:

  • lng → -170
  • lat → 90 (обрезается до максимального значения)

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

Основные методы LngLat

toArray()

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

const coord = new LngLat(30, 50);
coord.toArray(); // [30, 50]

Используется при взаимодействии с GeoJSON и низкоуровневыми API.


toString()

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

coord.toString(); // "LngLat(30, 50)"

Полезно для логирования и отладки.


wrap()

Метод возвращает новый объект LngLat, где долгота приведена к диапазону [-180, 180], без изменения широты:

const coord = new LngLat(540, 40);
const wrapped = coord.wrap();

Результат:

  • lng = 180 (или -180 в зависимости от нормализации)
  • lat = 40

Этот метод особенно важен при работе с повторяющимися мирами (wrapped world copies), когда карта отображает несколько копий земной поверхности.

Сравнение экземпляров

Для проверки равенства координат используется метод:

coord1.equals(coord2);

Он учитывает точность значений и возвращает true, если координаты совпадают.


LngLatBounds: работа с географическими границами

Класс LngLatBounds представляет прямоугольную область на карте, заданную двумя координатами:

  • юго-западный угол (SW)
  • северо-восточный угол (NE)
import { LngLatBounds } from 'maplibre-gl';

const bounds = new LngLatBounds(
  new LngLat(10, 40),
  new LngLat(20, 50)
);

Также допускается массивный формат:

const bounds = new LngLatBounds([10, 40], [20, 50]);

Концепция границ

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

  • определения видимой области карты
  • вычисления области покрытия данных
  • ограничения перемещения камеры
  • автоматического масштабирования

Геометрически объект представляет прямоугольник в координатах долготы и широты, но с учётом особенностей глобальной сферы.


Методы LngLatBounds

extend()

Расширяет границы, включая новую точку или другой bounding box:

bounds.extend(new LngLat(25, 55));

или:

bounds.extend([25, 55]);

При расширении происходит пересчёт min/max значений по осям.


getCenter()

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

const center = bounds.getCenter();

Центр вычисляется как среднее значение между минимальными и максимальными координатами.


getNorthEast() и getSouthWest()

Позволяют получить углы:

bounds.getNorthEast();
bounds.getSouthWest();

Эти методы возвращают новые объекты LngLat.


toArray()

Представляет границы в виде массива:

bounds.toArray();

Результат:

[
  [swLng, swLat],
  [neLng, neLat]
]

toString()

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

bounds.toString();

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


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

contains()

Определяет, находится ли точка внутри границ:

bounds.contains(new LngLat(15, 45));

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


Пересечение границ

Хотя прямого метода intersects() может не быть в базовом API, пересечение можно определить через сравнение диапазонов:

function intersects(a, b) {
  return !(
    a.getNorthEast().lng < b.getSouthWest().lng ||
    a.getSouthWest().lng > b.getNorthEast().lng ||
    a.getNorthEast().lat < b.getSouthWest().lat ||
    a.getSouthWest().lat > b.getNorthEast().lat
  );
}

Ограничение камеры через LngLatBounds

Одно из основных применений — ограничение перемещения карты:

map.setMaxBounds(
  new LngLatBounds(
    [-10, 35],
    [40, 60]
  )
);

Это предотвращает уход пользователя за пределы заданной области.


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

При пересечении линии ±180° долготы возникает сложность интерпретации границ. LngLatBounds учитывает это, но разработчик должен быть осторожен:

  • прямоугольник может быть “разорван”
  • логика extend() может давать неожиданные результаты при глобальных диапазонах
  • требуется нормализация через wrap() для точек

Взаимодействие LngLat и LngLatBounds

LngLat является базовой единицей, тогда как LngLatBounds агрегирует их:

  • точки добавляются в bounds через extend
  • центр bounds возвращает LngLat
  • проверка contains принимает LngLat

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

const coords = [
  new LngLat(10, 10),
  new LngLat(20, 20),
  new LngLat(15, 25)
];

const bounds = new LngLatBounds(coords[0], coords[0]);

coords.forEach(c => bounds.extend(c));

Использование в камере карты

Оба класса активно используются в управлении камерой:

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

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


Особенности точности и вычислений

Работа с координатами в MapLibre GL JS основана на числах с плавающей точкой, что накладывает ограничения:

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

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

Частые проблемы при работе с LngLat и LngLatBounds:

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

Роль в архитектуре геоданных MapLibre

LngLat и LngLatBounds выступают фундаментальными примитивами геометрии:

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