- 자리 칸 목록 한 벌 = TS `SEAT_KEYS`(Station_Swap · 파이썬 Router_Design 이 그 글을 읽음) — two_stage_slope · rock_boundary_offset_m · cut_slope_ratio_user · section_mode · ditch_side - 자리 판정 한 벌 = `sameSeat` ↔ 파이썬 `same_seat`(중심 0.01 m · 왼쪽 축 1e-3 · 모르면 같은 자리 = 옛 동작) - 끌기 세션 넘김 · Node stations.carry = `carryKeyedStates`(목록 측점 자리 · 값마다 쓴 때 자리 `@seat` — 되돌리기로 되살린 값도 제 자리로) - 미리보기 = `pipelineCrossSource` 가 저장분 · 세션 자리 칸에 자리째 실음 → `crossAtSeat` 가 새 자리면 뺌 - B06 갈아끼움(노선 초안) = 자리 바뀐 측점 설계의 자리 칸 걷고 기본값(`unseated` · 브레인 덧) - 서버 노선 저장 = `carry_cross_inputs` 자리 칸 같은 자리만 · 손 단면 유형 · 측구 방향 = `compute_default_designs` 입력 - 옛 단언 시험 고침(자리 모름 목록 = 같은 자리 = 손 상단측도 넘김 · 「@seat」 칸 거름) · 새 시험 test_475_3_seat_carry - 위키 rules 넘김 규칙 줄 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
137 lines
4.8 KiB
JavaScript
137 lines
4.8 KiB
JavaScript
// 440 — 노선 초안 동안 B06 카드(묶음 새 상세) 번호가 찾기 상세(갈아끼운 캐시)에 있음.
|
|
// 저장 상세 → cross 입력 모음(`pipelineCrossSource` · 진짜) → 새 상세(`draftSectionDetail` · 진짜) 대 갈아끼움(`swapCrossSections` · 진짜).
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const ROOT = path.resolve(__dirname, "..", "..");
|
|
const ts = require(path.join(ROOT, "config", "node_modules", "typescript"));
|
|
const idOf = (m) => `station_${String(Math.round(m * 1000)).padStart(12, "0")}`;
|
|
const REAL =
|
|
/(B05_Profile_Pipeline_Detail|B06_Section_Station_Swap|B06_Section_Route_Carry|design_pipeline_cross|common_util_\w+)$/; // Route_Carry = 자리 칸 「@seat」(475-3)
|
|
const CATALOG = require("./helper_322_catalog_module.cjs");
|
|
const STUBS = {
|
|
B05_Profile_Pipeline_Grade: { stationIdOf: idOf },
|
|
common_util_station: { stationLabel: (m) => String(m) },
|
|
B05_Profile_UI_Profile_Data: { toDesignProfile: () => ({}) },
|
|
b_page_state: { readState: () => null },
|
|
B06_Section_Section_Canon: { savedDesigns: () => null },
|
|
B06_Section_UI_Standard_Panel: {
|
|
effectiveStandardCross: () => ({ road_width_m: 3 }),
|
|
readRockBoundaryDefault: () => null,
|
|
},
|
|
};
|
|
const cache = new Map();
|
|
function load(full) {
|
|
if (cache.has(full)) return cache.get(full).exports;
|
|
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
|
}).outputText;
|
|
const box = { exports: {} };
|
|
cache.set(full, box);
|
|
const req = (r) => {
|
|
if (CATALOG.isCatalogRequest(r)) return CATALOG;
|
|
if (r.endsWith(".json"))
|
|
return JSON.parse(fs.readFileSync(path.resolve(path.dirname(full), r)));
|
|
const name = r.split("/").pop();
|
|
if (STUBS[name]) return STUBS[name];
|
|
if (REAL.test(r)) return load(path.resolve(path.dirname(full), r + ".ts"));
|
|
throw new Error(`stub 없음: ${r}`);
|
|
};
|
|
new Function("exports", "module", "require", js)(box.exports, box, req);
|
|
return box.exports;
|
|
}
|
|
const detailMod = load(path.join(ROOT, "B05_Profile/logic/B05_Profile_Pipeline_Detail.ts"));
|
|
const swapMod = load(path.join(ROOT, "B06_Section/logic/B06_Section_Station_Swap.ts"));
|
|
const crossMod = load(path.join(ROOT, "A00_Common/design/design_pipeline_cross.ts"));
|
|
|
|
const sec = (m, kind, extra = {}) => ({
|
|
station_id: idOf(m),
|
|
chainage_m: m,
|
|
label: "",
|
|
kind,
|
|
center_x: m,
|
|
center_y: 0,
|
|
samples: [],
|
|
design: { design_elevation_m: 100 },
|
|
...extra,
|
|
});
|
|
// 저장 상세: 일반 340 · 관 351(배수관) · 일반 360
|
|
const saved = {
|
|
longitudinal: { stations: [], design_profiles: [], length_m: 400, samples: [] },
|
|
cross_sections: [
|
|
sec(340, "regular"),
|
|
sec(351, "irregular", { culvert: { chainage_m: 351, diameter_m: 0.8 } }),
|
|
sec(360, "regular"),
|
|
],
|
|
};
|
|
const st = (key, m, kind) => ({
|
|
key,
|
|
chainageM: m,
|
|
kind,
|
|
x: m + 0.5,
|
|
y: 3,
|
|
left: [0, 1],
|
|
azimuthDeg: 0,
|
|
ground: null,
|
|
});
|
|
const savedStations = [
|
|
st("grid:340", 340, "grid"),
|
|
st("pipe:p35100", 351, "pipe"),
|
|
st("grid:360", 360, "grid"),
|
|
];
|
|
// 노선 초안: 교점 끌기 → 관이 좌표 따라 354 로(410) · 일반 측점은 같은 m
|
|
const draftStations = [
|
|
st("grid:340", 340, "grid"),
|
|
st("pipe:p35100", 354, "pipe"),
|
|
st("grid:360", 360, "grid"),
|
|
];
|
|
const oldKeys = savedStations.map((s) => s.key);
|
|
|
|
const source = crossMod.pipelineCrossSource("p1", saved, savedStations, null);
|
|
// 그림 자료 = 지금 현황(따라간 관 · 457) — 관 p35100 이 354 로
|
|
const types = [{ type_id: "pipe", name: "배수관", options: [] }];
|
|
const status = detailMod.shapeStatus(
|
|
[{ id: "p35100", facility: "pipe", chainage_m: 354, options: { pipe_diameter_mm: "800" } }],
|
|
[],
|
|
types,
|
|
);
|
|
const draft = detailMod.draftSectionDetail(
|
|
saved,
|
|
{ stations: draftStations, longitudinal: { chainageM: [0, 400], z: [0, 0] } },
|
|
{},
|
|
null,
|
|
source.specs,
|
|
20,
|
|
status,
|
|
);
|
|
const swapped = swapMod.swapCrossSections(saved, draftStations, oldKeys, 20).detail;
|
|
const ids = (detail) => detail.cross_sections.map((s) => s.station_id);
|
|
const swappedIds = new Set(ids(swapped));
|
|
const pipeCard = draft.cross_sections[1];
|
|
// 새 측점(초안에서 처음 생긴 일반 측점) = 누가거리 번호
|
|
const added = detailMod.draftSectionDetail(
|
|
saved,
|
|
{
|
|
stations: [...draftStations, st("grid:380", 380, "grid")],
|
|
longitudinal: { chainageM: [0, 400], z: [0, 0] },
|
|
},
|
|
{},
|
|
null,
|
|
source.specs,
|
|
20,
|
|
status,
|
|
);
|
|
console.log(
|
|
JSON.stringify({
|
|
draftIds: ids(draft),
|
|
allFoundInSwapped: ids(draft).every((id) => swappedIds.has(id)),
|
|
sameOrder: JSON.stringify(ids(draft)) === JSON.stringify(ids(swapped)),
|
|
pipeCard: [
|
|
pipeCard.station_id,
|
|
pipeCard.chainage_m,
|
|
pipeCard.culvert && pipeCard.culvert.chainage_m,
|
|
],
|
|
longIds: draft.longitudinal.stations.map((s) => s.station_id),
|
|
addedId: added.cross_sections[3].station_id,
|
|
}),
|
|
);
|