В основе любой картографической библиотеки лежит механизм преобразования географических координат в плоскую систему координат экрана. Leaflet использует абстракцию CRS (Coordinate Reference System), которая определяет, как широта и долгота преобразуются в пиксели, тайлы и внутренние координаты карты.
CRS в Leaflet определяет три ключевых аспекта: тип проекции, единицы измерения и правила масштабирования. Все вычисления положения объектов на карте происходят через выбранную систему координат.
Leaflet оперирует двумя основными пространствами:
Преобразование между ними осуществляется через CRS:
latlng → point (проекция на плоскость)point → latlng (обратное преобразование)Эти операции лежат в основе всех взаимодействий с картой: позиционирования маркеров, тайлов, оверлеев и событий.
По умолчанию Leaflet использует CRS, основанную на проекции Web Mercator:
map = L.map('map', {
crs: L.CRS.EPSG3857
});
Проекция преобразует широту следующим образом:
Это позволяет сохранить углы, но искажает площади на высоких широтах.
Альтернативная система координат — EPSG:4326:
map = L.map('map', {
crs: L.CRS.EPSG4326
});
Для изображений, схем и негеографических карт применяется простая CRS:
map = L.map('map', {
crs: L.CRS.Simple
});
const bounds = [[0, 0], [1000, 1000]];
const map = L.map('map', {
crs: L.CRS.Simple
});
L.imageOverlay('floor.png', bounds).addTo(map);
map.fitBounds(bounds);
CRS в Leaflet — это объект, реализующий набор методов:
latLngToPoint(latlng, zoom)pointToLatLng(point, zoom)project(latlng)unproject(point)scale(zoom)zoom(scale)Эти методы определяют всю геометрическую логику карты.
const point = map.options.crs.project(L.latLng(55.75, 37.61));
Проекция переводит географические координаты в координаты внутренней системы CRS.
const latlng = map.options.crs.unproject(L.point(1000000, 500000));
Используется при обработке кликов, перетаскивания и вычислении положения объектов.
CRS определяет, как изменяется масштаб карты при увеличении zoom level.
В Web Mercator используется правило:
[ = 2^{zoom}]
Это означает:
В Leaflet это отражается через метод:
L.CRS.EPSG3857.scale = function (zoom) {
return 256 * Math.pow(2, zoom);
};
Тайлы напрямую зависят от CRS, так как определяют:
В EPSG:3857 используется схема:
/z/x/y.png
Где:
CRS определяет, как географическая точка попадает в этот индекс.
Каждый CRS задаёт точку начала координат (origin).
Для EPSG:3857:
Для L.CRS.Simple:
Leaflet позволяет создавать собственные системы координат:
const customCRS = L.extend({}, L.CRS.EPSG3857, {
transformation: new L.Transformation(0.5, 0, -0.5, 0)
});
const map = L.map('map', {
crs: customCRS
});
Объект L.Transformation задаёт линейное
преобразование:
x' = a * x + b
y' = c * y + d
Используется для:
Система координат тесно связана с границами карты:
map.setMaxBounds([
[-85, -180],
[85, 180]
]);
CRS определяет, как эти границы интерпретируются:
Leaflet внутри оперирует не географией, а пикселями.
Каждая точка карты имеет:
Маркер, линия или полигон проходят цепочку преобразований:
latlng → projected point → world pixel → tile grid → screen pixel
При смене CRS все слои пересчитываются:
project/unprojectНекорректная смена CRS без соответствующих тайлов приводит к смещению или отсутствию отображения слоёв.
Leaflet использует CRS для:
В EPSG:3857 расстояния не соответствуют реальным на высоких широтах, что влияет на измерения.
Выбор CRS влияет на:
EPSG:3857 оптимизирован для производительности благодаря степенному росту сетки и предсказуемой структуре тайлов.
При использовании кастомных CRS важно учитывать:
Несовпадение этих параметров приводит к разрыву геометрии карты и визуальным артефактам.