Тема
Слои
Общее для всех слоёв: addTo(map), remove(), on/off/once там, где у слоя есть события.
TileLayer ✅
ts
new TileLayer({ url, maxNativeZoom?, retina?, maxParallel? })Растровые XYZ-тайлы. url — шаблон с {z}, {x}, {y} и необязательным {r} (заменяется на @2x для ретины). Выше maxNativeZoom тайлы растягиваются на клиенте. Уже загруженная подложка не исчезает, пока не загрузится новый уровень зума; ошибки загрузки повторяются 3 раза.
ts
map.add(new TileLayer({ url: 'https://evamaps.ru/v1/light/{z}/{x}/{y}{r}.png' }));Marker (метка) ✅
ts
new Marker(lngLat, { color?, label?, draggable?, zIndexOffset?, riseOnHover? })| Статус | |
|---|---|
setLngLat / getLngLat, setColor / getColor | ✅ |
setPopup(popup) / getPopup() — балун по клику | ✅ |
label / setLabel(text) — короткая постоянная подпись рядом с меткой (≤ 24 символа, только текст) | ✅ |
draggable, события dragstart / drag / dragend | ✅ |
событие click | ✅ |
zIndexOffset (по умолчанию 0) / setZIndexOffset(offset) / getZIndexOffset() — сдвиг метки в стопке относительно других меток | ✅ |
riseOnHover (по умолчанию false) — временно поднимать метку поверх остальных при наведении или фокусе | ✅ |
ts
const marker = new Marker([37.6173, 55.7558], { color: '#e53935', draggable: true })
.setPopup(new Popup().setText('Наш офис'))
.addTo(map);
marker.on('dragend', () => console.log(marker.getLngLat()));Popup (балун) ✅
ts
new Popup({ autoPan?, autoPanPadding? })| Статус | |
|---|---|
setText(text) — только текст, без HTML | ✅ |
setLink(href) — ссылка, только http(s) | ✅ |
setContent(node: Node) — доверенная разметка разработчика, DOM-узлом | ✅ |
openBalloon() / close() / toggle() | ✅ |
autoPan (по умолчанию true) / autoPanPadding (по умолчанию [20, 20] px) — если балун не помещается в видимую область, карта плавно подвигается с этим отступом | ✅ |
setText не принимает HTML-строку намеренно — это защита от XSS, когда текст метки приходит из пользовательских данных (адрес, имя клиента). Если разметка нужна и вы доверяете её источнику (например, собираете сами на сервере), передайте готовый DOM-узел в setContent(node).
ts
popup.setText('Обычный текст, безопасно даже из пользовательского ввода');
const node = document.createElement('div');
node.textContent = 'Своя разметка — только когда вы сами её строите';
popup.setContent(node);Polyline, Polygon, Circle ✅
ts
new Polyline(lngLats, { color, weight, opacity })
new Polygon(rings, { color, weight, fillColor, fillOpacity })
new Circle(center, radiusMeters, { color, weight, fillColor, fillOpacity })Рисуются в SVG; метки на карте всегда отображаются поверх фигур. Корректно работают через антимеридиан (180°, например у Чукотки) — не рисуются «через весь мир».
GeoJSONLayer ✅
ts
new GeoJSONLayer(geojson, { style?, pointToMarker? })Преобразует geometry-типы GeoJSON в слои карты: Point → Marker, LineString → Polyline, Polygon → Polygon, а также Multi* и GeometryCollection.
ts
const layer = new GeoJSONLayer(geojson, {
style: (feature) => ({ color: feature.properties.color ?? '#2f6fed' }),
}).addTo(map);ClusterLayer ✅
ts
new ClusterLayer(points, { radius? })Группирует близкие точки в кластеры, клик по кластеру приближает карту. Событие pointClick срабатывает по клику на отдельную (некластеризованную) точку. Работает и через 180° долготы — объекты по обе стороны от антимеридиана (например, у Чукотки) группируются вместе, если рядом географически.