- 세월교 · BOX 조정 제어가 폼 값을 조정 예약(culvertopt)에 또 담지 않음 — 관 초안(가게 pipes)이 관 id 로 옮김 · 노선 바뀜을 따라감(H4a) - 측점 갈아끼움 옮김 목록에 culvertopt 추가 — 옛 세션 잔값도 관 새 자리로 - 내보내기 주석 — 못 맞춘 값은 다른 관에 안 얹고 버림 - 시험 test_444_culvertopt_single_draft — 옮김 · 두 번째 [저장] 값 그대로(H4b) · 못 맞춘 값 버림 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
146 lines
4.7 KiB
JavaScript
146 lines
4.7 KiB
JavaScript
/* 444 헬퍼 — 관 구간값 예약(culvertopt)이 관 옮김을 따라가고 · 못 맞춘 값은 버리고 · 두 번째 [저장]이 안 덮음.
|
|
* node helper_444_culvertopt.mjs <묶음.mjs>
|
|
* 묶음 = 444 진입점(`helper_444_entry.ts` · 346-2 묶음 + 내보내기 · vite ssr 진짜 모듈) · 표준출력 JSON 한 벌.
|
|
* 짝 = test_444_culvertopt_single_draft.py · 틀 = helper_415_swap.mjs(415-3).
|
|
*/
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
const store = () => {
|
|
const m = new Map();
|
|
return {
|
|
getItem: (k) => (m.has(k) ? m.get(k) : null),
|
|
setItem: (k, v) => m.set(k, String(v)),
|
|
removeItem: (k) => m.delete(k),
|
|
key: (i) => [...m.keys()][i] ?? null,
|
|
get length() {
|
|
return m.size;
|
|
},
|
|
clear: () => m.clear(),
|
|
};
|
|
};
|
|
globalThis.window = globalThis;
|
|
globalThis.sessionStorage = store();
|
|
globalThis.localStorage = store();
|
|
const any = new Proxy(function () {}, {
|
|
get: (_t, k) => (k === Symbol.toPrimitive ? () => 0 : any),
|
|
apply: () => any,
|
|
construct: () => any,
|
|
});
|
|
globalThis.document = any;
|
|
globalThis.requestAnimationFrame = (run) => setTimeout(run, 0);
|
|
globalThis.__toasts = [];
|
|
|
|
/* 관 정본(서버) — GET 은 지금 관 · PUT 은 받은 몸통으로 바꿈 */
|
|
let saved = [];
|
|
const puts = [];
|
|
globalThis.fetch = async (url, init = {}) => {
|
|
if (String(url).includes("/drainage/pipe-points") && init.method === "PUT") {
|
|
const points = JSON.parse(init.body).points;
|
|
puts.push(points);
|
|
saved = points.map((point) => ({ ...point, lonlat: [0, 0] }));
|
|
}
|
|
return { ok: true, status: 200, json: async () => ({ pipe_points: saved, basins: [] }) };
|
|
};
|
|
|
|
const m = await import(pathToFileURL(process.argv[2]).href);
|
|
const P = "p444";
|
|
const R = 3;
|
|
const out = {};
|
|
|
|
const section = (chainage_m, kind, extra = {}) => ({
|
|
station_id: `station_${String(Math.round(chainage_m * 1000)).padStart(12, "0")}`,
|
|
chainage_m,
|
|
label: "",
|
|
kind,
|
|
center_z: 100,
|
|
azimuth_deg: 90,
|
|
center_x: chainage_m,
|
|
center_y: 0,
|
|
frame: { left_xy: [0, 1] },
|
|
samples: [{ offset_m: 0, elevation_m: 100, valid: true }],
|
|
design: { design_elevation_m: 101 },
|
|
...extra,
|
|
});
|
|
const detail = () => ({
|
|
longitudinal: {
|
|
length_m: 100,
|
|
stations: [],
|
|
profile_alignment: { policy: { station_interval_m: 20 } },
|
|
},
|
|
cross_sections: [
|
|
section(0, "bp"),
|
|
section(20, "regular"),
|
|
section(40, "regular"),
|
|
section(45.054, "irregular", { structure: "세월교", culvert: {} }),
|
|
section(60, "regular"),
|
|
section(80, "regular"),
|
|
section(100, "ep"),
|
|
],
|
|
});
|
|
const station = (key, chainageM, kind, id = null) => ({
|
|
key,
|
|
chainageM,
|
|
x: chainageM,
|
|
y: 0,
|
|
azimuthDeg: 90,
|
|
left: [0, 1],
|
|
kind,
|
|
id,
|
|
ground: { centerZ: 99, left: [{ offsetM: 0.5, z: 99.1 }], right: [{ offsetM: 0.5, z: 98.9 }] },
|
|
planRadiusM: null,
|
|
curveOuterSide: null,
|
|
curveWideningM: null,
|
|
});
|
|
const list = (pipeAt) =>
|
|
[
|
|
station("end:BP", 0, "end"),
|
|
station("grid:1", 20, "grid"),
|
|
station("grid:2", 40, "grid"),
|
|
station("pipe:pipe-s1", pipeAt, "pipe", "pipe-s1"),
|
|
station("grid:3", 60, "grid"),
|
|
station("grid:4", 80, "grid"),
|
|
station("end:EP", 100, "end"),
|
|
].sort((a, b) => a.chainageM - b.chainageM);
|
|
const key = `aislo:draft:culvertopt:${P}:${R}`;
|
|
|
|
/* 1. 관 5 m 옮김 — 옛 세션 구간값 예약도 관 새 자리로(조정창 맵 없이 · 415-3 과 같은 길) */
|
|
m.writeState("section-detail", detail(), P, R);
|
|
m.writeState("pipe-ids", { next: 2, ids: [{ id: "pipe-s1", at: 45.054 }] }, P);
|
|
await m.loadSectionDetail(P, R);
|
|
m.writeState("culvertopt", { 45.05: { ford_width_m: 4 } }, P, R);
|
|
const stop = m.followSwaps(
|
|
P,
|
|
() => R,
|
|
{ visible: () => true },
|
|
async () => undefined,
|
|
);
|
|
m.writeState("pipe-ids", { next: 2, ids: [{ id: "pipe-s1", at: 50 }] }, P);
|
|
m.useDesignStore(P, null).set("stations", list(50));
|
|
await new Promise((resolve) => setTimeout(resolve, 30));
|
|
out.moved = m.readState("culvertopt", P, R);
|
|
stop();
|
|
|
|
/* 2. [저장] 두 번 — 첫 번째는 관 새 자리에 얹고 세션 비움 · 두 번째는 안 보냄(값 그대로) */
|
|
saved = [
|
|
{ id: "p5000", chainage_m: 50, source: "stream", facility: "ford", options: { ford_width_m: 3 } },
|
|
];
|
|
await m.flushCulvertOptions(P, key);
|
|
out.firstSave = {
|
|
puts: puts.length,
|
|
width: saved[0].options.ford_width_m,
|
|
left: sessionStorage.getItem(key),
|
|
};
|
|
await m.flushCulvertOptions(P, key);
|
|
out.secondSave = { puts: puts.length, width: saved[0].options.ford_width_m };
|
|
|
|
/* 3. 못 맞춘 값(지운 · 옮긴 관 옛 자리) — 다른 관에 안 얹고 버림 */
|
|
m.writeState("culvertopt", { "30.00": { ford_width_m: 9 } }, P, R);
|
|
await m.flushCulvertOptions(P, key);
|
|
out.unmatched = {
|
|
puts: puts.length,
|
|
width: saved[0].options.ford_width_m,
|
|
left: sessionStorage.getItem(key),
|
|
};
|
|
|
|
process.stdout.write(JSON.stringify(out));
|