feat(proj): init
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
# 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`.
|
||||
Reference in New Issue
Block a user