feat: add web OSM import workflow

This commit is contained in:
2026-08-26 14:05:26 +08:00
parent 81e02c670d
commit 181e575e1e
10 changed files with 189 additions and 16 deletions

View File

@@ -456,4 +456,10 @@ scenePreviewToggle.onchange = () => {
message(scenePreview ? "场景效果预览:当前编译面" : "编辑图层预览");
};
for (const button of diagnosticFilters.querySelectorAll("button")) button.onclick = () => { diagnosticFilter = button.dataset.diagnosticFilter; renderDiagnostics(); };
fetch("/api/state").then((response) => response.json()).then((value) => { state = value; updateDirtyState(); updateSources(); renderDiagnostics(); renderSummary(); areaLabel.textContent = state.areaId; const signalUid = new URLSearchParams(location.search).get("signal"); const signal = signalUid && poleFeatureForSignal(signalUid); if (signal) selectSignal(signal); message(`已加载 ${state.compiled.model.roads.length} 条方向道路`); }).catch((error) => message(error.message));
function showImportScreen() {
const panel = document.createElement("form"); panel.style.cssText = "position:fixed;inset:90px 25%;z-index:20;background:#fff;padding:32px;box-shadow:0 8px 30px #0003";
panel.innerHTML = "<h1>导入 OSM 地图</h1><p>选择一个 .osm 文件开始创建工作区。</p><input type=\"file\" accept=\".osm,application/xml,text/xml\" required><button type=\"submit\">导入并编译</button><output style=\"display:block;margin-top:12px\"></output>";
panel.onsubmit = async (event) => { event.preventDefault(); const file = panel.querySelector("input").files[0]; const output = panel.querySelector("output"); if (!file) return; output.textContent = "正在导入并编译..."; const body = new FormData(); body.append("file", file, file.name); try { const response = await fetch("/api/import", { method: "POST", body }); const result = await response.json(); if (!response.ok || !result.ok) throw new Error(result.error || `HTTP ${response.status}`); location.reload(); } catch (error) { output.textContent = error.message; } };
document.body.append(panel);
}
fetch("/api/state").then((response) => response.json()).then((value) => { if (!value.active && !value.compiled) return showImportScreen(); state = value; updateDirtyState(); updateSources(); renderDiagnostics(); renderSummary(); areaLabel.textContent = state.areaId; const signalUid = new URLSearchParams(location.search).get("signal"); const signal = signalUid && poleFeatureForSignal(signalUid); if (signal) selectSignal(signal); message(`已加载 ${state.compiled.model.roads.length} 条方向道路`); }).catch((error) => message(error.message));