feat(E03): 판정 면 칸(원호 · 비원호 · 면 확인 · 모형 끝 면) + 탐색 한계 고르기 (PLAN 567-1)
- 목록 판정 면 칸 · 결과 방법 줄 · 면 확인 · 모형 끝 면 배지 - 해석 설정 탐색 한계(모형 끝 / 비탈 끝 + 2H / 비탈 끝 + 정한 m) — [해석] 이 저장 + 그 값으로 셈 - Router 설정 저장본 · 지문 · 일꾼 kwargs · 단면 · 가정 · 확률 길 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -55,6 +55,7 @@ from E03_StabSection import E03_StabSection_View as view
|
||||
from E03_StabSection import E03_StabSection_Walls as walls_mod
|
||||
from E03_StabSection import E03_StabSection_Worker as worker
|
||||
from E03_StabSection.E03_StabSection_Engine_Model import (
|
||||
SEARCH_REACH,
|
||||
ground_from_cross,
|
||||
section_model_from_b06,
|
||||
widen_ground,
|
||||
@@ -67,6 +68,7 @@ PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
KIND_STATION = worker.KIND_STATION
|
||||
KIND_SUMMARY = "stab2d_summary"
|
||||
REPRESENTATIVE = Path("E03_StabSection") / "representative.json"
|
||||
SETTINGS = Path("E03_StabSection") / "settings.json"
|
||||
ENGINE_FILES = (
|
||||
"E03_StabSection_Types.py",
|
||||
"E03_StabSection_Engine_Model.py",
|
||||
@@ -91,6 +93,31 @@ class RepresentativeRequest(BaseModel):
|
||||
overrides: dict[str, bool | None]
|
||||
|
||||
|
||||
class AnalyzeRequest(BaseModel):
|
||||
#: 2D 탐색 한계 — "model_end" · "2h" · 수(비탈 끝 + m) · None = 지금 저장값 그대로
|
||||
search_reach: str | float | None = None
|
||||
|
||||
|
||||
def _clean_reach(value: Any) -> str | float:
|
||||
"""탐색 한계 값 검사 — 모르는 값은 기본."""
|
||||
if value in ("model_end", "2h"):
|
||||
return value
|
||||
try:
|
||||
reach = float(value)
|
||||
except (TypeError, ValueError):
|
||||
return SEARCH_REACH
|
||||
return reach if math.isfinite(reach) and reach > 0 else SEARCH_REACH
|
||||
|
||||
|
||||
def search_reach_of(root: Path) -> str | float:
|
||||
"""작업본 해석 설정의 탐색 한계 — 없으면 서버 기본(`SEARCH_REACH`)."""
|
||||
try:
|
||||
data = json.loads((root / SETTINGS).read_text(encoding="utf-8"))
|
||||
except (OSError, ValueError):
|
||||
return SEARCH_REACH
|
||||
return _clean_reach(data.get("search_reach"))
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def engine_hash() -> str:
|
||||
"""엔진 코드 지문 — 코드가 바뀌면 모든 측점을 다시 셈."""
|
||||
@@ -140,6 +167,9 @@ def plan_run(root: Path, ground: dict[str, Any]) -> dict[str, Any]:
|
||||
"road_surcharge_kpa": float(ground.get("road_surcharge_kpa") or 0.0),
|
||||
"groundwater": ground.get("groundwater"),
|
||||
}
|
||||
reach = search_reach_of(root)
|
||||
if reach != SEARCH_REACH:
|
||||
shared["search_reach"] = reach # 기본값이면 빼서 옛 지문 그대로
|
||||
resolved = {chainage_key(r["chainage_m"]): r for r in ground_model.resolve_stations(ground)}
|
||||
try:
|
||||
found = _walls(str(source), copy_fp)
|
||||
@@ -255,6 +285,7 @@ def run_all(root: Path, plan: dict[str, Any], report: Any) -> int:
|
||||
"conditions": list(shared["conditions"]),
|
||||
"seismic_kh": shared["seismic_kh"],
|
||||
"road_surcharge_kpa": shared["road_surcharge_kpa"],
|
||||
"search_reach": shared.get("search_reach", SEARCH_REACH),
|
||||
},
|
||||
"items": job_items,
|
||||
}
|
||||
@@ -314,9 +345,15 @@ def _overrides(root: Path) -> dict[str, bool]:
|
||||
|
||||
|
||||
@router.post("/{project_id}/stab/analyze2d", response_model=None)
|
||||
async def analyze2d(project_id: UUID) -> dict[str, Any]:
|
||||
"""전 측점 해석(뒤에서) — 지문이 같으면 다시 안 셈(`fresh`) · 진행은 `GET …/stab/progress`."""
|
||||
async def analyze2d(project_id: UUID, req: AnalyzeRequest | None = None) -> dict[str, Any]:
|
||||
"""전 측점 해석(뒤에서) — 지문이 같으면 다시 안 셈(`fresh`) · 진행은 `GET …/stab/progress`.
|
||||
|
||||
본문 `search_reach` 가 있으면 해석 설정에 저장한 뒤 그 값으로 셈."""
|
||||
root, _ = await e02._project(project_id)
|
||||
if req is not None and req.search_reach is not None:
|
||||
reach = _clean_reach(req.search_reach)
|
||||
if reach != search_reach_of(root):
|
||||
atomic_write_json(root / SETTINGS, {"search_reach": reach})
|
||||
plan = plan_run(root, _ground(root))
|
||||
if read_derived(root, KIND_SUMMARY, plan["fp"]):
|
||||
return {"status": "fresh", "fingerprint": plan["fp"]}
|
||||
@@ -375,6 +412,7 @@ async def result2d(
|
||||
"running": running,
|
||||
"conditions": plan["shared"]["conditions"],
|
||||
"factors": plan["factors"],
|
||||
"search_reach": plan["shared"].get("search_reach", SEARCH_REACH),
|
||||
"stations": rows,
|
||||
"missing_stations": missing,
|
||||
}
|
||||
@@ -387,6 +425,7 @@ async def result2d(
|
||||
"editable": editable,
|
||||
"running": running,
|
||||
**{k: v for k, v in summary.items() if k != "stations"},
|
||||
"search_reach": plan["shared"].get("search_reach", SEARCH_REACH),
|
||||
"stations": rows,
|
||||
"missing_stations": missing,
|
||||
}
|
||||
@@ -413,6 +452,7 @@ async def section(project_id: UUID, station_key: str) -> dict[str, Any]:
|
||||
"ground": [tuple(p) for p in value["inputs"]["ground"]],
|
||||
"road_surcharge_kpa": plan["shared"]["road_surcharge_kpa"],
|
||||
"walls": walls_mod.walls_of(entry),
|
||||
"search_reach": plan["shared"].get("search_reach", SEARCH_REACH),
|
||||
}
|
||||
dry = section_model_from_b06(cross, design, **kw)
|
||||
water, rules = {}, {}
|
||||
|
||||
Reference in New Issue
Block a user