Системы координат и проекции

Любая интерактивная карта оперирует координатами, позволяющими однозначно определить положение объекта на поверхности Земли. Однако отображение земной поверхности на плоскости неизбежно связано с преобразованиями, поскольку Земля имеет форму, близкую к эллипсоиду, а экран компьютера представляет собой двумерную поверхность.

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

  • географические координаты;
  • проекционные координаты;
  • пиксельные координаты;
  • координаты слоя;
  • экранные координаты.

Понимание различий между ними необходимо для корректного отображения объектов, вычисления расстояний и реализации сложной картографической логики.


Географические координаты

Основной системой координат в Leaflet являются географические координаты, представленные широтой и долготой.

Широта

Широта определяет положение точки относительно экватора:

  • северное полушарие — положительные значения;
  • южное полушарие — отрицательные значения.

Примеры:

Место Широта
Москва 55.7558
Астана 51.1694
Сидней -33.8688

Долгота

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

  • восточное направление — положительные значения;
  • западное направление — отрицательные значения.

Примеры:

Место Долгота
Москва 37.6176
Астана 71.4491
Нью-Йорк -74.0060

В Leaflet координаты обычно задаются в формате:

[latitude, longitude]

Например:

const moscow = [55.7558, 37.6176];

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

const point = L.latLng(55.7558, 37.6176);

Экземпляр LatLng является базовым объектом для представления географической точки.


Объект LatLng

Класс L.LatLng используется практически всеми компонентами Leaflet.

Создание:

const point = new L.LatLng(
    55.7558,
    37.6176
);

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

console.log(point.lat);
console.log(point.lng);

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

const p1 = L.latLng(55.7558, 37.6176);
const p2 = L.latLng(55.7558, 37.6176);

console.log(p1.equals(p2));

Результат:

true

Координатная система WGS84

По умолчанию Leaflet использует систему координат WGS84 (World Geodetic System 1984).

Это мировой стандарт геодезической привязки, применяемый:

  • GPS-приёмниками;
  • Google Maps;
  • OpenStreetMap;
  • Bing Maps;
  • большинством спутниковых систем.

Координаты вида:

55.7558, 37.6176

представляют собой значения именно в системе WGS84.

Практически все данные, поступающие из внешних API, также используют этот стандарт.


Почему необходимы картографические проекции

Поверхность Земли нельзя развернуть на плоскость без искажений.

При переносе координат возникают ошибки:

  • площадей;
  • расстояний;
  • направлений;
  • форм объектов.

Для решения этой задачи применяются картографические проекции.

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

Схематично процесс выглядит следующим образом:

Земля
   ↓
Проекция
   ↓
Плоская карта

Проекция Web Mercator

Основная проекция Leaflet называется Web Mercator.

Её международный код:

EPSG:3857

Эта проекция используется:

  • OpenStreetMap;
  • Google Maps;
  • Яндекс Карты;
  • Bing Maps;
  • Mapbox.

По сути именно она стала стандартом современной веб-картографии.


Особенности Web Mercator

В проекции Web Mercator:

  • меридианы изображаются вертикальными линиями;
  • параллели изображаются горизонтальными линиями;
  • углы сохраняются;
  • формы небольших объектов сохраняются достаточно хорошо.

Однако существуют существенные искажения площадей.

Например:

  • Гренландия выглядит почти как Африка;
  • на самом деле Африка больше примерно в 14 раз.

По мере приближения к полюсам искажения стремительно возрастают.

Из-за этого карта ограничивается диапазоном широт:

-85.05112878°
+85.05112878°

Полюса в Web Mercator не отображаются.


CRS — Coordinate Reference System

В Leaflet система координат описывается объектом CRS.

CRS расшифровывается как:

Coordinate Reference System

Каждый CRS определяет:

  • проекцию;
  • масштабирование;
  • преобразование координат;
  • правила отображения тайлов.

Leaflet содержит несколько встроенных CRS.


CRS.EPSG3857

Стандартный вариант:

const map = L.map("map", {
    crs: L.CRS.EPSG3857
});

Это значение используется по умолчанию.

Особенности:

  • поддержка большинства тайловых сервисов;
  • высокая производительность;
  • совместимость с OpenStreetMap.

CRS.EPSG4326

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

const map = L.map("map", {
    crs: L.CRS.EPSG4326
});

Код:

EPSG:4326

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

Особенности:

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

CRS.Simple

Leaflet способен работать не только с географическими картами.

Для схем зданий, игровых миров и чертежей применяется:

L.CRS.Simple

Пример:

