Любая интерактивная карта оперирует координатами, позволяющими однозначно определить положение объекта на поверхности Земли. Однако отображение земной поверхности на плоскости неизбежно связано с преобразованиями, поскольку Земля имеет форму, близкую к эллипсоиду, а экран компьютера представляет собой двумерную поверхность.
В библиотеке 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 является базовым объектом для
представления географической точки.
Класс 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
По умолчанию Leaflet использует систему координат WGS84 (World Geodetic System 1984).
Это мировой стандарт геодезической привязки, применяемый:
Координаты вида:
55.7558, 37.6176
представляют собой значения именно в системе WGS84.
Практически все данные, поступающие из внешних API, также используют этот стандарт.
Поверхность Земли нельзя развернуть на плоскость без искажений.
При переносе координат возникают ошибки:
Для решения этой задачи применяются картографические проекции.
Проекция представляет собой математическое преобразование координат земной поверхности в плоские координаты карты.
Схематично процесс выглядит следующим образом:
Земля
↓
Проекция
↓
Плоская карта
Основная проекция Leaflet называется Web Mercator.
Её международный код:
EPSG:3857
Эта проекция используется:
По сути именно она стала стандартом современной веб-картографии.
В проекции Web Mercator:
Однако существуют существенные искажения площадей.
Например:
По мере приближения к полюсам искажения стремительно возрастают.
Из-за этого карта ограничивается диапазоном широт:
-85.05112878°
+85.05112878°
Полюса в Web Mercator не отображаются.
В Leaflet система координат описывается объектом CRS.
CRS расшифровывается как:
Coordinate Reference System
Каждый CRS определяет:
Leaflet содержит несколько встроенных CRS.
Стандартный вариант:
const map = L.map("map", {
crs: L.CRS.EPSG3857
});
Это значение используется по умолчанию.
Особенности:
Другая популярная система:
const map = L.map("map", {
crs: L.CRS.EPSG4326
});
Код:
EPSG:4326
Здесь используются непосредственно значения широты и долготы.
Особенности:
Leaflet способен работать не только с географическими картами.
Для схем зданий, игровых миров и чертежей применяется:
L.CRS.Simple
Пример:
const map = L.map("map", {
crs: L.CRS.Simple
});
В этом случае координаты становятся обычными координатами плоскости.
Например:
[100, 200]
может означать:
Никакой связи с географией здесь нет.
Для преобразования географических координат в координаты проекции используется метод:
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)
Это означает:
Контейнерные координаты измеряются относительно 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: [...]
}
);
После этого карта может отображать данные в нестандартной системе координат.
При отображении точки происходит несколько последовательных преобразований:
Широта и долгота
↓
LatLng
↓
Проекция CRS
↓
Координаты карты
↓
Пиксельные координаты
↓
Координаты слоя
↓
Координаты контейнера
↓
Экран
Каждый этап необходим для корректного отображения географических данных на двумерной интерактивной карте и обеспечивает гибкость, благодаря которой Leaflet способен работать как с глобальными картами мира, так и с локальными схемами, планами помещений и специализированными геоинформационными системами.