# Tile Server ASP.NET Core сервер векторных тайлов для клиентов **MapLibre GL**. Ежедневно (и при старте) воркер: 1. Скачивает все настроенные OSM-extract’ы с Geofabrik (и любых других HTTP-ссылок на `.osm.pbf`). 2. Собирает из них OpenMapTiles MBTiles через [planetiler-openmaptiles](https://github.com/openmaptiles/planetiler-openmaptiles). 3. Отдаёт тайлы, TileJSON и стили карты. ## Что нужно - .NET 8 SDK - **Java 21+** в `PATH` (или путь в `TileServer:JavaPath`) — без Java тайлы не соберутся, уже готовые MBTiles сервер всё равно отдаст - Диск: 5–10× размер PBF. ЦФО до **z15** — ориентир несколько ГБ готового MBTiles плюс столько же на staging во время сборки - RAM: ориентир `TileServer:JvmMaxHeap` ≈ 0.5× размер PBF (по умолчанию `8g`) Тайлы собираются через OpenMapTiles. Схема рассчитана на z0–z14 (дефолт MapTiler/Planetiler). Жёсткий потолок **planetiler-openmaptiles 3.16 — z15**; z16+ этот JAR не умеет. Ближе z15 MapLibre overzoom’ит те же тайлы до z18. Первая сборка ЦФО занимает часы. Для быстрой проверки временно поставьте Monaco: ```json "Url": "https://download.geofabrik.de/europe/monaco-latest.osm.pbf" ``` ## Запуск ```bash dotnet run --project src/TileServer.Api ``` Откройте http://localhost:5088 — тестовая карта, выбор источника и стиля. ```bash docker compose up -d --build ``` Сервис слушает **51300** (внутри контейнера 8080). Данные (PBF, MBTiles, стили, ключи) — Docker volume `tile-server-data`, деплой кода его не затирает. Не вызывайте `docker compose down -v`. Если на сервере уже есть `./data`, один раз перенесите: ```bash docker run --rm -v "$(pwd)/data:/from:ro" -v tile-server-data:/to alpine sh -c "cp -a /from/. /to/" docker compose up -d --build ``` ## API | Метод | URL | Назначение | | --- | --- | --- | | `GET` | `/api/v1/tiles/{source}/{z}/{x}/{y}.pbf` | векторный тайл (MapLibre XYZ) | | `GET` | `/api/v1/tiles/{source}.json` | TileJSON | | `GET` | `/api/v1/styles` | список стилей | | `GET` | `/api/v1/styles/{name}?source={source}` | MapLibre style JSON | | `PUT` | `/api/v1/styles/{name}` | добавить/обновить стиль | | `GET` | `/api/v1/sources` | extract’ы и статус воркера | | `PUT` | `/api/v1/sources/{id}` | добавить регион (ещё одна ссылка на PBF) | | `POST` | `/api/v1/sync` | прогнать все extract’ы сейчас | | `POST` | `/api/v1/sync/{id}` | прогнать один extract | | `GET` | `/` | демо MapLibre | Алиасы без `/api/v1`: `/tiles/{source}/{z}/{x}/{y}.pbf`. ## Несколько регионов В `appsettings.json` → `TileServer:Extracts` можно перечислить сколько угодно выгрузок. Воркер проходит **все** `Enabled: true` по очереди (чтобы не упереться в RAM). ```json "Extracts": [ { "Id": "central-fed-district", "Name": "Центральный федеральный округ", "Url": "https://download.geofabrik.de/russia/central-fed-district-latest.osm.pbf", "Center": [37.6173, 55.7558] }, { "Id": "northwestern-fed-district", "Name": "Северо-Западный федеральный округ", "Url": "https://download.geofabrik.de/russia/northwestern-fed-district-latest.osm.pbf", "Center": [30.3141, 59.9386] } ] ``` То же самое в runtime: `PUT /api/v1/sources/{id}` (пишет `data/extracts.json`, переживает рестарт). Расписание: cron `TileServer:Sync:Cron`, по умолчанию `0 3 * * *` UTC. Если PBF не изменился (HTTP 304) и MBTiles уже есть — пересборка пропускается, **кроме случая когда в конфиге MaxZoom больше, чем в текущем тайсете** (после поднятия z14→z15 сборка пойдёт сама). Клиенты в TileJSON/стиле видят maxzoom собранной пирамиды (14/15): MapLibre сам растягивает эти тайлы ближе. Если кто-то всё же запросит z16–18, сервер нарежет их из родителя. Вне ЦФО отдаётся 204, не 404. ## Стили Кладёте `data/styles/{name}.json` (MapLibre Style Spec v8, схема слоёв OpenMapTiles) или делаете `PUT /api/v1/styles/{name}`. Клиент запрашивает стиль по имени: ``` GET /api/v1/styles/osm-bright?source=central-fed-district ``` Сервер подставляет TileJSON выбранного источника. Из коробки: `osm-bright`, `dark`, `positron`. Пример источника в MapLibre: ```js const map = new maplibregl.Map({ container: "map", style: "http://localhost:5088/api/v1/styles/osm-bright?source=central-fed-district", center: [37.6173, 55.7558], zoom: 6 }); ``` ## Архитектура ``` Api контроллеры, демо, ProblemDetails Application sync, tiles, styles, extracts Domain extract, tile coordinate, ошибки Infrastructure загрузка PBF, Planetiler, MBTiles/SQLite, файловые стили, hosted worker ``` Данные по умолчанию: `data/` в корне репозитория (`../../data` относительно проекта API). В проде задайте `TileServer__DataDirectory`.