fix(B06): 구조물을 놓아도 횡단도에 안 보이던 것 — 빈 초안이 저장분을 지우고 있었음
「구조물을 놓아도 횡단도에 아무것도 안 보인다」가 창 둘에서 같은 증상이었다. 화면에 표식을 심어 재 보니 **브라우저 쪽 단면에 `revetment` 자체가 없었다**. - 원인: `withDraftWalls` 가 미저장 초안 목록이 **빈 배열**일 때도 「초안 있음」으로 읽고 **서버 저장분(`revetment`)을 통째로 지운 뒤** 아무것도 안 얹었다. ⇒ `!drafts || !drafts.length` 로 고쳤다 — 빈 목록도 「초안 없음」이다. - 초안 경로가 `foundation` 을 안 실어 터파기가 안 그려지던 것도 함께 고침 (`WallSpec.foundation` 추가, 거울 시험도 같이 갱신). - 겹침 방지 가드를 **좁혔다** — 링크가 있기만 하면 막던 것을, 그 링크의 벽이 **이 카드에 실제로 설 때만** 막게 했다(`culvertWallsStandAt`). 관이 아홉·열하나인 노선에서는 링크가 거의 모든 측점을 덮어 독립 벽 경로가 통째로 죽어 있었다. 화면 확인: 벽 터파기 「기초유 · 폭 1.62m · 깊이 0.50m (수직)」, 관 터파기 Φ1000 1.80m · Φ800 1.60m, 그려진 선 전부 좌우 변이 수직. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -52,7 +52,10 @@ async function withDraftWalls(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
): Promise<SectionDetailResponse> {
|
): Promise<SectionDetailResponse> {
|
||||||
const drafts = readPendingStructures(projectId);
|
const drafts = readPendingStructures(projectId);
|
||||||
if (!drafts) return withStructureAreas(detail);
|
// ⚠ **빈 목록도 「초안 없음」이다**(2026-09-09). 예전에는 `[]` 가 「초안이 있는데 벽이
|
||||||
|
// 하나도 없다」로 읽혀 **아래에서 서버 저장분을 통째로 지웠다** — 구조물을 놓아도
|
||||||
|
// 횡단도에 아무것도 안 보이던 결함의 원인이다(창 둘에서 같은 증상, 실측 확인).
|
||||||
|
if (!drafts || !drafts.length) return withStructureAreas(detail);
|
||||||
const types = await fetchStructureTypes().catch(() => []);
|
const types = await fetchStructureTypes().catch(() => []);
|
||||||
const names = new Map(
|
const names = new Map(
|
||||||
types
|
types
|
||||||
|
|||||||
@@ -256,6 +256,27 @@ export function wallStandsAt(owner: CrossSection, section: CrossSection, key: st
|
|||||||
return spanCovers(revetSpanOfSpec(side), deltaM);
|
return spanCovers(revetSpanOfSpec(side), deltaM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 링크된 관의 벽이 **이 카드에 실제로 서는가**. 하나도 안 서면 그 링크는 이 측점의
|
||||||
|
* 그림을 막을 이유가 없다 — 독립 벽(D경로)이 그려져야 한다.
|
||||||
|
*
|
||||||
|
* 왜 있나(2026-09-09) — 「관이 없는 측점인데도 구조물을 놓으면 아무것도 안 보인다」가
|
||||||
|
* 사용자에게 보이던 결함이었다. 겹침 방지 가드가 **링크가 있기만 하면** 막고 있었는데,
|
||||||
|
* 관이 아홉·열하나인 노선에서는 링크가 거의 모든 측점을 덮어 D경로가 통째로 죽었다.
|
||||||
|
* 가드를 없애지 않고 **좁힌다** — 벽이 실제로 서는 카드에서만 막는다.
|
||||||
|
*/
|
||||||
|
export function culvertWallsStandAt(owner: CrossSection, section: CrossSection): boolean {
|
||||||
|
const keys = ["inlet", "outlet"];
|
||||||
|
const counts = owner.design?.extra_wall_counts ?? {};
|
||||||
|
for (const [side, count] of Object.entries(counts)) {
|
||||||
|
const total = Math.max(Math.trunc(Number(count) || 0), 0);
|
||||||
|
for (let index = 0; index < total; index += 1) {
|
||||||
|
keys.push(side === "basin" ? `bextra${index}` : `extra${index}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys.some((key) => wallStandsAt(owner, section, key));
|
||||||
|
}
|
||||||
|
|
||||||
export function culvertLinkFor(
|
export function culvertLinkFor(
|
||||||
section: CrossSection,
|
section: CrossSection,
|
||||||
sections: readonly CrossSection[],
|
sections: readonly CrossSection[],
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
appendFordPavementOverlay,
|
appendFordPavementOverlay,
|
||||||
appendFordSurfaceDropPlan,
|
appendFordSurfaceDropPlan,
|
||||||
} from "./B06_Section_UI_Cross_Ford_Pavement";
|
} from "./B06_Section_UI_Cross_Ford_Pavement";
|
||||||
|
import { culvertWallsStandAt } from "./B06_Section_UI_Cross_Culvert_Wire";
|
||||||
import { appendRevetmentOverlay, computeRevetmentLayout } from "./B06_Section_UI_Cross_Revetment";
|
import { appendRevetmentOverlay, computeRevetmentLayout } from "./B06_Section_UI_Cross_Revetment";
|
||||||
import {
|
import {
|
||||||
appendCrossDesignOverlay,
|
appendCrossDesignOverlay,
|
||||||
@@ -422,7 +423,12 @@ export function createCrossSectionCard(
|
|||||||
// 이 측점에 배관/숨김 기슭막이 세트가 직접 붙었거나(section.culvert) **연동으로
|
// 이 측점에 배관/숨김 기슭막이 세트가 직접 붙었거나(section.culvert) **연동으로
|
||||||
// 옆에서 이어져 온**(culvertLink) 경우엔 배관 경로가 그린다 — 옛 D경로는 건너뛴다
|
// 옆에서 이어져 온**(culvertLink) 경우엔 배관 경로가 그린다 — 옛 D경로는 건너뛴다
|
||||||
// (둘 다 그리면 이웃 카드에 벽이 겹친다 — 2026-08-28 이관 이중그리기 방지).
|
// (둘 다 그리면 이웃 카드에 벽이 겹친다 — 2026-08-28 이관 이중그리기 방지).
|
||||||
if (!section.culvert && !culvertLink) {
|
// ⚠ 가드를 **좁혔다**(2026-09-09) — 예전에는 링크가 **있기만 하면** 막았는데,
|
||||||
|
// 관이 아홉·열하나인 노선에서는 링크가 거의 모든 측점을 덮어 **구조물을 놓아도
|
||||||
|
// 횡단도에 아무것도 안 보였다**(사용자에게 보이던 결함). 겹침 방지라는 까닭은
|
||||||
|
// 그대로 두고, **그 링크의 벽이 이 카드에 실제로 설 때만** 막는다.
|
||||||
|
const linkedWallsHere = !!culvertLink && culvertWallsStandAt(culvertLink.source, section);
|
||||||
|
if (!section.culvert && !linkedWallsHere) {
|
||||||
const ownAdjust = revetOffset?.adjustFor(section, "own");
|
const ownAdjust = revetOffset?.adjustFor(section, "own");
|
||||||
const ownLayout = computeRevetmentLayout(section, ownAdjust);
|
const ownLayout = computeRevetmentLayout(section, ownAdjust);
|
||||||
ownDesignTrim = ownLayout?.designTrim;
|
ownDesignTrim = ownLayout?.designTrim;
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ export interface WallSpec {
|
|||||||
form: string | null;
|
form: string | null;
|
||||||
height_m: number | null;
|
height_m: number | null;
|
||||||
side: string | null;
|
side: string | null;
|
||||||
|
/** 기초 축 — "기초유" | "기초버림". 저장 칸과 같은 글자(터파기 그림이 이 값으로 갈린다). */
|
||||||
|
foundation: string | null;
|
||||||
tiers: number | null;
|
tiers: number | null;
|
||||||
lift_m: number | null;
|
lift_m: number | null;
|
||||||
shift_m: number | null;
|
shift_m: number | null;
|
||||||
@@ -78,6 +80,8 @@ export function wallSpecsFrom(
|
|||||||
form: (options.form as string) || FORM_BY_TYPE[structure.type_id] || null,
|
form: (options.form as string) || FORM_BY_TYPE[structure.type_id] || null,
|
||||||
height_m: num(options.height_m),
|
height_m: num(options.height_m),
|
||||||
side: (options.side as string) ?? null,
|
side: (options.side as string) ?? null,
|
||||||
|
// 기초 축 — 저장 칸과 **같은 글자**. 초안 경로에서 빠지면 터파기가 안 그려진다.
|
||||||
|
foundation: (options.foundation as string) ?? null,
|
||||||
tiers: num(options.tiers),
|
tiers: num(options.tiers),
|
||||||
lift_m: num(options.lift_m),
|
lift_m: num(options.lift_m),
|
||||||
shift_m: num(options.shift_m),
|
shift_m: num(options.shift_m),
|
||||||
|
|||||||
Reference in New Issue
Block a user