Initial commit: v1.0

This commit is contained in:
Azidaan
2026-04-16 15:26:59 +03:00
commit 5c5404b122
23 changed files with 7564 additions and 0 deletions

145
README.md Normal file
View File

@@ -0,0 +1,145 @@
# SandCastle
Инструмент для массового захвата Google Photorealistic 3D Tiles в формате датасета **UAV-GeoLoc**. Через Cesium снимает ортофото-кропы сцены (DB) и «дроновые» кадры (query) по сетке, формирует JSON траектории камеры и сохраняет всё в дерево папок, совместимое с UAV-GeoLoc.
## Быстрый старт
1. Установите Node.js 14+.
2. Запустите `start.bat`:
- `start.bat` — запуск на порту `3000`
- `start.bat 3001` — запуск на указанном порту
3. Откройте `http://localhost:<порт>` если браузер не открылся сам.
## Рабочий процесс
1. **Панель управления** ([index.html](index.html)) — задайте имена сцены и параметры:
- `Dataset / Country / City / Region` — 4 уровня дерева в `output/`
- `Точка 1 / Точка 2` — противоположные углы прямоугольника в формате DMS
- `Шаг сетки (метры)` — размер одного тайла
- `Прореживание` — 1 = все точки, 2 = каждая вторая
- `DB crop sizes` — ровно 11 уникальных размеров PNG-кропов (через запятую)
- `Разрешение query кадра` — размер итогового JPEG (по умолчанию 512)
- `FOV вертикальный` — параметр съёмки query-камеры
- `Pitch query` — фиксирован в `-90` (top-down)
- `Высоты (3 слота)` — чекбоксы + редактируемые значения высот
- `Абсолютная высота` — выкл = над рельефом
- `Предзагрузка тайлов` — прогрев Cesium перед съёмкой
- `Пропускать пустые зоны` — не сохранять области без 3D-контента
2. **Сохранить настройки**`settings.json`.
3. **Создать папки** → дерево сцены и `{region}.txt` с углами прямоугольника.
4. **Запустить захват** — откроется два окна:
- **Карта зоны** ([mapview.html](mapview.html)) — чистый canvas без внешних тайлов, красный прямоугольник зоны, синие точки тайлов, жёлтая активная точка, зелёный след пройденного
- **Окно захвата** ([capture.html](capture.html)) — Cesium Viewer, прогресс и лог
## Структура проекта
```
SandCastle/
├── start.bat Запуск (проверяет Node, принимает порт, стартует сервер)
├── package.json
├── server.js Express backend + API
├── index.html Панель управления
├── ui.js UI-контроллер панели
├── style.css
├── capture.html Окно захвата (Cesium)
├── mapview.html Окно карты (canvas, без внешних тайлов)
├── settings.json Последние настройки (создаётся автоматически)
└── output/ Результаты (создаётся автоматически)
└── {dataset}/{country}/{city}/{region}/
├── {region}.txt Углы зоны: maxLat minLon / minLat maxLon
├── DB/
│ ├── merge.tif Базовый TIFF сцены (для внешней нарезки)
│ ├── db_postion.txt Строки: filename lon lat res_x res_y
│ └── img/
│ └── crop_{col}_{row}_{size}.png Ортофото по сетке (X=col, Y=row, size=px)
├── positive.json Соответствия query -> точный DB crop
├── semi_positive.json Соответствия query -> соседние DB crop
└── query/
└── height{H}_rot{R}/
├── height{H}_rot{R}.json Траектория камеры
└── footage/
└── height{H}_rot{R}_{NN}.jpeg Дроновые кадры
```
## Формат траектории (UAV-GeoLoc)
`query/height100_rot0/height100_rot0.json`:
```json
{
"name": "height100_rot0",
"width": 512,
"height": 512,
"frameRate": 30,
"numFrames": 75,
"durationSeconds": 2.5,
"cameraFrames": [
{
"position": { "x": 3843512.1, "y": 604821.7, "z": 5095123.4 },
"rotation": { "x": -60, "y": 0, "z": 0 },
"coordinate": { "latitude": 52.41, "longitude": 9.65, "altitude": 100 },
"fovVertical": 30
}
]
}
```
`numFrames` и `durationSeconds` вычисляются автоматически по фактическому числу сохранённых кадров.
- `position` — ECEF (Earth-Centered Earth-Fixed) в метрах, получено через `Cesium.Cartesian3.fromDegrees`
- `rotation``x` = pitch, `y` = heading (yaw), `z` = roll, все в градусах (pitch задаётся в UI)
- `coordinate` — геодезические координаты точки съёмки
- `fovVertical` — вертикальный FOV камеры Cesium в градусах (задаётся в UI)
## API сервера
| Метод | Путь | Назначение |
|---|---|---|
| GET | `/api/get-settings` | Текущие настройки (или дефолты) |
| POST | `/api/save-settings` | Сохранить настройки в `settings.json` |
| POST | `/api/create-folders` | Создать дерево сцены и `{region}.txt` |
| POST | `/api/start-capture` | Сохранить настройки и вернуть URL `capture.html` |
| POST | `/api/save-db-crop` | Сохранить `crop_{col}_{row}_{size}.png` + строку в `db_postion.txt` |
| POST | `/api/save-merge-tif` | Сохранить `DB/merge.tif` |
| POST | `/api/save-drone-frame`| Сохранить кадр `height{H}_rot{R}_{NN}.jpeg` |
| POST | `/api/save-trajectory` | Сохранить `height{H}_rot{R}.json` |
| POST | `/api/save-annotations` | Сохранить `positive.json` и `semi_positive.json` |
## Координаты DMS
Формат: `52°25'10.28"N 9°39'10.04"E`. Точки 1 и 2 — противоположные углы прямоугольника; их порядок не важен, сервер сам вычисляет `minLat/maxLat/minLon/maxLon`.
## Параметры съёмки (актуально)
- `DB crop sizes` — обязательный список из **11 уникальных** положительных размеров (px)
- стандартная кнопка в UI подставляет:
- `100,150,200,250,300,400,500,512,600,800,1000`
- для каждого тайла сохраняется 11 PNG-кропов:
- `crop_{col}_{row}_{size}.png`
- `Query`:
- `drone_size` — размер JPEG кадра
- `query_fov_deg` — вертикальный FOV
- `query_pitch_deg` — зафиксирован на `-90` (top-down)
- высоты query задаются тремя редактируемыми слотами (`height_100_value`, `height_125_value`, `height_150_value`) и включаются соответствующими чекбоксами
- при завершении захвата сохраняются:
- `DB/merge.tif`
- `positive.json`
- `semi_positive.json`
## Обмен окнами
`capture.html``mapview.html` общаются через `BroadcastChannel('sandcastle-map')`. Сообщения:
- `{type: 'init', bounds, tiles}` — одноразово после генерации сетки
- `{type: 'position', index, total, lat, lon}` — перед съёмкой каждого тайла
- `{type: 'done', total}` — по завершении
- `{type: 'request-init'}` — карта запрашивает реплей при позднем открытии
## Требования
- Node.js 14+
- Cesium Ion token (Google Photorealistic 3D Tiles, asset `2275207`) — вшит в `capture.html`
- Интернет для Cesium CDN и Google 3D Tiles (карта зоны работает офлайн)
## Версия
1.0.0 — Мороз Е.С. Павленко Б. В. / ЛИСАД