Skip to content

Переход с Leaflet ​

Leaflet бесплатен, но карта без тайлов пустая. tile.openstreetmap.org нельзя использовать в продакшене, зарубежные сервисы тайлов из РФ почти не оплатить, а Яндекс не продаёт подложку отдельно. EvaMaps — библиотека и тайлы по РФ и СНГ одной поставкой: подключили скрипт, и карта работает. До 5 000 загрузок карты в месяц бесплатно, без ключа и регистрации.

Имена методов взяты у Leaflet (setView, flyTo, fitBounds, addTo, on/off), поэтому перенос простой карты занимает минуты. Главное отличие — порядок координат.

Тайлы EvaMaps не подключаются в Leaflet

Тайлы работают только через SDK @evamaps/sdk, <eva-map> и iframe. Оставить Leaflet и поменять только адрес тайлов не получится — переносится код карты целиком.

Было и стало ​

html
<!-- Leaflet -->
<link rel="stylesheet" href="leaflet.css">
<script src="leaflet.js"></script>
<script>
  const map = L.map('map').setView([55.7558, 37.6173], 13);
  L.tileLayer('https://…/{z}/{x}/{y}.png', { attribution: '…' }).addTo(map);
  L.marker([55.7558, 37.6173]).addTo(map).bindPopup('Наш офис');
</script>
html
<!-- EvaMaps -->
<link rel="stylesheet" href="https://evamaps.ru/sdk/1/evamaps.css">
<script src="https://evamaps.ru/sdk/1/evamaps.js"></script>
<script>
  const map = EvaMaps.create('map', { center: [37.6173, 55.7558], zoom: 13 });
  EvaMaps.marker([37.6173, 55.7558])
    .setPopup(EvaMaps.popup().setText('Наш офис'))
    .addTo(map);
</script>

Подложка, атрибуция, кнопки зума и линейка уже внутри create().

Координаты: [lng, lat] ​

У Leaflet [lat, lng] — широта первой. У EvaMaps, как в GeoJSON, [lng, lat] — долгота первой. Москва: Leaflet [55.7558, 37.6173], EvaMaps [37.6173, 55.7558].

Это самая частая ошибка при переходе: точка улетает в Индийский океан или в Сомали. Если координаты приходят из своей базы в порядке [lat, lng], разверните их один раз на входе: ([lat, lng]) => [lng, lat].

Зато GeoJSON читается без разворота — его порядок совпадает с нашим. Шкала зума та же, что у Leaflet и OSM: зум 13 там и здесь показывает одно и то же.

Таблица соответствия ​

LeafletEvaMaps (скрипт evamaps.js)Заметки
L.map(id).setView(latlng, z)EvaMaps.create(id, { center, zoom })Тайлы и атрибуция подключаются сами
L.tileLayer(url).addTo(map)не нужноТема подложки: theme: 'light' | 'dark' | 'gray', на лету map.setTheme('dark')
map.setView, setZoom, zoomIn, zoomOut, panTo, panBy, flyTo, fitBoundsте же именаflyTo(center, zoom, { duration })
map.getCenter(), getZoom(), getBounds()те же именаВозвращают [lng, lat] и LngLatBounds
map.on('click', e => e.latlng)map.on('click', e => e.lngLat)e.lngLat — [lng, lat]
map.remove()map.destroy()Снимает слушатели, DOM, таймеры, загрузки
L.marker(latlng, { draggable })EvaMaps.marker(lngLat, { draggable })Плюс color, label (подпись рядом с меткой), title
L.icon({ iconUrl, iconSize, iconAnchor })опция icon: { url, size, anchor }Или icon: HTMLElement
marker.bindPopup('<b>Офис</b>')marker.setPopup(EvaMaps.popup().setText('Офис'))Строки HTML не принимаются — см. ниже
L.popup().setLatLng(ll).setContent(…).openOn(map)EvaMaps.popup().setLngLat(ll).setText(…).openOn(map)
L.polyline, L.polygon, L.circle(ll, { radius })EvaMaps.polyline, EvaMaps.polygon, EvaMaps.circle(ll, радиусМетры, {…})Радиус круга — вторым аргументом
L.geoJSON(data)EvaMaps.geoJSON(data)
плагин Leaflet.markerclusterEvaMaps.cluster(points)Встроено, плагин не нужен
L.layerGroup([…])EvaMaps.layerGroup([…])
L.control.layers(base, overlays)EvaMaps.layersControl(base, overlays)Темы подложки — EvaMaps.themeLayers()
L.tileLayer.wms(url, {…})EvaMaps.wmsLayer({ url, layers, … })Чужой источник — на условиях его владельца
L.imageOverlay(url, bounds)EvaMaps.imageOverlay(url, bounds)План этажа, схема территории
scrollWheelZoom: false для встраиванияcooperative: trueКолесо с Ctrl/⌘, на телефоне двумя пальцами

Из npm — тот же набор классами: import { create, Marker, Popup } from '@evamaps/sdk'. Полный справочник — SDK.

Балуны: текст вместо HTML ​

bindPopup('<b>…</b>') в Leaflet вставляет строку как HTML — так на сайты попадает XSS из данных меток. В EvaMaps балун принимает:

  • setText(text) — только текст, теги выводятся как есть;
  • setLink(href) — ссылка, только http(s);
  • setContent(node) — своя разметка, но DOM-узлом, который вы создали сами.

Чего в EvaMaps нет ​

Честно, чтобы не было сюрпризов после переноса:

  • Плагинов Leaflet. Кластеры, GeoJSON, переключатель слоёв, WMS встроены. Остальное (рисование, тепловые карты, маршруты) — пока нет.
  • Чужой подложки вместо нашей. Свои XYZ-тайлы и WMS можно добавить слоем поверх, но основа — тайлы EvaMaps.
  • Retina-тайлов — в планах.
  • Маршрутов и поиска адресов. Геокодер в разработке.

Остальные ограничения — на отдельной странице. Сравнение с MapLibre, Яндексом и 2ГИС — здесь.

Нашли ошибку в документации? Напишите нам