Files
LisCastle/app.js
2026-04-16 15:26:59 +03:00

218 lines
5.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import * as Cesium from "cesium";
Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3NjcxNWZiYy1mZjFiLTQzNGEtYmEwNy1hMmU0ZDg4NWI2ZGUiLCJpZCI6Mzc3NjU2LCJpYXQiOjE3NjgyMTk2NzJ9.D5DL5zrDi4yK6OPgq-ypC4hM5hfqYKODvppgakc7y3g";
const creditContainer = document.createElement('div');
creditContainer.style.display = 'none';
const viewer = new Cesium.Viewer("cesiumContainer", {
timeline: false,
animation: false,
sceneModePicker: false,
baseLayerPicker: false,
geocoder: false,
homeButton: false,
navigationHelpButton: false,
terrainProvider: await Cesium.createWorldTerrainAsync(),
creditContainer: creditContainer,
contextOptions: {
webgl: {
preserveDrawingBuffer: true
}
}
});
try {
const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(2275207);
viewer.scene.primitives.add(tileset);
} catch (error) {
console.log(error);
}
/*
=================== Настройка отображения ===================
*/
const outputWidth = 512;
const outputHeight = 512;
viewer.scene.canvas.style.width = outputWidth + 'px';
viewer.scene.canvas.style.height = outputHeight + 'px';
viewer.container.style.width = outputWidth + 'px';
viewer.container.style.height = outputHeight + 'px';
viewer.resize(); // важно: обновляет внутренние размеры рендерера
/*
=================== Вспомагательные функции ===================
*/
function dmsToDecimal(dms) {
// Пример входа: "48°18'20\"N" или "16°24'41\"E"
const regex = /(\d+)°(\d+)'(\d+)"?([NSEW])/i;
const match = dms.match(regex);
if (!match) {
throw new Error("Неверный формат координат: " + dms);
}
const degrees = parseInt(match[1], 10);
const minutes = parseInt(match[2], 10);
const seconds = parseInt(match[3], 10);
const direction = match[4].toUpperCase();
let decimal = degrees + minutes / 60 + seconds / 3600;
// Южная и Западная широты — отрицательные
if (direction === "S" || direction === "W") {
decimal = -decimal;
}
return decimal;
}
function metersToLat(m) {
return m / METERS_PER_DEG_LAT;
}
function metersToLon(m, latDeg) {
return m / (METERS_PER_DEG_LAT * Math.cos(Cesium.Math.toRadians(latDeg)));
}
function saveImage(filename) {
const canvas = viewer.scene.canvas;
const image = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.href = image;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function downloadFile(filename, content, mime = "text/plain") {
const blob = new Blob([content], { type: mime });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
/*
=================== Константы и переменные ===================
*/
const METERS_PER_DEG_LAT = 111_320;
// ---- Параметры сетки ----
const GRID = 2;
const TILE_M = 50;
const CAMERA_HEIGHT = 450;
// ---- Координаты ----
const latDMS = "45°25'3\"N";
const lonDMS = "9°04'15\"E";
//45°25'35"N 9°04'15"E
const half = (GRID - 1) * TILE_M / 2;
const CENTER_LAT = dmsToDecimal(latDMS);
const CENTER_LON = dmsToDecimal(lonDMS);
const startLat = CENTER_LAT + metersToLat(half);
const startLon = CENTER_LON - metersToLon(half, CENTER_LAT);
let row = 0;
let col = 0;
let index = 0;
const offset = 0.0005;
/*
=================== Главный цикл сбора ===================
*/
var flag = false;
function captureNextTile() {
if (flag == false) {
setTimeout(() => {
flag = true;
}, 5000)
}
const lat = startLat - metersToLat(row * TILE_M);
const lon = startLon + metersToLon(col * TILE_M, lat);
downloadFile(
`tile_${index}_sat.json`,
JSON.stringify({ lat: lat, lon: lon }, null, 2),
"application/json"
);
// ---------- Спутник ----------
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(lon, lat, CAMERA_HEIGHT),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-90),
roll: 0
}
});
viewer.scene.requestRender();
setTimeout(() => {
saveImage(`tile_${index}_sat.png`);
// ---------- Дрон ----------
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(lon, lat - offset, CAMERA_HEIGHT),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-60),
roll: 0
}
});
viewer.scene.requestRender();
setTimeout(() => {
saveImage(`tile_${index}_drone.png`);
// ---- След. ячейка ----
col++;
if (col >= GRID) {
col = 0;
row++;
}
index++;
captureNextTile();
}, 2500); // Задержка дрон-рендера
}, 2500); // Задержка спутник-рендера
}
/*
=================== Запуск ===================
*/
viewer.scene.postRender.addEventListener(function once() {
viewer.scene.postRender.removeEventListener(once);
setTimeout(() => {
captureNextTile();
}, 9000);
});