- swapCrossSections 같은 자리 원천 끝에 저장 정본(Section_Canon CanonRow 에 자리 · 표본 · Section_Store 가 savedDesigns 넘김) — 옮겼다 제자리로 온 관 · 버린 노선 초안 뒤 측점 = 정본 표본 · 기하 - sameStationList — 시설 측점(irregular) 자리가 일반 측점으로 돌아가면 다른 목록(관 지운 카드가 남던 흠) - design_facility_lane paint — 종류 표 전 빈 측점을 종단도에 안 씀 - 시험 test_272_swap_keeps_canon · test_272_berm_source 에 셋(옛 코드 실패 확인) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
157 lines
5.2 KiB
JavaScript
157 lines
5.2 KiB
JavaScript
/* 467 헬퍼 — 소단 원천 한 벌: 구조물 → 소단 구간(TS) · 저장분 소단 제원(TS) · 시설 줄이 세션 사본을 씀 ·
|
|
* 다시 셈 = 사본 없으면 저장분 `design.berm`.
|
|
* node helper_272_berm_source.mjs <묶음.mjs> <job.json>
|
|
* job = { standard, rockDefault, structureCases, storedCases, ground } · 짝 = `test_272_berm_source.py`.
|
|
*/
|
|
import { readFileSync } from "node:fs";
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
const writes = [];
|
|
const memory = () => {
|
|
const m = new Map();
|
|
return {
|
|
getItem: (k) => (m.has(k) ? m.get(k) : null),
|
|
setItem: (k, v) => {
|
|
writes.push(k);
|
|
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 = memory();
|
|
globalThis.localStorage = memory();
|
|
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.fetch = async () => new Response("{}", { status: 404 });
|
|
|
|
const m = await import(pathToFileURL(process.argv[2]).href);
|
|
const job = JSON.parse(readFileSync(process.argv[3], "utf8"));
|
|
const P = "p272berm";
|
|
const R = 5;
|
|
const out = {};
|
|
|
|
/* 1. 거울 — 구조물 → 소단 구간 · 저장분 제원 */
|
|
out.spans = job.structureCases.map((list) => m.bermSpansFromStructures(list));
|
|
out.stored = job.storedCases.map((spec) => m.storedBermSpec(spec));
|
|
|
|
/* 2. 시설 줄이 사본을 씀 — 구조물 받기 전 안 씀 · 같으면 안 씀 · 바뀌면 한 번 */
|
|
{
|
|
m.setPageRouteId(P, R);
|
|
const key = m.stateKey("berm", P, R);
|
|
const count = () => writes.filter((k) => k === key).length;
|
|
const copy = () => m.readState("berm", P, R);
|
|
const lane = m.createFacilityLane(P, () => null);
|
|
const steps = {};
|
|
lane.setTypes([]);
|
|
lane.follow(); // 저장분 · 가게 구조물 없음 = 아직 모름
|
|
steps.beforeKnown = { copy: copy(), writes: count() };
|
|
const saved = job.structureCases[0];
|
|
lane.setStored(saved);
|
|
lane.set({ structures: saved }, false);
|
|
steps.loaded = { copy: copy(), writes: count() };
|
|
lane.set({ structures: saved.map((item) => ({ ...item })) });
|
|
lane.set({ pipes: [] });
|
|
steps.same = { writes: count() };
|
|
const moved = saved.map((item) =>
|
|
item.type_id === "berm" ? { ...item, start_m: item.start_m + 5, end_m: item.end_m + 5 } : item,
|
|
);
|
|
lane.set({ structures: moved });
|
|
steps.moved = { copy: copy(), writes: count() };
|
|
lane.set({ structures: [] });
|
|
steps.removed = { copy: copy(), writes: count() };
|
|
lane.dispose();
|
|
out.lane = steps;
|
|
}
|
|
|
|
/* 2-2. 시설 줄 칠함 — 종류 표 받기 전 측점(빈 목록)을 종단도에 안 씀 · 받은 뒤 한 번 */
|
|
{
|
|
const P2 = "p272paint";
|
|
const wrote = [];
|
|
const fake = {
|
|
setStructureTypes: () => undefined,
|
|
setStructures: () => undefined,
|
|
setIrregularStations: (list) => wrote.push(list.length),
|
|
setMinCoverPipes: () => undefined,
|
|
resetStationEdit: () => undefined,
|
|
};
|
|
const lane = m.createFacilityLane(P2, () => fake);
|
|
lane.set({ pipes: [] });
|
|
lane.set({ structures: [] }, false);
|
|
lane.paint();
|
|
const before = wrote.length;
|
|
lane.setTypes([{ type_id: "berm", name: "소단", placement: "interval" }]);
|
|
out.paint = { before, after: wrote.length };
|
|
lane.dispose();
|
|
}
|
|
|
|
/* 3. 다시 셈 소단 원천 — 사본 없음(저장분 design.berm) · 사본 = 같은 구간 · 사본 = 빈 목록 */
|
|
{
|
|
m.writeState("std-cross", job.standard, P);
|
|
m.rememberRockBoundaryDefault(P, job.rockDefault);
|
|
const detailOf = () => ({
|
|
longitudinal: { length_m: 200, stations: [], profile_alignment: { policy: {} } },
|
|
cross_sections: [
|
|
{
|
|
station_id: "station_000000040000",
|
|
chainage_m: 40,
|
|
label: "",
|
|
kind: "regular",
|
|
center_z: 96,
|
|
azimuth_deg: 90,
|
|
center_x: 40,
|
|
center_y: 0,
|
|
frame: { left_xy: [0, 1] },
|
|
uphill_side: "left",
|
|
samples: job.ground,
|
|
design: {
|
|
design_elevation_m: 100,
|
|
ground_type: "soil",
|
|
section_mode: "both_fill",
|
|
ditch_type: "standard",
|
|
berm: job.storedBerm,
|
|
},
|
|
},
|
|
],
|
|
});
|
|
const alignment = {
|
|
stations: [{ chainage_m: 40, plan_elevation_m: 100 }],
|
|
samples: [
|
|
{ chainage_m: 0, elevation_m: 100 },
|
|
{ chainage_m: 100000, elevation_m: 100 },
|
|
],
|
|
balance: { cut_area_m2: 0, fill_area_m2: 0, net_area_m2: 0 },
|
|
};
|
|
const run = async (copy) => {
|
|
if (copy === undefined) sessionStorage.removeItem(m.stateKey("berm", P, R));
|
|
else m.writeState("berm", copy, P, R);
|
|
const detail = detailOf();
|
|
await m.refreshCrossDesigns({
|
|
projectId: P,
|
|
routeId: R,
|
|
detail,
|
|
edits: { station_offsets: {}, curve_radii: {} },
|
|
alignment,
|
|
});
|
|
const design = detail.cross_sections[0].design;
|
|
return { fill: design.fill_area_m2 ?? null, cut: design.cut_area_m2 ?? null };
|
|
};
|
|
out.refresh = {
|
|
noCopy: await run(undefined),
|
|
copySame: await run(m.bermSpansFromStructures(job.structureCases[0])),
|
|
copyEmpty: await run([]),
|
|
};
|
|
}
|
|
|
|
process.stdout.write(JSON.stringify(out));
|