Векторные карты на открытых данных OpenStreetMap: 3D-здания, глобус, рельеф, светлая и тёмная тема. Вставляются на сайт одной строкой или подключаются в приложение как стиль MapLibre. Ключ не нужен.
1. Iframe: проще всего
Двигайте карту в превью: код ниже обновляется сам.
Параметры URL /embed
| Параметр | Значение |
|---|---|
lat, lon, z | Центр и масштаб (0–20) |
bearing, pitch | Поворот в градусах и наклон (0–75) |
theme | light, dark или auto (по умолчанию: как в системе) |
lang | Язык подписей и кнопок: ru или en. Без параметра — по языку браузера зрителя |
worldview | Как показывать границы Крыма: ru — в составе России, ua — в составе Украины, intl — спорная граница пунктиром. Без параметра — по стране зрителя (по IP) |
marker | 1: маркер в центре, или lat,lon |
title | Подпись маркера |
color | Цвет маркера: e53935 (без #), f00 или имя цвета CSS, например green |
icon | Значок внутри маркера: эмодзи или 1–2 символа, например ☕ или А |
pin | Своя картинка вместо маркера: ссылка https://… (PNG, SVG, WebP). Точка на карте — середина нижнего края картинки |
pinsize | Ширина маркера в пикселях: капля 20–64 (по умолчанию 30, со значком 34), картинка 16–96 (по умолчанию 40) |
3d, controls, scroll, link | 1/0: наклон, кнопки, зум колесом без Ctrl, ссылка «Открыть карту» |
Управление из страницы (postMessage)
const frame = document.querySelector('iframe').contentWindow
frame.postMessage({ type: 'furkmaps:flyTo', center: [30.3158, 59.9391], zoom: 15 }, '*')
frame.postMessage({ type: 'furkmaps:setTheme', theme: 'dark' }, '*')
frame.postMessage({ type: 'furkmaps:addMarker', lngLat: [30.3158, 59.9391], title: 'Эрмитаж', color: '7b1fa2', icon: '🏛' }, '*')
frame.postMessage({ type: 'furkmaps:clearMarkers' }, '*')
// Карта сообщает о перемещениях и кликах
window.addEventListener('message', (e) => {
if (e.data?.type === 'furkmaps:click') console.log('клик', e.data.lngLat)
if (e.data?.type === 'furkmaps:moveend') console.log('центр', e.data.center, 'зум', e.data.zoom)
})
2. JS SDK
Обёртка над MapLibre GL JS: подключает стили, тему и 3D. Возвращает обычный maplibregl.Map.
<div id="map" style="height: 480px"></div>
<script src="https://maps.furkkinov.com/sdk.js"></script>
<script>
FurkMaps.createMap('map', {
theme: 'auto', // 'light' | 'dark' | 'auto'
lang: 'auto', // 'ru' | 'en' | 'auto' (по языку браузера)
worldview: 'auto', // границы Крыма: 'ru' | 'ua' | 'intl' | 'auto' (по стране зрителя)
center: [37.6175, 55.752], // [долгота, широта]
zoom: 15,
pitch: 55,
}).then(function (map) {
FurkMaps.addMarker(map, [37.6175, 55.752], { popup: 'Красная площадь', color: '#c62828', icon: '★' })
// своя картинка вместо капли: { image: 'https://example.com/logo.png', size: 48 }
// map.setTheme('dark')
})
</script>
Как ES-модуль
<script type="module">
import { createMap, addMarker, maplibregl } from 'https://maps.furkkinov.com/sdk.mjs'
const map = createMap('map', { theme: 'dark', center: [30.3158, 59.9391], zoom: 14 })
addMarker(map, [30.3158, 59.9391], { popup: 'Эрмитаж', icon: '🏛' })
// Полностью свой вид: любой HTML-элемент
const el = document.createElement('div')
el.textContent = 'Мы здесь'
new maplibregl.Marker({ element: el, anchor: 'bottom' }).setLngLat([30.3165, 59.9398]).addTo(map)
</script>
3. Свой MapLibre: стили
Если MapLibre у вас уже подключён (веб, React, Vue), достаточно URL стиля.
| Стиль | URL |
|---|---|
| Светлый | https://maps.furkkinov.com/styles/light.json |
| Тёмный | https://maps.furkkinov.com/styles/dark.json |
| Светлый, подписи EN | https://maps.furkkinov.com/styles/light-en.json |
| Тёмный, подписи EN | https://maps.furkkinov.com/styles/dark-en.json |
Эти стили показывают границы Крыма международными (спорная граница пунктиром). Варианты для России и Украины
лежат в папках ru/ и ua/: https://maps.furkkinov.com/styles/ru/light.json, https://maps.furkkinov.com/styles/ua/dark-en.json и т. д.
Отличаются только линии границ, слои и их id те же.
import maplibregl from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'
const map = new maplibregl.Map({
container: 'map',
style: 'https://maps.furkkinov.com/styles/light.json',
center: [37.6175, 55.752],
zoom: 14,
})
// Смена темы без перезагрузки
map.setStyle('https://maps.furkkinov.com/styles/dark.json', { diff: true })
// Объёмный рельеф
map.setTerrain({ source: 'dem', exaggeration: 1.4 })
4. Мобильные приложения
Стили совместимы с MapLibre Native: Android, iOS, Flutter, React Native. Глобус и небо поддерживаются не во всех версиях Native; без них карта всё равно работает.
Android (Kotlin)
// build.gradle: implementation("org.maplibre.gl:android-sdk:<версия>")
mapView.getMapAsync { map ->
map.setStyle("https://maps.furkkinov.com/styles/light.json")
map.cameraPosition = CameraPosition.Builder()
.target(LatLng(55.752, 37.6175)).zoom(14.0).tilt(45.0).build()
}
iOS (Swift)
import MapLibre
let mapView = MLNMapView(frame: view.bounds,
styleURL: URL(string: "https://maps.furkkinov.com/styles/dark.json"))
mapView.setCenter(CLLocationCoordinate2D(latitude: 55.752, longitude: 37.6175),
zoomLevel: 14, animated: false)
view.addSubview(mapView)
Flutter / React Native
// Flutter (maplibre_gl)
MapLibreMap(styleString: 'https://maps.furkkinov.com/styles/light.json', initialCameraPosition: ...)
// React Native (@maplibre/maplibre-react-native)
<MapView mapStyle="https://maps.furkkinov.com/styles/light.json" />
Для WebView проще всего iframe-страница: https://maps.furkkinov.com/embed?lat=55.752&lon=37.6175&z=14.
5. Прямой доступ к данным
| Что | URL |
|---|---|
| Векторные тайлы (MVT, схема Protomaps) | https://maps.furkkinov.com/tiles/planet/{z}/{x}/{y}.mvt |
| TileJSON | https://maps.furkkinov.com/tiles/planet.json |
| Рельеф (Terrarium PNG) | https://maps.furkkinov.com/dem/{z}/{x}/{y}.png |
| Поиск | https://maps.furkkinov.com/api/search?q=Эрмитаж&lat=59.94&lon=30.31&limit=5 |
| Карточка заведения | https://maps.furkkinov.com/api/place?lat=55.65962&lon=37.74979&name=Yves%20RocherЧасы работы, телефоны, сайт, соцсети из OSM: заведение ищется по названию рядом с точкой |
| Адрес по координатам | https://maps.furkkinov.com/api/reverse?lat=55.752&lon=37.6175У обоих запросов есть lang=ru|en и worldview=ru|ua|intl: с ru адреса в Крыму — «Республика Крым, Россия», иначе — «Автономна Республіка Крим, Україна» |
Тайлы и стили отдаются с CORS *. Поиск ограничен 5 запросами в секунду с одного IP.
Данные и лицензии
Всё построено на открытых данных и открытом ПО. При встраивании оставляйте атрибуцию на карте: iframe и SDK показывают её сами.
| Картографические данные | © участники OpenStreetMap, ODbL |
| Схема и сборка тайлов | Protomaps Basemap (Natural Earth, OSM) |
| Рельеф | Mapzen Terrain Tiles (SRTM, GMTED, ETOPO1 и др.) |
| Поиск | Photon по данным OpenStreetMap |
| Движок | MapLibre GL JS, BSD-3-Clause |
| Шрифты | Noto Sans, SIL Open Font License |