Математические вспомогательные функции

В основе всех пространственных операций в Leaflet лежит преобразование между географическими координатами и экранной системой координат. Географическая модель использует пары широта/долгота (LatLng), тогда как рендеринг карты опирается на пиксельные координаты в проекции мира.

Ключевая идея заключается в разделении двух пространств:

  • Географическое пространство — сферическая модель Земли (WGS84)
  • Пиксельное пространство — декартова система координат тайлов и слоя карты

Все математические функции Leaflet обеспечивают согласованное преобразование между этими системами.


Координаты LatLng и базовые операции

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

L.latLng(51.505, -0.09)

Он поддерживает нормализацию значений и базовые преобразования.

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

Leaflet автоматически приводит значения к допустимым диапазонам:

  • широта: от -90 до 90
  • долгота: от -180 до 180 (с возможным “зацикливанием”)

Математическая нормализация долготы:

function wrapLng(lng) {
  return ((lng + 180) % 360 + 360) % 360 - 180;
}

Это обеспечивает непрерывность карты при переходе через меридиан ±180°.


Расчёт расстояний между точками

Leaflet предоставляет геодезическое расстояние между координатами на сфере.

Используется приближённая модель Земли (сфера), а не эллипсоид.

Формула Haversine

L.latLng(lat1, lng1).distanceTo(L.latLng(lat2, lng2))

Внутренне применяется классическая тригонометрия:

[ a = ^2() + _1 _2 ^2()]

[ c = 2 (, )]

[ d = R c]

где (R) — радиус Земли (6378137 м в WGS84).

Особенности реализации

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

Проекции: перевод между LatLng и пикселями

Leaflet использует систему проекций, где основной является Spherical Mercator (EPSG:3857).

Преобразование LatLng → Point

map.project(L.latLng(51.5, -0.09), zoom)

Математически:

[ x = R ]

[ y = R (( + ))]

где:

  • () — долгота в радианах
  • () — широта в радианах

Обратное преобразование

map.unproject(point, zoom)

Масштабирование мира и тайловая система

В Leaflet масштаб зависит от уровня зума:

[ scale = 2^{zoom}]

Каждый следующий уровень увеличивает детализацию в два раза.

Размер мира в пикселях

worldSize = tileSize * Math.pow(2, zoom)

При стандартном размере тайла 256:

  • zoom 0 → 256 px
  • zoom 1 → 512 px
  • zoom 2 → 1024 px

Линейная интерполяция (lerp)

При анимации перемещения карты и плавных переходах используется интерполяция:

function lerp(a, b, t) {
  return a + (b - a) * t;
}

Применение:

  • плавный pan
  • zoom animation
  • easing переходы между состояниями

Для координат:

lat = lat1 + (lat2 - lat1) * t;
lng = lng1 + (lng2 - lng1) * t;

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

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

  • LatLng → world coordinates
  • world coordinates → layer pixels
map.latLngToLayerPoint(latlng)
map.layerPointToLatLng(point)

Логика вычислений

  1. LatLng переводится в мировую проекцию
  2. Применяется масштаб zoom
  3. Вычитается смещение (offset карты)
  4. Получается конечная пиксельная позиция

Границы (LatLngBounds) и операции с ними

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

Основные операции

bounds.extend(latlng)
bounds.contains(latlng)
bounds.intersects(otherBounds)

Расширение границ

function extendBounds(bounds, latlng) {
  bounds.minLat = Math.min(bounds.minLat, latlng.lat);
  bounds.maxLat = Math.max(bounds.maxLat, latlng.lat);
  bounds.minLng = Math.min(bounds.minLng, latlng.lng);
  bounds.maxLng = Math.max(bounds.maxLng, latlng.lng);
}

Работа с долготой и цикличностью карты

Проблема мировых карт — непрерывность по оси X.

Leaflet решает это через wrapping:

lng = ((lng + 180) % 360 + 360) % 360 - 180;

Использование в рендеринге

  • тайлы дублируются по горизонтали
  • объекты могут отображаться в нескольких копиях
  • bounds проверяются с учётом wrap

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

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

function normalizePoint(point, worldSize) {
  return {
    x: ((point.x % worldSize) + worldSize) % worldSize,
    y: point.y
  };
}

Это предотвращает “разрыв” карты при перемещении.


CRS (Coordinate Reference System) и математическая абстракция

Leaflet использует систему CRS как слой математических преобразований.

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

  • latLngToPoint
  • pointToLatLng
  • project
  • unproject
  • scale

Пример CRS.EPSG3857

L.CRS.EPSG3857.project(latlng)

Фактически CRS инкапсулирует:

  • сферическую проекцию
  • масштабирование
  • преобразование единиц

Операции с числами и внутренние утилиты

Leaflet содержит набор низкоуровневых математических утилит.

Ограничение значений

function clamp(x, min, max) {
  return Math.max(min, Math.min(max, x));
}

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

  • ограничения zoom
  • нормализации координат
  • предотвращения переполнений

Преобразование в радианы

function toRad(deg) {
  return deg * Math.PI / 180;
}

Преобразование в градусы

function toDeg(rad) {
  return rad * 180 / Math.PI;
}

Пиксельная математика перемещения карты

При каждом движении карты происходит перерасчёт:

  • центра
  • смещения слоя
  • позиций маркеров

Формула смещения:

offset = containerCenter.subtract(mapCenterInPixels);

Масштабирование объектов относительно зума

Размер объектов часто зависит от zoom:

size = baseSize * Math.pow(2, zoom - baseZoom);

Это позволяет:

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

Геометрия пересечений и проверок

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

function contains(bounds, latlng) {
  return (
    latlng.lat >= bounds._southWest.lat &&
    latlng.lat <= bounds._northEast.lat &&
    latlng.lng >= bounds._southWest.lng &&
    latlng.lng <= bounds._northEast.lng
  );
}

Производительность математических операций

Leaflet оптимизирует вычисления за счёт:

  • кэширования проекций
  • минимизации тригонометрии
  • повторного использования объектов Point
  • предвычисления scale по zoom

Особенно дорогостоящие операции:

  • sin/cos в больших объёмах
  • логарифмы в Mercator projection
  • distanceTo при множественных маркерах

Итеративные преобразования при анимации

Во время pan/zoom применяется цикл пересчёта:

  1. вычисление нового центра
  2. пересчёт world coordinates
  3. преобразование в pixel coordinates
  4. обновление DOM-позиций слоёв

Внутренняя числовая стабильность

Leaflet избегает накопления ошибок:

  • округление пикселей на рендере
  • фиксация floating-point drift
  • использование целых значений там, где возможно

Обобщённая модель математического слоя

Математическая подсистема Leaflet строится вокруг трёх уровней:

  1. LatLng слой — геодезия и сферическая модель
  2. Projection слой — Mercator преобразования
  3. Pixel слой — экранная геометрия и UI

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