Files
Aislo/resources/data_global_contours/convert_to_gpkg.py
T
eomsangdonandClaude Opus 5 4cb9b15939 style: 저장소 전체 포맷터 일괄 적용 (prettier·biome·ruff)
파일마다 포맷 폭이 달라(≈80 대 100) 한 줄만 고쳐도 포맷터가 무관한 줄을 대량
재포맷했음. 사용자 지시로 전체를 한 번에 맞춤. 코드 동작 변경 없음 — 포맷만.

- 프론트엔드 `.ts/.css/.html` → 저장소 prettier (`.prettierrc`, printWidth 100)
- `B07_DesignDetail/openwebcad/**` → 자체 biome (tab 들여쓰기·single quote·lineWidth 100).
  `biome format` 만 사용 — `biome lint --write` 는 포맷 아닌 코드 수정까지 하므로 제외
- 파이썬 → `ruff format` (엔진 코드는 이미 정합, resources·scratch 스크립트 24개만 변경)

두 포맷터가 서로 되돌리지 않도록 `.prettierignore` 신규 — openwebcad 와 빌드·산출물
폴더를 prettier 대상에서 뺌. `.prettierrc` 에 `endOfLine: "auto"` 추가 — 기본값 `lf` 가
`core.autocrlf=true` 로 받은 CRLF 파일을 매번 전부 다시 써서 `--list-different` 가
실제 포맷 차이를 가리고 있었음.

검증: `tsc --noEmit` 통과(루트·openwebcad 둘 다), pytest 349 passed / 17 skipped /
0 failed, CAD vitest 87건 중 81 passed / 6 failed(laptop-sub 기준선과 동일, 회귀 없음).
포맷터 재실행 시 prettier·biome 모두 변경 0건.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 07:08:24 +09:00

114 lines
4.5 KiB
Python

"""
국가 기본도 등고선 대용량 SHP 파일 세트를 고속 공간 인덱싱이 적용된 단일 GeoPackage(.gpkg)로 병합 변환하는 유틸리티.
[사전 필수 패키지 설치]
실행 전 가상환경(venv) 터미널에서 다음 라이브러리를 설치해 주세요:
pip install geopandas pyogrio
"""
import sys
from pathlib import Path
import time
try:
import geopandas as gpd
# fiona 대신 현재 설치된 고속 pyogrio 엔진을 검증 및 사용합니다.
import pyogrio
except ImportError:
print("[오류] 필수 라이브러리가 누락되었습니다.")
print("터미널에 다음 명령어를 입력하여 설치해 주세요:")
print(">>> pip install geopandas pyogrio")
sys.exit(1)
def convert_shp_to_gpkg():
current_dir = Path(__file__).resolve().parent
shp_files = sorted(list(current_dir.glob("TN_CTRLN*.shp")))
if not shp_files:
print(
f"[경고] {current_dir} 경로에서 'TN_CTRLN'으로 시작하는 .shp 파일을 찾을 수 없습니다."
)
return
gpkg_output_path = current_dir / "national_contours.gpkg"
print(f"-> 총 {len(shp_files)}개의 등고선 SHP 파일이 감지되었습니다.")
print(f"-> 변환 시작 (저장 경로: {gpkg_output_path})")
start_time = time.time()
# 첫 번째 파일 처리 (새 GeoPackage 파일 생성)
first_shp = shp_files[0]
print(f"\n[1/{len(shp_files)}] {first_shp.name} 읽는 중...")
try:
# GeoPandas를 이용해 shapefile 로드 (엔진으로 pyogrio 명시하여 고속 로드)
gdf = gpd.read_file(first_shp, encoding="cp949", engine="pyogrio")
# 속성 필드명 표준화 (소문자로 통일하고 cont_val / elev 필드가 있으면 elevation으로 통일)
gdf.columns = [col.lower() for col in gdf.columns]
for elev_col in ["cont_val", "elev_val", "elevation"]:
if elev_col in gdf.columns:
gdf["elevation"] = gdf[elev_col].astype(float)
break
# 필요한 필드만 최소한으로 남겨 용량 최소화
keep_cols = ["geometry", "elevation"] if "elevation" in gdf.columns else ["geometry"]
gdf = gdf[keep_cols]
# GeoPackage 파일로 쓰기 (고속 pyogrio 엔진 및 spatial_index 생성 활성화)
print(" -> GeoPackage 초기 생성 및 쓰기 중...")
gdf.to_file(
gpkg_output_path, layer="contours", driver="GPKG", spatial_index=True, engine="pyogrio"
)
print(f" -> 완료 (레코드 수: {len(gdf)}개)")
except Exception as e:
print(f" -> [에러] 첫 번째 파일 처리 중 오류 발생: {e}")
return
# 나머지 파일들을 루프를 돌며 기존 GeoPackage 레이어에 추가(Append)
for idx, shp_path in enumerate(shp_files[1:], start=2):
print(f"\n[{idx}/{len(shp_files)}] {shp_path.name} 읽는 중...")
try:
gdf_append = gpd.read_file(shp_path, encoding="cp949", engine="pyogrio")
# 컬럼 표준화
gdf_append.columns = [col.lower() for col in gdf_append.columns]
for elev_col in ["cont_val", "elev_val", "elevation"]:
if elev_col in gdf_append.columns:
gdf_append["elevation"] = gdf_append[elev_col].astype(float)
break
keep_cols = (
["geometry", "elevation"] if "elevation" in gdf_append.columns else ["geometry"]
)
gdf_append = gdf_append[keep_cols]
# 기존 gpkg 파일에 이어쓰기 (append mode, pyogrio 엔진 사용)
print(" -> GeoPackage에 데이터 이어붙이는 중...")
gdf_append.to_file(
gpkg_output_path,
layer="contours",
driver="GPKG",
mode="a",
spatial_index=True,
engine="pyogrio",
)
print(f" -> 완료 (레코드 수: {len(gdf_append)}개)")
except Exception as e:
print(f" -> [에러] {shp_path.name} 파일 처리 중 오류 발생: {e}. 계속 진행합니다.")
continue
end_time = time.time()
elapsed = end_time - start_time
print("\n==================================================")
print(f"★ 모든 등고선 변환이 완료되었습니다! (소요시간: {elapsed:.2f}초)")
print(f"★ 파일 위치: {gpkg_output_path}")
print("==================================================")
if __name__ == "__main__":
convert_shp_to_gpkg()