Система координат (CRS — Coordinate Reference System) определяет способ интерпретации географических данных на плоскости карты. В Leaflet базовая архитектура построена вокруг предположения, что все тайлы, координаты и преобразования подчиняются выбранной проекции. По умолчанию используется Web Mercator, однако архитектура библиотеки позволяет полностью заменить систему координат, включая математическую модель преобразования широты/долготы в пиксельные координаты.
В Leaflet каждая карта опирается на объект L.CRS,
который описывает:
Основные встроенные CRS:
Каждый CRS реализует единый интерфейс, что позволяет подменять его без изменения логики карты.
Web Mercator (EPSG:3857) используется в большинстве веб-картографических систем. Его особенности:
Leaflet использует эту проекцию как стандартную, так как она совместима с большинством тайловых серверов (OpenStreetMap, Mapbox и др.).
Переопределение CRS требуется в случаях:
В таких сценариях Web Mercator становится ограничением, так как предполагает географическую модель Земли.
Наиболее простой вариант пользовательской системы координат —
L.CRS.Simple.
Она трактует карту как двумерную плоскость:
Пример использования:
const map = L.map('map', {
crs: L.CRS.Simple,
minZoom: -2
});
const bounds = [[0, 0], [1000, 1000]];
L.imageOverlay('floorplan.png', bounds).addTo(map);
map.fitBounds(bounds);
Особенность: Leaflet воспринимает координаты как линейное пространство, где «широта» и «долгота» — это просто X и Y.
Полноценный пользовательский CRS реализуется через объект с набором обязательных методов:
latLngToPoint(latlng, zoom)pointToLatLng(point, zoom)project(latlng)unproject(point)scale(zoom)zoom(scale)wrapLatLng(latlng)Эти методы образуют математический слой преобразования координат.
Минимальный шаблон:
const CustomCRS = L.extend({}, L.CRS, {
project(latlng) {
return new L.Point(latlng.lng * 200, latlng.lat * 200);
},
unproject(point) {
return new L.LatLng(point.y / 200, point.x / 200);
},
scale(zoom) {
return Math.pow(2, zoom);
}
});
Функция scale(zoom) определяет, как меняется размер
карты при увеличении масштаба.
Стандартная модель:
scale(zoom) {
return 256 * Math.pow(2, zoom);
}
Нестандартные CRS могут использовать:
Для карты здания часто используют условные метры:
const BuildingCRS = L.extend({}, L.CRS.Simple, {
transformation: new L.Transformation(1 / 2, 0, -1 / 2, 0)
});
Инициализация:
const map = L.map('map', {
crs: BuildingCRS,
minZoom: 0,
maxZoom: 4
});
Здесь L.Transformation задаёт линейное
преобразование:
Ключевой элемент пользовательских CRS — линейные преобразования:
new L.Transformation(a, b, c, d)
Формула:
Это позволяет:
Пример инверсии Y:
const t = new L.Transformation(1, 0, -1, 0);
Для работы с реальными географическими CRS часто используется библиотека proj4js и расширение Proj4Leaflet.
Она позволяет подключать EPSG-коды:
Пример:
const crs = new L.Proj.CRS(
'EPSG:32636',
'+proj=utm +zone=36 +datum=WGS84 +units=m +no_defs',
{
resolutions: [
8192, 4096, 2048, 1024, 512,
256, 128, 64, 32, 16, 8, 4, 2, 1
]
}
);
const map = L.map('map', { crs });
TileLayer в Leaflet зависит от CRS:
При пользовательском CRS необходимо учитывать:
Каждый CRS имеет точку отсчёта:
Пример изменения origin:
const crs = L.extend({}, L.CRS.Simple, {
transformation: new L.Transformation(1, 500, -1, 500)
});
Это смещает систему координат в центр условного пространства.
Leaflet требует симметрии:
Пример:
pointToLatLng(point, zoom) {
const scale = this.scale(zoom);
return L.latLng(point.y / scale, point.x / scale);
}
Нарушение симметрии приводит к:
При создании CRS необходимо учитывать:
Сложные нелинейные проекции могут снижать производительность из-за частых вычислений при pan/zoom.
Игровые миры часто используют собственные CRS:
Пример:
const GameCRS = L.extend({}, L.CRS.Simple, {
transformation: new L.Transformation(1, 0, -1, 0),
scale: function (zoom) {
return Math.pow(2, zoom);
}
});
Используется для:
При смене CRS важно учитывать:
GeoJSON данные интерпретируются через CRS:
L.geoJSON(data, {
coordsToLatLng: function (coords) {
return L.latLng(coords[1], coords[0]);
}
}).addTo(map);
Это позволяет адаптировать:
Ключевые факторы:
project/unproject;Оптимизации: