"""cst_tp_cd(해안 구성) → ESI 등급 매핑. ESI(Environmental Sensitivity Index) 등급은 해안의 물리적 특성에 따라 분류된다. 매핑 기준: NOAA(2010) + 성 등(2003) ESI 등급 표. """ from __future__ import annotations import re from typing import Optional, Tuple # 키워드 → (esi_cd, esi_num) 매핑 (구체적 키워드 우선) _ESI_RULES: list[tuple[list[str], str, int]] = [ # 8B: 습지 (['염습지', '습지'], '8B', 8), # 8A: 갯벌/점토질 (['갯벌', '점토질', '점토'], '8A', 8), # 7: 반폐쇄형 (['반폐쇄', '반 폐쇄'], '7', 7), # 6B: 투과성 인공호안/사석 (['투과성 인공호안', '투과성 사석', '투과성 인공해안', '투과성 경사식'], '6B', 6), # 6A: 자갈/바위 (['자갈', '왕자갈', '바위', '갈('], '6A', 6), # 5: 모래+자갈 혼합 (['모래자갈', '모래+자갈', '혼합'], '5', 5), # 4: 굵은 모래 (['굵은 모래', '조립질 모래'], '4', 4), # 3: 세립질 모래/모래(기본) (['세립질 모래', '세립질', '모래'], '3', 3), # 2: 수평암반/비투과성 (['수평암반', '수평호안', '기반암', '비투과성 기질', '비투과성 인공호안', '비투과성 인공해안', '노출기반암', '수암반', '콘크리트'], '2', 2), # 1: 수직암반/인공구조물/계류안벽 (['수직암반', '인공구조물', '직립호안', '절벽', '수직호안', '수진호안', '수직 계류', '인공호안', '계류 안벽', '안벽'], '1', 1), ] # ESI 코드 → 숫자 변환 _ESI_NUM_RE = re.compile(r'^(\d+)') def map_esi(cst_tp_cd: Optional[str]) -> Tuple[Optional[str], Optional[int]]: """cst_tp_cd(해안 구성 키워드)에서 ESI 등급을 매핑한다. Returns: (esi_cd, esi_num) 튜플. 매핑 실패 시 (None, None). """ if not cst_tp_cd: return None, None text = cst_tp_cd.strip() for keywords, esi_cd, esi_num in _ESI_RULES: for kw in keywords: if kw in text: return esi_cd, esi_num return None, None def parse_esi_cd(esi_str: str) -> Tuple[str, int]: """ESI 등급 문자열(e.g. '8A', '6B', '2')에서 (esi_cd, esi_num) 추출.""" esi_cd = esi_str.strip() m = _ESI_NUM_RE.match(esi_cd) esi_num = int(m.group(1)) if m else 0 return esi_cd, esi_num