const map = L.map("map", {
    crs: L.CRS.Simple
});

В этом случае координаты становятся обычными координатами плоскости.

Например:

[100, 200]

может означать:

  • пиксели изображения;
  • клетки игрового поля;
  • координаты помещения.

Никакой связи с географией здесь нет.


Проекция координат в Leaflet

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

project()

Пример:

const point = map.project(
    L.latLng(55.7558, 37.6176)
);

Результат:

Point(x, y)

Теперь точка представлена в координатах карты.

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

const latlng = map.unproject(point);

Пиксельные координаты

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

Получение пиксельной позиции:

const pixel = map.latLngToContainerPoint(
    [55.7558, 37.6176]
);

Результат:

Point(420, 280)

Это означает:

  • 420 пикселей от левого края контейнера;
  • 280 пикселей от верхнего края контейнера.

Контейнерные координаты

Контейнерные координаты измеряются относительно HTML-элемента карты.

Преобразование:

const point = map.latLngToContainerPoint(
    marker.getLatLng()
);

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

const latlng =
    map.containerPointToLatLng(point);

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

  • при кликах мышью;
  • при обработке касаний;
  • при создании пользовательских интерфейсов.

Координаты слоя

Leaflet разделяет понятия:

  • контейнер карты;
  • слой карты.

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

map.latLngToLayerPoint()

и

map.layerPointToLatLng()

Пример:

const point =
    map.latLngToLayerPoint(
        [55.7558, 37.6176]
    );

Координаты слоя изменяются при перемещении карты.

Контейнерные координаты при этом остаются привязанными к окну карты.


Экранные координаты событий

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

Пример:

map.on("click", function(e) {
    console.log(e.latlng);
    console.log(e.containerPoint);
    console.log(e.layerPoint);
});

Доступны:

Свойство Назначение
latlng Географические координаты
containerPoint Координаты контейнера
layerPoint Координаты слоя

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


Масштабирование и координаты

В Leaflet масштаб определяется уровнем зума.

Например:

map.setZoom(5);

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

Zoom 0
↓
Zoom 1 = ×2

Zoom 2 = ×4

Zoom 3 = ×8

Из-за этого координаты проекции также изменяются.

Получение масштаба:

const scale = map.getZoomScale(
    10,
    5
);

Тайловая система координат

Большинство карт состоит из тайлов.

Тайл представляет собой квадратное изображение.

Стандартный размер:

256 × 256 px

На уровне:

Zoom 0

существует один тайл.

На уровне:

Zoom 1

существует:

2 × 2 = 4 тайла

На уровне:

Zoom 2

существует:

4 × 4 = 16 тайлов

Общее количество вычисляется формулой:

2^zoom × 2^zoom

Именно поэтому при увеличении масштаба количество данных растёт очень быстро.


Границы карты и координатные прямоугольники

Для описания области карты используется объект LatLngBounds.

Создание:

const bounds = L.latLngBounds(
    [55.7, 37.5],
    [55.9, 37.8]
);

Получение углов:

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

Проверка попадания точки:

bounds.contains(
    [55.8, 37.6]
);

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


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

Leaflet позволяет ограничить перемещение карты определёнными координатами.

Пример:

const bounds = [
    [54.0, 36.0],
    [57.0, 39.0]
];

map.setMaxBounds(bounds);

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


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

Объект LatLng умеет вычислять расстояние по поверхности Земли.

Пример:

const moscow =
    L.latLng(55.7558, 37.6176);

const astana =
    L.latLng(51.1694, 71.4491);

const distance =
    moscow.distanceTo(astana);

console.log(distance);

Результат возвращается в метрах.

Внутри используется сферическая модель Земли, обеспечивающая достаточную точность для большинства веб-картографических задач.


Пользовательские проекции

Leaflet допускает использование собственных проекций.

Для этого обычно подключается библиотека:

Proj4Leaflet

Она позволяет работать с:

  • государственными системами координат;
  • кадастровыми картами;
  • специализированными геоинформационными системами;
  • локальными проекциями.

Пример создания CRS:

const crs = new L.Proj.CRS(
    "EPSG:1234",
    "+proj=tmerc ...",
    {
        resolutions: [...]
    }
);

После этого карта может отображать данные в нестандартной системе координат.


Типичный путь координаты внутри Leaflet

При отображении точки происходит несколько последовательных преобразований:

Широта и долгота
        ↓
LatLng
        ↓
Проекция CRS
        ↓
Координаты карты
        ↓
Пиксельные координаты
        ↓
Координаты слоя
        ↓
Координаты контейнера
        ↓
Экран

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