Merge remote-tracking branch 'origin/dev' into sub_laptop_6
This commit is contained in:
@@ -305,7 +305,14 @@ export function createSectionCanvas(onPick: (index: number | null) => void): Sec
|
||||
labels.append(
|
||||
svgEl(
|
||||
"text",
|
||||
{ x: ax + 8, y: ay - 10, class: "e03-label e03-label--fs", "data-role": "fs-label" },
|
||||
{
|
||||
x: ax,
|
||||
y: ay,
|
||||
dx: "0.6em",
|
||||
dy: "-0.7em",
|
||||
class: "e03-label e03-label--fs",
|
||||
"data-role": "fs-label",
|
||||
},
|
||||
`Fs = ${fmt(critical.fs)}`,
|
||||
),
|
||||
);
|
||||
@@ -313,7 +320,7 @@ export function createSectionCanvas(onPick: (index: number | null) => void): Sec
|
||||
labels.append(
|
||||
svgEl(
|
||||
"text",
|
||||
{ x: ax + 8, y: ay + 6, class: "e03-label" },
|
||||
{ x: ax, y: ay, dx: "0.7em", dy: "0.5em", class: "e03-label" },
|
||||
`Xc ${fmt(critical.center[0], 2)} · Zc ${fmt(critical.center[1], 2)} · R ${fmt(critical.radius, 2)} m`,
|
||||
),
|
||||
);
|
||||
@@ -351,7 +358,10 @@ export function createSectionCanvas(onPick: (index: number | null) => void): Sec
|
||||
maxScale: MAX_SCALE,
|
||||
home: focusHome(fit, view, analysis, width, height, MAX_SCALE),
|
||||
initial: zoom,
|
||||
onChange: (state) => (zoom = state),
|
||||
onChange: (state) => {
|
||||
zoom = state;
|
||||
labels.style.setProperty("--e03-label-k", String(1 / state.scale)); // 글자는 확대 안 함
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -420,14 +420,14 @@
|
||||
|
||||
.e03-label {
|
||||
fill: var(--color-text);
|
||||
font-size: 12px;
|
||||
font-size: calc(12px * var(--e03-label-k, 1));
|
||||
paint-order: stroke;
|
||||
stroke: var(--e03-plot);
|
||||
stroke-width: 3px;
|
||||
stroke-width: calc(3px * var(--e03-label-k, 1));
|
||||
}
|
||||
|
||||
.e03-label--fs {
|
||||
font-size: 14px;
|
||||
font-size: calc(14px * var(--e03-label-k, 1));
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ def _row2d(row: dict[str, Any], method: str) -> dict[str, Any]:
|
||||
cond: sides[side]["fs"] for cond, sides in cases.items() if side in sides
|
||||
},
|
||||
"fs_min": min(values) if values else None,
|
||||
"min_by_condition": row.get("min") or {},
|
||||
"method": method,
|
||||
"verdict": "ng" if "ng" in verdicts else "ok" if verdicts == {"ok"} else None,
|
||||
"representative": row.get("representative") or {},
|
||||
@@ -556,19 +557,23 @@ def fill_3d(sheet: dict[str, Any], inputs: dict[str, Any]) -> tuple[str, str]:
|
||||
ground = inputs["ground"]
|
||||
labels = _labels(inputs["stations"])
|
||||
rows2d = inputs["result2d"]["stations"]
|
||||
crit = _criterion(ground, "dry")
|
||||
sections = []
|
||||
for i, sec in enumerate(inputs["sections3d"]):
|
||||
r = 20 + i
|
||||
_copy_row(sheet, 20, r, "ABCDEGH")
|
||||
start, end = float(sec["start_m"]), float(sec["end_m"])
|
||||
cond = sec.get("condition") or "dry" # 2D 는 3D 와 같은 조건끼리 견줌
|
||||
inside = [
|
||||
float(s["fs_min"])
|
||||
float(s["min_by_condition"][cond])
|
||||
for s in rows2d
|
||||
if s.get("fs_min") is not None and start - 1e-6 <= float(s["chainage_m"]) <= end + 1e-6
|
||||
if s["min_by_condition"].get(cond) is not None
|
||||
and start - 1e-6 <= float(s["chainage_m"]) <= end + 1e-6
|
||||
]
|
||||
f3 = float(sec["f_min"])
|
||||
ok = f3 >= crit - 1e-9
|
||||
if sec.get("verdict") in ("ok", "ng"): # 판정 = E04 엔진 값(기준안전율도 E04)
|
||||
ok = sec["verdict"] == "ok"
|
||||
else:
|
||||
ok = f3 >= _criterion(ground, cond) - 1e-9
|
||||
_set(sheet, f"A{r}", f"{i + 1}구간" + (" (미리보기)" if sec.get("preview") else ""))
|
||||
_set(sheet, f"B{r}", _label_at(labels, start))
|
||||
_set(sheet, f"C{r}", _label_at(labels, end))
|
||||
|
||||
@@ -165,7 +165,7 @@ def test_e01_requires_b06(monkeypatch):
|
||||
call()
|
||||
assert e.value.status_code == 404
|
||||
seen, call = _e01(monkeypatch, [{**src, "project_year": 2026, "section_complete": 1}])
|
||||
assert call() == {"project_id": "stab-id", "source_fingerprint": "f" * 40}
|
||||
assert call() == {"project_id": "stab-id", "source_fingerprint": "f" * 40, "warnings": []}
|
||||
assert seen["copied"] == ("stab-id", "s" * 36)
|
||||
assert seen["kind"] == "STABILITY" and seen["source_project_id"] == "s" * 36
|
||||
assert seen["name"] == "임도 안정성평가"
|
||||
|
||||
@@ -157,7 +157,15 @@ def project(tmp_path, monkeypatch) -> Path:
|
||||
{
|
||||
"fingerprint": "3d-1",
|
||||
"settings": {},
|
||||
"summary": {"start_m": 0.0, "end_m": 200.0, "f_min": 1.42, "volume": 830.0},
|
||||
"summary": {
|
||||
"start_m": 0.0,
|
||||
"end_m": 200.0,
|
||||
"f_min": 1.42,
|
||||
"volume": 830.0,
|
||||
"condition": "wet",
|
||||
"reference_fs": 1.3,
|
||||
"verdict": "ok",
|
||||
},
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
@@ -215,8 +223,8 @@ def test_처음_만듦_측점수_NG_그림(project):
|
||||
assert s3["A26"]["값"] == "풍화토" and s3["B32"]["값"].startswith("0 ~ 100 m 위 지층")
|
||||
assert s3["A32"]["값"] == "붕적토" and s3["B13"]["값"] == 1.3
|
||||
s6 = by["3D요약"]["칸"]
|
||||
assert s6["D20"]["값"] == 1.42 and s6["H20"] == {"값": "N.G", "서식": build.ST_NG}
|
||||
assert s6["E20"]["값"] == pytest.approx(1.11) # 0~200 m 안 2D 최소
|
||||
assert s6["D20"]["값"] == 1.42 and s6["H20"] == {"값": "O.K", "서식": build.ST_OK} # E04 판정
|
||||
assert s6["E20"]["값"] == pytest.approx(1.11) # 0~200 m 안 2D 우기 최소(3D 와 같은 조건)
|
||||
assert (build.initial_dir(project) / build.REPORT).is_file()
|
||||
assert saved["fingerprint"] == build.analysis_fingerprint(project)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user