Merge remote-tracking branch 'origin/sub_laptop_5' into main_laptop_1

This commit is contained in:
2026-11-01 11:54:21 +09:00
9 changed files with 409 additions and 104 deletions
+59 -3
View File
@@ -4,9 +4,12 @@
(좌표계 다르면 x · y 옮겨 적음)
- 받기 고리 `receive_uploads` · 입력 자리 갈음 `stage_las` · 짓기 `build_surface`
(B04 엔진 `run_surface_analysis(maps=False)` — 지도 · GIS 받기 · 도엽 서피스 안 함)
- 갈음 뒤 안 지은 라이다 필터 지움 `drop_stale_filters`
(옛 LAS 산출 · 뒤에 고르면 새 LAS 로 다시 지음)
- 뒤 일 `start_job` · 진행 기록 `note_job` · `saved_job`(서버 다시 켜짐 = 「끊김」)
- DB `save_models` — `surface_models` 넣기/고치기만
(다른 행 안 지움 · `save_surface_analysis_to_db` 안 씀)
(다른 행 안 지움 · `drop` = 지운 필터 파일 행만 · 확정 행 남김 ·
`save_surface_analysis_to_db` 안 씀)
부르는 쪽 = `D03_PlanAnalysis_Lidar`(자리 `B04_PreProcess/lidar/`) ·
`B05_Profile_Router_Lidar`(프로젝트 뿌리).
@@ -143,6 +146,45 @@ def build_surface(
)
def drop_stale_filters(base: Path, built: list[str]) -> list[str]:
"""갈음 뒤 — 이번에 안 지은 라이다 필터의 옛 LAS 산출(모델 · 미리보기 · 등고선 · 마스크 ·
지면점 · 점 미리보기 · manifest 줄)을 지움 → 지운 모델 파일(`base` 기준 상대경로).
B04 엔진은 LAS 가 바뀌면 고른 필터만 다시 지음 — 남은 다른 필터 파일은 옛 LAS 것.
지우면 뒤에 그 필터를 고를 때 캐시가 없어 새 LAS 로 다시 지음.
수치지형도(`sheet_*`)는 필터 밖."""
from B04_PreProcess.B04_PreProcess_Engine_Ground import available_filters
from B04_PreProcess.B04_PreProcess_Engine_ModelBuild import BUILDERS
models = base / "B04_PreProcess" / "models"
processed = base / "B04_PreProcess" / "processed"
stale = [key for key in available_filters() if key not in built]
gone: list[str] = []
for key in stale:
paths = [
*(path for method in BUILDERS for path in models.glob(f"{method}_{key}.*")),
*(path for method in BUILDERS for path in models.glob(f"{method}_{key}_*")),
*models.glob(f"contour_{key}_*"),
*(processed / name for name in (f"mask_{key}.npy", f"ground_points_{key}.npz")),
processed / f"preview_points_{key}.bin",
]
for path in paths:
if path.is_file():
path.unlink()
if path.parent == models and path.suffix == ".npz":
gone.append(path.relative_to(base).as_posix())
manifest = models / "manifest.json"
try:
data = json.loads(manifest.read_text(encoding="utf-8"))
except (OSError, ValueError):
data = None
filters = data.get("source_filters") if isinstance(data, dict) else None
if isinstance(filters, dict) and any(key in filters for key in stale):
data["source_filters"] = {k: v for k, v in filters.items() if k not in stale}
atomic_write_json(manifest, data)
return sorted(gone)
# ── 뒤 일 · 진행 기록 ─────────────────────────────────────────────────────────
IDLE = {"running": False, "percent": 100, "message": None, "error": None, "interrupted": False}
@@ -214,12 +256,19 @@ def start_job(
async def save_models(
project_id: UUID, models: list[dict[str, Any]], epsg: int, *, keep: bool = False
project_id: UUID,
models: list[dict[str, Any]],
epsg: int,
*,
keep: bool = False,
drop: list[str] | None = None,
) -> None:
"""지형면 → `surface_models` 행(같은 파일 · 같은 지문이면 id 살림 · 다른 행 그대로).
`keep` = 같은 파일을 가리키는 옛 행은 지문이 달라도 id · 상태(확정) · 입력 연결을 살림
(LAS 갈음 — 노선 `surface_model_id` · 설계 확정이 끊기지 않게 · B05)."""
(LAS 갈음 — 노선 `surface_model_id` · 설계 확정이 끊기지 않게 · B05).
`drop` = 지운 모델 파일(`drop_stale_filters`)을 가리키는 행 지움(확정 행은 남김 ·
terrain_layers CASCADE · routes SET NULL)."""
from B04_PreProcess.B04_PreProcess_Repository import (
_existing_models,
_model_key,
@@ -259,6 +308,13 @@ async def save_models(
)
if status == "CONFIRMED": # 고쳐 쓰기가 COMPLETE 로 내린 확정을 되살림
await confirm_surface_model(connection, project_id, model_id)
if drop:
async with connection.cursor() as cursor:
await cursor.execute(
"DELETE FROM surface_models WHERE project_id = %s AND status <> 'CONFIRMED'"
" AND model_file_path IN (" + ", ".join(["%s"] * len(drop)) + ")",
(str(project_id), *drop),
)
await connection.commit()
except Exception:
await connection.rollback()