- 노선 저장 직전 저장 관(id · 옛 누가거리)을 떠 두고 저장 뒤 같은 id 새 자리로 — 초안으로 안 따라간 관 조절(첫 초안 측점 짝 · 관 id 규칙 갈림) - carryChainageStates 시설 풀이 = 옛 자리 → 새 자리 · 관 열쇠 → 새 자리 - 시험 test_417 옛 자리 짝 · 346-3 저장 차례(관 받기) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Se7ytqbohmBQnfYpwYFnYf
156 lines
5.5 KiB
JavaScript
156 lines
5.5 KiB
JavaScript
/* 417 헬퍼 — vite ssr 로 묶은 진짜 모듈(helper_417_entry.ts)을 부르고 결과를 JSON 한 벌로.
|
|
* node helper_417_route_carry.mjs <묶음.mjs> <입력.json>
|
|
* 입력 = { standard: 파이썬 config 표준단면 }.
|
|
*/
|
|
import { readFileSync } from "node:fs";
|
|
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);
|
|
|
|
const [bundlePath, inputPath] = process.argv.slice(2);
|
|
const m = await import(pathToFileURL(bundlePath).href);
|
|
const input = JSON.parse(readFileSync(inputPath, "utf8"));
|
|
const P = "p417";
|
|
const R = 7;
|
|
const R2 = 8;
|
|
const raw = (name, route) => m.readState(name, P, route) ?? {};
|
|
const keysOf = (name, route) =>
|
|
Object.keys(raw(name, route))
|
|
.filter((k) => k !== "@at")
|
|
.sort();
|
|
const section = (chainage_m, kind, extra = {}) => ({
|
|
station_id: `s${chainage_m}`,
|
|
chainage_m,
|
|
kind,
|
|
label: String(chainage_m),
|
|
samples: [],
|
|
design: {},
|
|
...extra,
|
|
});
|
|
const detailOf = (sections) => ({
|
|
longitudinal: {
|
|
stations: sections,
|
|
profile_alignment: { policy: { station_interval_m: 20 } },
|
|
},
|
|
cross_sections: sections,
|
|
});
|
|
const out = {};
|
|
|
|
/* 1. 옛 노선(관 45 m) — B06 조절 · 사면 쉬프트 · 소단 깊이 · 측점 폭 · 상세 표 · 연동을 세션에 */
|
|
m.writeState("pipe-ids", { next: 2, ids: [{ id: "pipe-s1", at: 45 }] }, P);
|
|
const pipe = { structure: "파형강관 D800", culvert: {} };
|
|
m.useStationKeys(
|
|
P,
|
|
R,
|
|
detailOf([
|
|
section(0, "bp"),
|
|
section(20, "regular"),
|
|
section(40, "regular"),
|
|
section(45, "irregular", pipe),
|
|
section(60, "ep"),
|
|
]),
|
|
);
|
|
m.writeShoulderExtend(P, R, 40, "left", 0.5);
|
|
m.writeBermDepth(P, R, 40, "right", 1.2);
|
|
const wall = { x: 0.3, d: null, h: 1.5, m: null };
|
|
m.writeState("revetx", { "45.00:outlet": wall, "40.00:inlet": wall }, P, R);
|
|
m.writeState("boxadjust", { "45.00": { left: { x: 0.2 } } }, P, R);
|
|
m.writeState("crossw", { "40.00": 6 }, P, R);
|
|
m.writeState("detail-table", { "45.00": { rows: 2 } }, P, R);
|
|
m.writeState("revetlink", { detached: { "45.00": true }, grade: {} }, P, R);
|
|
|
|
/* 2. 노선 바뀐 [저장] — 새 노선(관 47 m 로 따라감 · 끝 58 m) 측점 열쇠로 옮김 */
|
|
m.writeState("pipe-ids", { next: 2, ids: [{ id: "pipe-s1", at: 47 }] }, P);
|
|
const next = detailOf([
|
|
section(0, "bp"),
|
|
section(20, "regular", { design: { shoulder_extend_right_m: 0.7, berm_depth_left_m: 0.4 } }),
|
|
section(40, "regular"),
|
|
section(47, "irregular", pipe),
|
|
section(58, "ep"),
|
|
]);
|
|
m.useStationKeys(P, R2, next);
|
|
out.keyedOutside = m.carryStationDrafts(P, R, R2, { quiet: true });
|
|
out.chainageOutside = m.carryChainageStates(P, R, R2);
|
|
out.shoulderKeys = keysOf("shoulderext", R2);
|
|
out.bermKeys = keysOf("bermdepth", R2);
|
|
out.revet = raw("revetx", R2);
|
|
out.box = raw("boxadjust", R2);
|
|
out.width = raw("crossw", R2);
|
|
out.table = raw("detail-table", R2);
|
|
out.link = raw("revetlink", R2);
|
|
|
|
/* 3. 새 상세 설계 칸에 얹음 — 같은 [저장]의 횡단 패치가 실을 값 */
|
|
m.withDraftAdjusts(next, P, R2);
|
|
m.withCarriedEdits(next, P, R2);
|
|
const at = (c) => next.cross_sections.find((s) => s.chainage_m === c).design;
|
|
out.design40 = at(40);
|
|
out.design47 = at(47);
|
|
|
|
/* 4. 평면 초안 횡단 입력 — 세션 사면 쉬프트 · 소단 깊이 + 저장분(세션 없음)도 */
|
|
m.writeState("std-cross", input.standard, P);
|
|
const stations = next.cross_sections.map((s, i) => ({
|
|
key: ["end:BP", "grid:1", "grid:2", "pipe:pipe-s1", "end:EP"][i],
|
|
chainageM: s.chainage_m,
|
|
kind: i === 3 ? "pipe" : "grid",
|
|
}));
|
|
const source = m.pipelineCrossSource(P, next, stations, R2);
|
|
const pick = (entry) =>
|
|
Object.fromEntries(
|
|
Object.entries(entry ?? {}).filter(([k]) => /^(shoulderExtend|bermDepth)/.test(k)),
|
|
);
|
|
out.input40 = pick(source?.input.byKey["grid:2"]);
|
|
out.input20 = pick(source?.input.byKey["grid:1"]);
|
|
|
|
/* 5. 관 id 규칙이 갈림(옛 목록 세션 id · 새 목록 저장 관 id) — 시설 자리 풀이로 옮김 · 없으면 버림 */
|
|
const R3 = 9;
|
|
const R4 = 10;
|
|
const list = [
|
|
{ key: "end:BP", chainageM: 0 },
|
|
{ key: "grid:1", chainageM: 20 },
|
|
{ key: "grid:2", chainageM: 40 },
|
|
{ key: "pipe:p9", chainageM: 52 },
|
|
{ key: "end:EP", chainageM: 60 },
|
|
];
|
|
m.useStationKeyList(P, R3, list);
|
|
m.useStationKeyList(P, R4, list);
|
|
m.writeState("pipe-ids", { next: 2, ids: [{ id: "pipe-s1", at: 45 }] }, P);
|
|
m.useStationKeys(
|
|
P,
|
|
R,
|
|
detailOf([section(0, "bp"), section(45, "irregular", pipe), section(60, "ep")]),
|
|
);
|
|
m.writeState("revetx", { "45.00:outlet": wall }, P, R);
|
|
m.carryChainageStates(P, R, R3, { keyAt: (key) => (key === "pipe:pipe-s1" ? 52 : null) });
|
|
m.carryChainageStates(P, R, R4);
|
|
out.splitResolved = raw("revetx", R3);
|
|
out.splitDropped = raw("revetx", R4);
|
|
// 옛 저장 시설 측점(초안으로 안 따라간 고침) — 좌표 짝으로 새 시설 측점에
|
|
const R5 = 11;
|
|
m.useStationKeyList(P, R5, list);
|
|
m.carryChainageStates(P, R, R5, { movedAt: (c) => (c === 45 ? 52 : null) });
|
|
out.movedByPlace = raw("revetx", R5);
|
|
|
|
process.stdout.write(JSON.stringify(out));
|