- 계획노선 사용 범위: B02 등록에 시작·종료 누가거리 두 칸 추가, B01 수정 모달에서도 변경. projects.route_start_m·route_end_m 신설(015_route_range.sql). load_design_route 가 범위 절단 → 서피스 트림 순서로 적용. 시작 >= 종료는 화면·서버 양쪽에서 차단. 비우면 전 구간으로 종전과 같음. - 서피스 절단 여유 기본값 30m → 3m (SURFACE_ROUTE_EDGE_TRIM_M). - B04 지도·B05 배수유역도 줌 상한을 「화면 폭 20m」 기준으로 계산(고정 8배·16배 폐지). 4배를 넘으면 배경 그림 흐림 보간 해제. - 계획선 위 측점 눈금·번호 표기(측점번호+잔여거리). 관 마커와 겹치면 반대쪽으로 밀고, 되꺾임 구간에서 라벨이 겹치면 건너뜀. 그리기 코드는 두 화면 공용. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
188 lines
11 KiB
Python
188 lines
11 KiB
Python
"""지형 분석·지표면 모델 생성 파라미터 (5장·5-2장).
|
|
|
|
`config_system.py` 가 700줄을 넘어 떼어냈다(2026-09-04). 값·이름은 그대로이고,
|
|
`config_system` 이 다시 내보내므로 기존 `from config.config_system import …` 는 불변이다.
|
|
"""
|
|
|
|
import os
|
|
|
|
# 5. 지형 분석 알고리즘 파라미터
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
# Trimesh 메쉬 생성
|
|
MESH_GRID_SIZE = float(os.getenv("MESH_GRID_SIZE", "1.0")) # 미터 단위
|
|
MESH_SMOOTHING_ITERATIONS = int(os.getenv("MESH_SMOOTHING_ITERATIONS", "0"))
|
|
SURFACE_LAS_CHUNK_SIZE = int(os.getenv("SURFACE_LAS_CHUNK_SIZE", "500000"))
|
|
SURFACE_DEFAULT_RGB_VALUE = int(os.getenv("SURFACE_DEFAULT_RGB_VALUE", "128"))
|
|
SURFACE_GRID_CELL_SIZE_M = float(os.getenv("SURFACE_GRID_CELL_SIZE_M", "2.0"))
|
|
SURFACE_GRID_HEIGHT_THRESHOLD_M = float(os.getenv("SURFACE_GRID_HEIGHT_THRESHOLD_M", "1.5"))
|
|
|
|
# CSF (Cloth Simulation Filter) 지면 분류 파라미터
|
|
SURFACE_CSF_CLOTH_RESOLUTION_M = float(os.getenv("SURFACE_CSF_CLOTH_RESOLUTION_M", "1.5"))
|
|
SURFACE_CSF_RIGIDNESS = int(os.getenv("SURFACE_CSF_RIGIDNESS", "1"))
|
|
SURFACE_CSF_TIME_STEP = float(os.getenv("SURFACE_CSF_TIME_STEP", "0.65"))
|
|
SURFACE_CSF_CLASS_THRESHOLD_M = float(os.getenv("SURFACE_CSF_CLASS_THRESHOLD_M", "0.5"))
|
|
# 낙하 후 스프링 정착에 쓰는 여유 반복 수 (실제 낙하 구간은 현장 기복에서 계산한다)
|
|
SURFACE_CSF_ITERATIONS = int(os.getenv("SURFACE_CSF_ITERATIONS", "150"))
|
|
# 낙하+정착 반복 상한 — 기복 1500m(0.3185m/회)까지 커버한다
|
|
SURFACE_CSF_MAX_ITERATIONS = int(os.getenv("SURFACE_CSF_MAX_ITERATIONS", "5000"))
|
|
SURFACE_CSF_SLOPE_SMOOTH = os.getenv("SURFACE_CSF_SLOPE_SMOOTH", "True").lower() == "true"
|
|
SURFACE_CSF_SLOPE_SMOOTH_THRESHOLD_M = float(
|
|
os.getenv("SURFACE_CSF_SLOPE_SMOOTH_THRESHOLD_M", "1.8")
|
|
)
|
|
|
|
# PMF (Progressive Morphological Filter) 지면 분류 파라미터
|
|
SURFACE_PMF_CELL_SIZE_M = float(os.getenv("SURFACE_PMF_CELL_SIZE_M", "2.0"))
|
|
SURFACE_PMF_MAX_WINDOW_SIZE = int(os.getenv("SURFACE_PMF_MAX_WINDOW_SIZE", "40"))
|
|
SURFACE_PMF_INITIAL_WINDOW_SIZE = int(os.getenv("SURFACE_PMF_INITIAL_WINDOW_SIZE", "3"))
|
|
SURFACE_PMF_SLOPE = float(os.getenv("SURFACE_PMF_SLOPE", "1.0"))
|
|
SURFACE_PMF_MAX_DISTANCE_M = float(os.getenv("SURFACE_PMF_MAX_DISTANCE_M", "2.5"))
|
|
|
|
# RANSAC (Local plane fitting) 지면 분류 파라미터
|
|
SURFACE_RANSAC_DISTANCE_THRESHOLD_M = float(os.getenv("SURFACE_RANSAC_DISTANCE_THRESHOLD_M", "0.3"))
|
|
SURFACE_RANSAC_N = int(os.getenv("SURFACE_RANSAC_N", "3"))
|
|
SURFACE_RANSAC_ITERATIONS = int(os.getenv("SURFACE_RANSAC_ITERATIONS", "100"))
|
|
SURFACE_RANSAC_LOCAL_GRID_SIZE_M = float(os.getenv("SURFACE_RANSAC_LOCAL_GRID_SIZE_M", "10.0"))
|
|
SURFACE_RANSAC_SEED = int(os.getenv("SURFACE_RANSAC_SEED", "42"))
|
|
|
|
# LAS 자체 지면분류(class 2) 필터 — 이 비율 이상 분류돼 있을 때만 필터로 제공한다.
|
|
# 미분류 LAS는 classification이 전부 0이라 마스크가 비어 버린다.
|
|
SURFACE_CLASSIFIED_GROUND_MIN_RATIO = float(
|
|
os.getenv("SURFACE_CLASSIFIED_GROUND_MIN_RATIO", "0.002")
|
|
)
|
|
# 지면점 비율이 이 값 미만이면 필터가 사실상 실패한 것으로 보고 WARNING을 남긴다.
|
|
SURFACE_GROUND_RATIO_WARN = float(os.getenv("SURFACE_GROUND_RATIO_WARN", "0.01"))
|
|
|
|
# 계획노선이 지표면 밖으로 나가 잘릴 때, 잘린 쪽 끝에서 더 깎을 길이(m).
|
|
# 서피스 가장자리는 점 밀도가 떨어져 외곽선이 불규칙하다 — 경계에 딱 붙여 자르면
|
|
# 그 구간 지반고가 못 미덥다 (2026-09-01 사용자 확정).
|
|
# 30m 는 너무 많이 깎는다는 지적으로 3m 로 낮춤 (2026-09-04 사용자 지시).
|
|
SURFACE_ROUTE_EDGE_TRIM_M = float(os.getenv("SURFACE_ROUTE_EDGE_TRIM_M", "3.0"))
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
# 5-2. 지표면 모델 생성 파라미터 (TIN/DTM/NURBS/implicit/meshfree)
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
# 고를 수 있는 지면 필터 전체 — 관리자가 B04 드롭다운에서 요청할 때 쓰인다.
|
|
# 자동 전처리가 미리 만드는 조합이 아니다(그건 SURFACE_AUTO_* 가 정한다).
|
|
SURFACE_MODEL_SOURCE_FILTERS = tuple(
|
|
os.getenv("SURFACE_MODEL_SOURCE_FILTERS", "classification,grid_min_z,csf,pmf").split(",")
|
|
)
|
|
# 자동 전처리가 만드는 조합 — 기본 필터 1종 × 아래 표현. 나머지는 관리자 요청 시 만든다.
|
|
SURFACE_AUTO_METHODS = tuple(os.getenv("SURFACE_AUTO_METHODS", "dtm").split(","))
|
|
# 기본 필터는 입력 LAS를 보고 정한다 — 지면분류(class 2)가 있으면 그것을, 없으면 아래 값.
|
|
SURFACE_AUTO_FALLBACK_FILTER = os.getenv("SURFACE_AUTO_FALLBACK_FILTER", "csf")
|
|
# dtm을 먼저 빌드해야 TIN 등고선 사전 캐시가 dtm footprint를 참조할 수 있다 (PLAN D-6)
|
|
SURFACE_MODEL_PRECOMPUTE = tuple(
|
|
os.getenv("SURFACE_MODEL_PRECOMPUTE", "dtm,tin,nurbs,implicit,meshfree").split(",")
|
|
)
|
|
SURFACE_MODEL_SMOOTHING_METHODS = tuple(
|
|
os.getenv("SURFACE_MODEL_SMOOTHING_METHODS", "dtm,tin").split(",")
|
|
)
|
|
SURFACE_MODEL_SYNC_TIMEOUT_SECONDS = int(os.getenv("SURFACE_MODEL_SYNC_TIMEOUT_SECONDS", "0"))
|
|
|
|
# footprint(외곽) 산출
|
|
SURFACE_FOOTPRINT_RESOLUTION_M = float(os.getenv("SURFACE_FOOTPRINT_RESOLUTION_M", "1.0"))
|
|
SURFACE_FOOTPRINT_GAP_CLOSE_M = float(os.getenv("SURFACE_FOOTPRINT_GAP_CLOSE_M", "1.0"))
|
|
SURFACE_BOUNDARY_INSET_M = float(os.getenv("SURFACE_BOUNDARY_INSET_M", "1.0"))
|
|
SURFACE_KEEP_LARGEST_FOOTPRINT = (
|
|
os.getenv("SURFACE_KEEP_LARGEST_FOOTPRINT", "True").lower() == "true"
|
|
)
|
|
SURFACE_TILE_SIZE_M = float(os.getenv("SURFACE_TILE_SIZE_M", "50.0"))
|
|
SURFACE_MAX_PREVIEW_VERTICES = int(os.getenv("SURFACE_MAX_PREVIEW_VERTICES", "500000"))
|
|
|
|
# 표현별 파라미터 (old 버전 검증값 기준 — PLAN F)
|
|
SURFACE_TIN_MAX_INPUT_POINTS = int(os.getenv("SURFACE_TIN_MAX_INPUT_POINTS", "500000"))
|
|
SURFACE_DTM_GRID_RESOLUTION_M = float(os.getenv("SURFACE_DTM_GRID_RESOLUTION_M", "1.0"))
|
|
SURFACE_NURBS_DEGREE = int(os.getenv("SURFACE_NURBS_DEGREE", "3"))
|
|
SURFACE_NURBS_PATCH_SIZE_M = float(os.getenv("SURFACE_NURBS_PATCH_SIZE_M", "50.0"))
|
|
SURFACE_NURBS_CONTROL_POINTS_PER_AXIS = int(
|
|
os.getenv("SURFACE_NURBS_CONTROL_POINTS_PER_AXIS", "16")
|
|
)
|
|
SURFACE_IMPLICIT_MAX_POINTS_PER_TILE = int(
|
|
os.getenv("SURFACE_IMPLICIT_MAX_POINTS_PER_TILE", "10000")
|
|
)
|
|
SURFACE_IMPLICIT_SMOOTHING = float(os.getenv("SURFACE_IMPLICIT_SMOOTHING", "0.1"))
|
|
SURFACE_MESHFREE_MAX_MODEL_POINTS = int(os.getenv("SURFACE_MESHFREE_MAX_MODEL_POINTS", "500000"))
|
|
SURFACE_MESHFREE_POINT_RADIUS_M = float(os.getenv("SURFACE_MESHFREE_POINT_RADIUS_M", "0.15"))
|
|
|
|
# 스무딩 파라미터
|
|
SURFACE_SMOOTHING_DTM_SIGMA_M = float(os.getenv("SURFACE_SMOOTHING_DTM_SIGMA_M", "0.5"))
|
|
SURFACE_SMOOTHING_DTM_SPLINE_SMOOTH = float(os.getenv("SURFACE_SMOOTHING_DTM_SPLINE_SMOOTH", "0.0"))
|
|
SURFACE_SMOOTHING_DTM_PREVIEW_RESOLUTION_M = float(
|
|
os.getenv("SURFACE_SMOOTHING_DTM_PREVIEW_RESOLUTION_M", "0.5")
|
|
)
|
|
SURFACE_SMOOTHING_TIN_TAUBIN_ITERATIONS = int(
|
|
os.getenv("SURFACE_SMOOTHING_TIN_TAUBIN_ITERATIONS", "10")
|
|
)
|
|
SURFACE_SMOOTHING_TIN_TAUBIN_LAMBDA = float(os.getenv("SURFACE_SMOOTHING_TIN_TAUBIN_LAMBDA", "0.5"))
|
|
SURFACE_SMOOTHING_TIN_TAUBIN_MU = float(os.getenv("SURFACE_SMOOTHING_TIN_TAUBIN_MU", "-0.53"))
|
|
|
|
# 등고선 파라미터
|
|
SURFACE_CONTOUR_INTERVAL_M = float(os.getenv("SURFACE_CONTOUR_INTERVAL_M", "1.0"))
|
|
SURFACE_CONTOUR_GRID_RESOLUTION_M = float(os.getenv("SURFACE_CONTOUR_GRID_RESOLUTION_M", "1.0"))
|
|
|
|
# 도엽등고선 3D 서피스 (LAS 없는 설계 — 2026-08-30 사용자 확정)
|
|
# 노선 XY bbox에 더하는 절취 여유(m). 300m = 횡단·코리도·성토면 여유(사용자 확정값).
|
|
SHEET_SURFACE_MARGIN_M = float(os.getenv("SHEET_SURFACE_MARGIN_M", "300.0"))
|
|
# 도엽등고선 DTM 격자 한 변(m). LAS DTM·등고선 캐시와 같은 1m(사용자 확정값).
|
|
SHEET_SURFACE_GRID_M = float(os.getenv("SHEET_SURFACE_GRID_M", "1.0"))
|
|
# 만들어 둘 등고선 보간 방식 — B04 화면에서 버튼으로 바꿔 가며 비교한다
|
|
# (2026-08-30 사용자 지시). 정의는 B04_PreProcess_Engine_SheetMethods.py.
|
|
SHEET_SURFACE_METHODS = [
|
|
method.strip()
|
|
for method in os.getenv(
|
|
"SHEET_SURFACE_METHODS",
|
|
"tin_sheet,tin,biharmonic,anudem,multires,laplace",
|
|
).split(",")
|
|
if method.strip()
|
|
]
|
|
# 확정에 쓸 기본 방식 — 라플라스 (2026-08-30 사용자 확정).
|
|
SHEET_SURFACE_DEFAULT_METHOD = os.getenv("SHEET_SURFACE_DEFAULT_METHOD", "laplace")
|
|
# 자동 전처리가 만드는 도엽 방식 — 기본 하나뿐이다. 여섯 방식을 매번 다 만들면
|
|
# WF1의 대부분(용화 실측 891초 중 655초)을 여기서 쓴다. 나머지는 관리자가 B04에서
|
|
# 그 방식을 고를 때 만든다 (2026-09-01 사용자 확정).
|
|
SHEET_SURFACE_AUTO_METHODS = [
|
|
method.strip()
|
|
for method in os.getenv("SHEET_SURFACE_AUTO_METHODS", SHEET_SURFACE_DEFAULT_METHOD).split(",")
|
|
if method.strip()
|
|
]
|
|
|
|
# 일반 사용자 WF1 자동 확정 기본값
|
|
SURFACE_CONFIRM_DEFAULT_FILTER = os.getenv("SURFACE_CONFIRM_DEFAULT_FILTER", "csf")
|
|
SURFACE_CONFIRM_DEFAULT_METHOD = os.getenv("SURFACE_CONFIRM_DEFAULT_METHOD", "dtm")
|
|
SURFACE_CONFIRM_DEFAULT_SMOOTH = (
|
|
os.getenv("SURFACE_CONFIRM_DEFAULT_SMOOTH", "True").lower() == "true"
|
|
)
|
|
|
|
|
|
def build_surface_model_config() -> dict:
|
|
"""지표면 모델 파이프라인이 사용하는 config dict를 조립한다."""
|
|
return {
|
|
"source_filters": list(SURFACE_MODEL_SOURCE_FILTERS),
|
|
"precompute": list(SURFACE_MODEL_PRECOMPUTE),
|
|
"smoothing_methods": tuple(SURFACE_MODEL_SMOOTHING_METHODS),
|
|
"sync_timeout_seconds": SURFACE_MODEL_SYNC_TIMEOUT_SECONDS,
|
|
"footprint_resolution_meters": SURFACE_FOOTPRINT_RESOLUTION_M,
|
|
"footprint_gap_close_meters": SURFACE_FOOTPRINT_GAP_CLOSE_M,
|
|
"boundary_inset_meters": SURFACE_BOUNDARY_INSET_M,
|
|
"keep_largest_footprint": SURFACE_KEEP_LARGEST_FOOTPRINT,
|
|
"tile_size_meters": SURFACE_TILE_SIZE_M,
|
|
"max_preview_vertices": SURFACE_MAX_PREVIEW_VERTICES,
|
|
"tin_max_input_points": SURFACE_TIN_MAX_INPUT_POINTS,
|
|
"dtm_grid_resolution_meters": SURFACE_DTM_GRID_RESOLUTION_M,
|
|
"nurbs_degree": SURFACE_NURBS_DEGREE,
|
|
"nurbs_patch_size_meters": SURFACE_NURBS_PATCH_SIZE_M,
|
|
"nurbs_control_points_per_axis": SURFACE_NURBS_CONTROL_POINTS_PER_AXIS,
|
|
"implicit_max_points_per_tile": SURFACE_IMPLICIT_MAX_POINTS_PER_TILE,
|
|
"implicit_smoothing": SURFACE_IMPLICIT_SMOOTHING,
|
|
"meshfree_max_model_points": SURFACE_MESHFREE_MAX_MODEL_POINTS,
|
|
"meshfree_point_radius_meters": SURFACE_MESHFREE_POINT_RADIUS_M,
|
|
"smoothing_dtm_sigma_meters": SURFACE_SMOOTHING_DTM_SIGMA_M,
|
|
"smoothing_dtm_spline_smooth": SURFACE_SMOOTHING_DTM_SPLINE_SMOOTH,
|
|
"smoothing_dtm_preview_resolution_meters": SURFACE_SMOOTHING_DTM_PREVIEW_RESOLUTION_M,
|
|
"smoothing_tin_taubin_iterations": SURFACE_SMOOTHING_TIN_TAUBIN_ITERATIONS,
|
|
"smoothing_tin_taubin_lambda": SURFACE_SMOOTHING_TIN_TAUBIN_LAMBDA,
|
|
"smoothing_tin_taubin_mu": SURFACE_SMOOTHING_TIN_TAUBIN_MU,
|
|
"contour_interval_meters": SURFACE_CONTOUR_INTERVAL_M,
|
|
"contour_grid_resolution_meters": SURFACE_CONTOUR_GRID_RESOLUTION_M,
|
|
}
|