5c5404b1226c1765c5fe6284ccff4ca486555940
SandCastle
Инструмент для массового захвата Google Photorealistic 3D Tiles в формате датасета UAV-GeoLoc. Через Cesium снимает ортофото-кропы сцены (DB) и «дроновые» кадры (query) по сетке, формирует JSON траектории камеры и сохраняет всё в дерево папок, совместимое с UAV-GeoLoc.
Быстрый старт
- Установите Node.js 14+.
- Запустите
start.bat:start.bat— запуск на порту3000start.bat 3001— запуск на указанном порту
- Откройте
http://localhost:<порт>если браузер не открылся сам.
Рабочий процесс
- Панель управления (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-контента
- Сохранить настройки →
settings.json. - Создать папки → дерево сцены и
{region}.txtс углами прямоугольника. - Запустить захват — откроется два окна:
- Карта зоны (mapview.html) — чистый canvas без внешних тайлов, красный прямоугольник зоны, синие точки тайлов, жёлтая активная точка, зелёный след пройденного
- Окно захвата (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:
{
"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.fromDegreesrotation—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— вертикальный FOVquery_pitch_deg— зафиксирован на-90(top-down)
- высоты query задаются тремя редактируемыми слотами (
height_100_value,height_125_value,height_150_value) и включаются соответствующими чекбоксами - при завершении захвата сохраняются:
DB/merge.tifpositive.jsonsemi_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 — Мороз Е.С. Павленко Б. В. / ЛИСАД
Description
Languages
HTML
70.6%
JavaScript
23.2%
CSS
5.3%
Batchfile
0.9%