122 lines
4.5 KiB
JavaScript
122 lines
4.5 KiB
JavaScript
"use strict";
|
|
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
function writeCesiumPreviewSupportFiles(outDir) {
|
|
for (const file of ["cesium-preview.css", "cesium-preview.js"]) {
|
|
const source = path.join(__dirname, file);
|
|
if (!fs.existsSync(source)) {
|
|
throw new Error(`Cesium preview support file '${file}' not found: ${source}`);
|
|
}
|
|
fs.copyFileSync(source, path.join(outDir, file));
|
|
}
|
|
}
|
|
|
|
function cesiumPreviewHtml(glbName, metadataName, routeName, vehicleModelName, areaId, vehicleModelNames = [], trafficSignalsName = null) {
|
|
const previewConfig = {
|
|
areaId,
|
|
glbName,
|
|
metadataName,
|
|
routeName,
|
|
vehicleModelName,
|
|
vehicleModelNames,
|
|
trafficSignalsName,
|
|
};
|
|
return `<!doctype html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>${escapeHtml(areaId)} Cesium Preview</title>
|
|
<script src="https://cdn.jsdelivr.net/npm/cesium@1.121.1/Build/Cesium/Cesium.js"></script>
|
|
<link href="https://cdn.jsdelivr.net/npm/cesium@1.121.1/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
|
|
<link href="cesium-preview.css" rel="stylesheet">
|
|
</head>
|
|
<body>
|
|
<div id="cesiumContainer"></div>
|
|
<div id="controls">
|
|
<div class="control-group">
|
|
<button id="toggleCruise">Pause</button>
|
|
<button id="toggleFollow">Follow</button>
|
|
<label>Vehicle <select id="vehicleSelect"></select></label>
|
|
<label>Speed <input id="speedControl" type="range" min="2" max="22" step="1" value="8"></label>
|
|
<span id="speedLabel">8 m/s</span>
|
|
</div>
|
|
<div class="control-group">
|
|
<span class="control-label">View</span>
|
|
<span id="viewMode" class="segmented-control" role="group" aria-label="Scene view mode">
|
|
<button type="button" data-view-mode="scene" aria-pressed="true">Scene</button>
|
|
<button type="button" data-view-mode="inspect" aria-pressed="false">Inspect</button>
|
|
</span>
|
|
<label><input id="toggleScene" type="checkbox" checked> Scene</label>
|
|
<label><input id="toggleBuildingGhost" type="checkbox"> Building ghost</label>
|
|
<span id="assetToggles" class="control-subgroup"></span>
|
|
<span id="semanticToggles" class="control-subgroup hidden"></span>
|
|
<label><input id="toggleRoutes" type="checkbox" checked> Routes</label>
|
|
<label><input id="toggleVehicles" type="checkbox" checked> Vehicles</label>
|
|
<label id="signalsControl"><input id="toggleSignals" type="checkbox" checked> Signals</label>
|
|
<label><input id="toggleFps" type="checkbox"> FPS</label>
|
|
<label><input id="toggleDiagnostics" type="checkbox" checked> Info</label>
|
|
</div>
|
|
<div class="control-group">
|
|
<button data-camera="overview">Overview</button>
|
|
<button data-camera="oblique">Oblique</button>
|
|
<button data-camera="detail">Detail</button>
|
|
<button data-camera="route">Route</button>
|
|
</div>
|
|
</div>
|
|
<div id="diagnostics">Loading diagnostics...</div>
|
|
<div id="status">Loading ${escapeHtml(glbName)}...</div>
|
|
<div id="loadingOverlay">
|
|
<div class="loading-card">
|
|
<div class="loading-spinner" aria-hidden="true"></div>
|
|
<div class="loading-copy">
|
|
<strong>Loading scene</strong>
|
|
<span>${escapeHtml(areaId)}</span>
|
|
</div>
|
|
<div class="loading-bar" aria-hidden="true"><span></span></div>
|
|
</div>
|
|
</div>
|
|
<script>window.OSM_ASSET_PREVIEW_CONFIG = ${escapeScriptJson(JSON.stringify(previewConfig))};</script>
|
|
<script src="cesium-preview.js"></script>
|
|
</body>
|
|
</html>
|
|
`;
|
|
}
|
|
|
|
function escapeHtml(value) {
|
|
return String(value)
|
|
.replaceAll("&", "&")
|
|
.replaceAll("<", "<")
|
|
.replaceAll(">", ">")
|
|
.replaceAll('"', """);
|
|
}
|
|
|
|
function escapeScriptJson(value) {
|
|
return String(value)
|
|
.replaceAll("<", "\\u003c")
|
|
.replaceAll(">", "\\u003e")
|
|
.replaceAll("&", "\\u0026")
|
|
.replaceAll("\u2028", "\\u2028")
|
|
.replaceAll("\u2029", "\\u2029");
|
|
}
|
|
|
|
function previewSummary(area) {
|
|
const route = JSON.parse(fs.readFileSync(area.outputs.vehicleRoute, "utf8"));
|
|
return {
|
|
glbName: path.basename(area.outputs.glb),
|
|
metadataName: path.basename(area.outputs.metadata),
|
|
routeName: path.basename(area.outputs.vehicleRoute),
|
|
vehicleModelName: path.basename(area.outputs.vehicleModel),
|
|
trafficSignalsName: path.relative(area.outputs.areaDir, area.outputs.trafficSignals).split(path.sep).join("/"),
|
|
routeSegments: Array.isArray(route.segments) ? route.segments.length : null,
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
cesiumPreviewHtml,
|
|
previewSummary,
|
|
writeCesiumPreviewSupportFiles,
|
|
};
|