/* 459 노선 바뀜 — 진짜 TS(`logic/B05_Profile_Pipeline_Grade` 옮긴 시설 측점 · 427 세움 · planline 단계 · * `common_util_route_follow` 구조물 맞춤 · 추가 측점 따라감)를 Node 로 돌림. * 입력 argv[2] JSON [{ op, ... }, …] · 표준출력 = 결과 한 벌씩. */ const fs = require("fs"); const path = require("path"); const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const CATALOG = require("./helper_322_catalog_module.cjs"); const ROOT = path.join(__dirname, "..", ".."); const { loadTs: loadFull, load } = makeLoader({ root: ROOT, requireFor: (full) => (request) => { if (CATALOG.isCatalogRequest(request)) return CATALOG; if (request.endsWith(".json")) return JSON.parse(fs.readFileSync(path.join(path.dirname(full), request), "utf8")); if (request.startsWith(".")) return loadFull(path.join(path.dirname(full), `${request}.ts`)); throw new Error(`stub 없음: ${request} (${path.relative(ROOT, full)})`); }, }); const loadTs = (file) => load(file); // 뿌리 기준 상대 경로 const grade = loadTs("B05_Profile/logic/B05_Profile_Pipeline_Grade.ts"); const carry = loadTs("B05_Profile/logic/B05_Profile_Grade_Carry.ts"); const follow = loadTs("common_util/common_util_route_follow.ts"); const xy = (line) => line.map(([x, y]) => ({ x, y })); const cases = JSON.parse(fs.readFileSync(process.argv[2], "utf8")); const out = cases.map((item) => { switch (item.op) { case "moved": return grade.routeMovedStations(item.stations, xy(item.oldXy), xy(item.newXy)); case "userMoves": return grade.userMoves(item.stations, new Map(Object.entries(item.spots))); case "planline": { // 계산 묶음 planline 단계 그대로 — 저장 기준(storedPvi) · 새 지반 · 측점 · follow 출력 const stage = grade.createPlanlineStage({ savedBase: () => item.base, savedLine: () => item.oldXy, storedPvi: () => item.base.basePvi, }); const ctxOf = (stations, followed) => ({ inputs: { route: {}, alignment: null, pipes: item.pipes ?? null, structures: null }, out: { route: { line: item.newXy }, ground: { stations: stations.map((s) => ({ ...s, ground: null })), longitudinal: { chainageM: item.chainage, z: item.ground }, }, follow: followed, }, }); // follow 단계가 따라가기만 한 자리를 남김(노선 초안 전 관 = `origin`) const followed = item.origin ? grade.createFollowStage({ savedLine: () => item.oldXy, saved: () => item.origin })({ inputs: { route: {}, alignment: null, pipes: item.pipes ?? null, structures: null }, before: {}, out: { route: { line: item.newXy } }, }) : null; const result = stage(ctxOf(item.stations, followed)); // 시설 없는 같은 측점 = 옮겨 붙인 꼭짓점(427 세움 전) — 파이썬 `seat_route_moved` 입력 const plain = stage( ctxOf( (item.homeStations ?? item.stations).map((s) => ({ ...s, kind: "grid", id: null })), null, ), ); // 노선 저장 뒤(바뀐 구간 세움까지) — 사용자 옮김 전 기준 · 파이썬 관 저장 차례 입력 const home = grade.seatRouteMoved( { chainage: item.chainage, ground: item.ground, policy: item.base.policy, basePvi: plain.basePvi, }, item.homeBorn ?? [], ); return { basePvi: result.basePvi, carried: plain.basePvi, home }; } case "carry": return carry.carryBase(xy(item.oldXy), xy(item.newXy), item.oldBase, item.groundPvi); case "rebase": return follow.rebaseStructureDraft(item.draft, item.before, item.after); case "outside": { // 노선 밖 판정 · 따라감 표시 · 측점 계획에서 뺌(459 덧) const line = xy(item.line); const station = loadTs("common_util/common_util_structure_station.ts"); const pipes = follow.projectPipePoints(item.pipes, line); const structures = follow.followStructures(item.structures, line).map(({ item: s }) => s); return { flags: item.points.map(([x, y]) => follow.routeOutside(line, { x, y })), pipes: pipes.map((p) => [p.id, p.chainage_m, p.outside ?? false]), structures: structures.map((s) => [s.structure_id, s.chainage_m, s.outside ?? false]), planned: station.planStations(pipes, structures, []).map((m) => m.chainage_m), }; } case "plus": return follow.followPlusStations(item.list, xy(item.from), xy(item.to)); default: throw new Error(`op 없음: ${item.op}`); } }); process.stdout.write(JSON.stringify(out));