Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SPipe
프로젝트 개요
웹 브라우저에서 쓰는 상수도 관망 수리해석·관리 플랫폼. EPANET 2.3.5 엔진으로 관망을 해석하고, GIS·DEM·자산 정보를 한 화면에서 함께 다룬다.
주요 기능:
- EPANET INP 관망 불러오기·편집·해석 (Native DLL과 WASM 두 엔진 교차 검증)
- 지도 기반 관망 편집 (절점·관로·밸브·펌프, 꺾임점, 분할·병합)
- 해석 결과 지도·그래프·종단·보고서, 실측 보정
- 분석 도구: 소화전 모의, 관로 중요도, 급수 구역, VSP, 등치선, 에너지 비용, 자동 보정, 펌프 운전 최적화
- GIS 연동: SHP·DXF·DGN·MIF·GML·KML·GPKG 불러오기·내보내기, 좌표계 변환, 도형 연산
- DEM 기반 절점 표고 입력·검증, 유역·하천 분석, 등고선, 3D 보기
- 도면 출력: 수리 종단면도, 관망도(색인도 + 부분도, 절점 수압표) → PDF·DXF(AutoCAD 2018)·SVG
- 프로젝트 파일(.spipe), 시나리오, 자동 백업
웹 기반으로 만드는 이유
기존 운영 방식
설치형 관망해석 프로그램(EPANET 등)을 PC마다 설치하고, 관망 파일·GIS 자료·DEM·엑셀 자료를 파일 단위로 주고받으며 작업하는 구조.
기존 문제
- PC마다 프로그램 설치·버전 관리 필요
- 관망 INP, GIS 레이어, 표고 자료, 자산 대장이 서로 다른 프로그램·파일에 분산
- 같은 관망을 여러 사람이 볼 때 파일 사본이 늘어나고 최신본 확인이 어려움
- 수리해석 결과를 지도·자산 정보와 함께 보려면 여러 프로그램을 오가야 함
웹 기반 통합의 필요성
사내망 서버 한 곳에 해석 엔진과 GIS 처리를 두고, 사용자는 브라우저로 접속해 같은 기능을 쓴다. 관망 모델(INP)을 기준으로 GIS·DEM·자산 정보를 연결해 하나의 작업 흐름으로 관리한다.
기대 효과
- 설치 없이 브라우저 접속만으로 사용
- 관망·지도·표고·자산 정보를 한 화면에서 확인
- 해석 결과를 두 엔진으로 교차 검증해 신뢰도 확보
- 분석 결과를 표준 형식(INP, SHP, GPKG, CSV)으로 내보내 기존 업무와 연계
핵심 용어
| 용어 | 의미 |
|---|---|
| INP | EPANET 관망 입력 파일. SPipe 관망 모델의 원본 형식 |
| 절점 / 링크 | 접합점·배수지·탱크(절점)와 관로·펌프·밸브(링크) |
| EPS | 연장 기간 해석. 시간대별 수요 패턴에 따라 여러 시점을 해석 |
| Native / WASM 엔진 | 서버의 EPANET DLL과 브라우저의 epanet-js. 같은 관망을 둘 다 해석해 결과를 비교 |
| 시나리오 | 원본 관망에서 갈라져 나온 대안 관망 |
| 자산 속성 | INP에 없는 관재질·설치년도·매설깊이·소블록 등 관리 정보 |
| DEM | 수치표고모델. 절점 표고 입력과 유역 분석에 사용 |
| 일괄 해석(Job) | 관로 중요도·소화전 모의처럼 해석을 여러 번 반복하는 서버 작업 |
| .spipe | 관망·시나리오·GIS 레이어·스타일·보정 자료를 묶은 프로젝트 파일 |
처리 흐름
INP 불러오기 또는 GIS 레이어로 관망 만들기
↓
지도에서 관망 편집 · 자산 속성 · DEM 표고 입력
↓
수리해석 (Native DLL + WASM 동시 실행, 결과 비교)
↓
결과 확인 (지도 · 그래프 · 종단 · 보고서 · 실측 보정)
↓
분석 도구로 검토 (중요도 · 급수 구역 · 소화전 · 최적화 ...)
↓
도면 출력 (수리 종단면도 · 관망도 → PDF · DXF · SVG)
↓
INP · SHP · 엑셀 · .spipe 로 저장·공유
핵심 원칙:
- 관망 모델의 원본은 INP 구조이며, 편집은 모두 INP로 다시 생성 가능한 형태로 저장
- INP에 없는 정보(자산 속성, 화면 설정)는 별도 저장소에 두고 요소 ID로만 연결
- 해석 결과는 엔진 출력이 원본이며, 화면은 단위 변환만 수행
- 모든 편집은 실행 취소(Ctrl+Z) 가능
이 문서는 저장소의 시작점입니다. 상세 설계와 점검 기록은 별도 문서에 두고, 여기에는 실행·검증·배포 순서와 문서 선택 기준을 정리합니다.
1. 빠른 시작
로컬 실행 (Windows)
필요 조건:
- Node.js 24.x (검증 버전 24.14.1)
- Python 3.12 64비트
- EPANET 2.3.5 (
64bit/epanet2.dll포함)
npm install
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r backend\requirements.txt pytest httpx
가장 간단한 실행 방법은 start-spipe.bat 더블클릭입니다. 해석 API(8000)와 웹 개발 서버(5173)를 함께 띄우고 브라우저를 엽니다. 종료는 stop-spipe.bat.
수동 실행:
npm run api
npm run dev
접속 주소:
- Web: http://127.0.0.1:5173
- 해석 API: http://127.0.0.1:8000
- API 상태 확인: http://127.0.0.1:8000/api/health
지도 서비스 키 설정 (.env.example을 .env.local로 복사해 값 입력. 없으면 배경지도·주소 검색만 동작하지 않음):
Copy-Item .env.example .env.local
개발 서버는 127.0.0.1에만 바인딩됩니다. 사내망에 공개할 때는 아래 "8. 사내 서버 배포"를 따릅니다.
로컬 검증
npm run typecheck
npm test
npm run test:api
npm run build
npm test: 모델·단위·비교 로직, 편집·분석 도구 회귀 테스트 (Node 테스트)npm run test:api: FastAPI·EPANET DLL·GIS·DEM 테스트 (pytest)
CI는 .github/workflows/ci.yml (windows-latest).
2. 서비스 구조
브라우저
│
▼
Web (React + Vite) 지도·편집·결과 화면, WASM 해석(Web Worker)
│ /api 프록시
▼
해석 API (FastAPI) EPANET DLL(ctypes) 해석, 일괄 해석, GIS·DEM 처리
├─▶ 64bit/epanet2.dll EPANET 2.3.5 엔진 (프로세스 풀)
├─▶ GDAL (pyogrio, rasterio) 벡터·래스터 입출력
└─▶ data/dem 업로드한 DEM 보관
외부 연동(브라우저에서 직접 호출): 브이월드 배경지도 · 카카오 주소 검색 · Open-Meteo 표고(90m) · OpenStreetMap 건물
| 구성요소 | 책임 | 기본 포트 |
|---|---|---|
src/ Web |
관망 편집, 결과 표시, WASM 해석, 엔진 결과 비교 | 5173 개발 / 8080 사내 |
backend/ 해석 API |
해석, 일괄 분석 Job, GIS 변환·연산, DEM | 8000 (내부 전용) |
64bit/epanet2.dll |
EPANET 2.3.5 엔진 | - |
data/dem/ |
서버 DEM 보관 (최근 8개) | - |
3. 데이터와 원본 원칙
관망의 원본은 INP 구조입니다. 화면 편집은 내부 모델(src/inpModel.ts)을 바꾸고, 해석·저장 시 항상 INP로 다시 생성합니다.
INP로 저장되는 것:
- 절점·관로·펌프·밸브, 패턴·곡선·컨트롤·규칙, 해석 옵션
- 다중 수요, 이미터, 수질·수원, 탱크 혼합, 에너지, 초기 상태, 반응 계수, 지도 라벨
- 관로 꺾임점(
[VERTICES]) — 이름 변경·삭제·분할·방향 전환을 따라감
INP 밖에 별도로 두는 것:
- 자산 속성(관재질·설치년도·매설깊이·소블록 등): 요소 ID로 연결,
.spipe에 함께 저장 - 화면 설정(레이어 스타일·범례·라벨):
.spipe에 저장 - DEM 원본: 서버
data/dem에 보관, 브라우저에는 식별자만 보관
원칙:
- 해석 결과는 엔진 출력을 그대로 쓰고, 화면은 표시 단위 변환만 수행
- 재생성한 INP가 원본 INP와 같은 해석 결과를 내는지 회귀 테스트로 확인
- 실무 관망 원본 파일(INP)은 저장소에 커밋하지 않음
4. 해석 흐름
- 사용자가 해석 실행을 누르면 현재 모델로 INP를 생성합니다.
- 같은 INP를 서버(Native DLL)와 브라우저(WASM)에서 동시에 해석합니다.
- 두 결과를 시간대별·요소별로 비교해 허용오차 안에서 일치하는지 표시합니다 (
src/comparisonEngine.ts). - EPANET 경고 코드(1~6)와 비정상 압력을 별도로 점검해 표시합니다 (
src/convergence.ts). - 분석 탭의 일괄 해석(관로 중요도, 소화전, 보정 등)은 서버 Job으로 실행합니다 (
backend/jobs.py).
관련 구현 위치:
- INP 파싱·생성:
src/inpModel.ts,src/inpExtras.ts - 서버 해석:
backend/main.py,backend/epanet.py - 일괄 해석 프레임워크:
backend/batch.py,backend/jobs.py - WASM 해석:
src/worker.ts
5. 주요 기능 사용 가이드
관망 편집
상단 [편집] 모드에서 절점·관로를 추가하고 지도에서 끌어 옮깁니다. 관로를 선택하면 꺾임점 핸들이 나타나며, 주황 점을 끌면 이동, 흰 점을 끌면 추가, 더블클릭하면 삭제됩니다. 속성창 아래 "추가 속성"에서 다중 수요·이미터·수질·탱크 혼합·펌프 에너지를 편집합니다.
결과 확인
[결과] 창에서 표·시계열·누적 빈도·종단(시간별)·실측 보정을 확인합니다. 표의 행을 누르면 지도가 해당 요소로 이동합니다.
분석 탭
| 분석 | 내용 |
|---|---|
| 소화전 모의 | 시간대별 소화 유량 추가 해석, 확보 가능 유량 |
| 관로 중요도 | 관로를 하나씩 닫아 영향 절점·수요 순위 |
| 급수 구역 | 배수지별 공급 비율 추적 |
| 흐름 방향 | 역류·무흐름 관로 |
| VSP | 목표 압력용 시간별 펌프 회전수 |
| 등치선 | 압력·동수두·표고 등치선 |
| 에너지 비용 | 펌프별 가동률·효율·원단위·전력비 |
| 관로 통계 | 관경·재질·설치 연대별 집계 |
| 자동 보정 (시험) | 실측값으로 그룹별 C값 배율·관벽 계수 추정 |
| 펌프 운전 최적화 (시험) | 압력·탱크 조건을 지키는 저비용 운전 일정 |
| 편집 도구 | 이동·회전·2점 보정, 분할, 절점 병합, 관로 점검, 추적 |
| 지형(DEM) | DEM 표고 입력·검증, 인터넷 90m 표고, TIN, 유역·하천, 3D |
| GIS 도구 | 레이어 좌표계·내보내기, 도형 연산, 밸브·계량기·소블록 반영 |
도면 출력
상단 [내보내기] > [도면 출력](종단면도는 결과 창 [시간별 종단] > [도면 출력]으로도 열림)에서 실무 도면 양식으로 내보냅니다. 표제란(발주처·개정란·설계사·사업명·도면명·설계/제도/검토/승인·축척·작성일·도면번호)에 넣을 내용은 창에서 입력하며 다음에도 기억합니다.
| 도면 | 내용 |
|---|---|
| 수리 종단면도 | 두 절점 사이 경로의 지반선·관저고·동수경사선(선택 시점·최대)·배수지 H.W.L, 경로 위 실제 밸브·펌프와 설정값. 하단 표: 측점·절점번호·거리·추가거리·지반고·관저고·동수두·수압(기준 미만 붉은 글씨)·관경·연장 |
| 관망도 (한 장) | 관망 전체를 용지 한 장에. 유속·수압 판정색 또는 관경색, 좌표 격자, 방위표, 축척 막대, 켜진 GIS 레이어 배경 |
| 관망도 (색인도 + 부분도) | A3 격자로 자동 분할(이웃 도면 6% 겹침, 관이 지나는 칸만). 색인도 1장 + 부분도 N장, 부분도마다 위치도와 상하좌우·대각선 접속도면 표시. 도면 번호는 일련번호(01, 02 …) 또는 격자(A-1, B-2 …) |
- 부분도 축척: 자동(절점 간격에 맞춤) 또는 1:500~1:10,000 직접 선택
- 수압표: 절점마다 원 안에 동수두/지반고, 옆에 수압(kg/cm² 또는 m)과 유출량. 해석 결과가 있어야 그려지며, 자리가 없는 수압표는 생략하고 개수를 안내 (축척을 키우면 더 표시)
- 관로 표기: 관경 / 관경+연장 / 관번호+관경+연장
- 범례: 표형(서울시 배관망도식) / 간단형 / 표시 안 함, 제목 띠 색 선택
- 색상 구성: 기본 / CAD 기본색 / 색약 배려(Okabe-Ito) / 흑백 인쇄용, 등급별 색 직접 지정
- 글꼴: HY울릉도M(기본) 또는 맑은 고딕. HY울릉도M은 유료 글꼴이라 저장소에 넣지 않으며, 없는 PC에서는 맑은 고딕(PDF)·CAD 대체 글꼴로 표시
- 저장 형식
| 형식 | 내용 |
|---|---|
| 인쇄 창에서 "PDF로 저장". 분할 출력은 전 장이 한 파일 | |
| DXF | 해석 API(/api/drawing/dxf, ezdxf)가 AutoCAD 2018 형식으로 생성. mm 단위, 도면층·선 굵기·색 구분, 한글 UTF-8. 분할 출력은 전 장을 모형 공간에 옆으로 나란히. API에 연결할 수 없으면 간이 R12 DXF로 저장 |
| SVG | 보고 있는 장만 |
관련 구현 위치: 도면 모델·표제란·범례 src/drawing.ts, 종단면도 src/profileDrawing.ts, 관망도·자동 분할 src/networkDrawing.ts, 모델→도면 자료 src/drawingData.ts, 출력 창 src/DrawingExportModal.tsx, DXF 생성 backend/drawing_dxf.py
저장과 백업
프로젝트 메뉴에서 .spipe로 저장하면 관망·시나리오·레이어·보정 자료가 한 파일에 담깁니다. 수정 중에는 10분마다 브라우저에 자동 백업되며(최근 30개), 프로젝트 메뉴 > 백업 기록에서 복원합니다.
6. API
브라우저는 Web 서버의 /api 프록시를 통해 해석 API를 호출합니다. 해석 API 포트는 외부에 공개하지 않습니다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/health |
상태 확인 |
| POST | /api/analyze |
multipart file(.inp) → 전체 EPS 해석 결과 JSON (?format=columnar 압축 형식) |
| POST | /api/jobs/{name} |
일괄 해석: fireflow, criticality, servicearea, vsp, energy, calibrate, pumpschedule |
| POST | /api/gis/vector |
GDAL 벡터 파일 → WGS84 GeoJSON |
| POST | /api/gis/export |
레이어 → SHP·GPKG·DXF·GeoJSON·KML (좌표계 지정) |
| POST | /api/gis/op |
버퍼·병합·잘라내기·차이·보로노이·격자 |
| POST | /api/gis/reproject |
레이어 좌표계 다시 지정 |
| POST | /api/dem |
DEM 업로드 (GeoTIFF·ASC·IMG, zip) |
| GET | /api/dem/{id}/preview.png |
DEM 음영 미리보기 |
| GET | /api/dem/{id}/terrain/{z}/{x}/{y}.png |
3D 지형 타일 (terrarium) |
| POST | /api/dem/{id}/sample |
지점 표고 (쌍선형 보간) |
| POST | /api/dem/{id}/hydro |
하천선 추출 / 유역 |
| POST | /api/dem/from-points |
점 표고로 DEM 생성 (TIN) |
| GET | /api/dem-base |
서버에 등록한 기본 DEM 목록 |
| POST | /api/drawing/dxf |
도면(JSON) → DXF (AutoCAD 2018, UTF-8 한글) |
해석 결과의 필드 정의는 src/types.ts의 SimulationResult를 기준으로 합니다. 오류는 {"detail": "..."} 형식입니다.
| 상태 | 의미 |
|---|---|
| 400 | 입력 형식 오류 (확장자, 파라미터, 좌표계) |
| 413 | 업로드 한도 또는 해석 규모 상한 초과 |
| 500 | EPANET 입력·해석 오류 |
| 504 | 해석 시간 초과 |
7. 환경변수와 비밀값
| 변수 | 기본값 | 의미 |
|---|---|---|
SPIPE_MAX_UPLOAD_MB |
20 | INP·GIS 업로드 한도. nginx client_max_body_size와 맞출 것 |
SPIPE_MAX_DEM_MB |
300 | DEM 업로드 한도. nginx location /api/dem과 맞출 것 |
SPIPE_ANALYZE_TIMEOUT_S |
120 | 해석 1건 시간 제한 |
SPIPE_JOB_TIMEOUT_S |
900 | 일괄 해석 1건 시간 제한 |
SPIPE_MAX_PERIODS |
10000 | 수리 스텝 수 상한 |
SPIPE_MAX_RESULT_CELLS |
50000000 | (노드+링크) × 스텝 상한 |
SPIPE_WORKERS |
min(4, CPU-1) | 해석 프로세스 수 |
SPIPE_DEM_DIR |
data/dem |
DEM 보관 폴더 |
SPIPE_DEM_KEEP |
8 | 보관할 DEM 개수 |
SPIPE_BASE_DEM_DIR |
data/base_dem |
서버 기본 DEM 폴더 (정리되지 않음) |
EPANET_LIBRARY_PATH |
64bit/epanet2.dll |
EPANET 라이브러리 경로 |
비밀값 원칙:
- API 키·토큰은 저장소에 커밋하지 않습니다.
- 지도 서비스 키는
.env.local(커밋 제외)에 넣습니다..env.example을 복사해 채우고 다시 빌드합니다.VITE_VWORLD_API_KEY: 브이월드 배경지도VITE_KAKAO_JS_KEY: 카카오 주소 검색 (콘솔의 JavaScript SDK 도메인에 접속 주소 등록 필요)
- 이 키들은 빌드된 화면 코드에 포함되어 브라우저에 노출되므로, 각 콘솔에서 사용 도메인을 제한합니다.
- 이전 커밋 기록에는 키가 남아 있습니다. 저장소를 공개하려면 키를 재발급합니다.
- 실무 관망 INP, HWP·PDF 보고서, 화면 캡처는 커밋하지 않습니다 (
.gitignore참고).
8. 사내 서버 배포
Windows 서버 PC (현재 운영 방식)
현재 배포본은 데모 v2 (2026-10-30, 이전 배포 데모 v1 2026-10-15)에 도면 출력을 더한 2026-11-06 판입니다. 변경 내역은 docs/SPipe_패치내역_v2_2026-10-30.txt와 docs/SPipe_패치내역_도면출력_2026-11-06.txt를 확인하고, (시험)으로 표시된 기능은 기존 방식과 결과를 비교해 사용합니다.
저장소의 파일(또는 배포용 압축 파일 SPipe_server_*.zip)을 서버 PC의 SPipe 폴더에 덮어쓰고 다음 순서로 실행합니다. 기존 .venv, node_modules, data와 .env.local은 유지합니다. 최초 설치 절차는 SERVER_SETUP.md를 따릅니다.
- 새 라이브러리 설치 (데모 v2에서 scipy, rasterio 등, 2026-11-06 판에서 ezdxf(DXF)·maplibre-contour(등고선)가 추가되어 반드시 실행)
.\.venv\Scripts\python.exe -m pip install -r backend\requirements.txt
npm install
- 화면을 다시 빌드하면서 서버 실행 (
-Rebuild없이 실행하면 예전 화면이 남음)
powershell -ExecutionPolicy Bypass -File .\start-lan.ps1 -Rebuild
- 웹 화면:
http://<서버 IP>:8080(사내망 공개) - 해석 API:
127.0.0.1:8000(서버 내부 전용, 웹 서버가/api만 전달) - 코드 갱신 후에는 반드시
-Rebuild로 화면을 다시 빌드합니다.
서버 기본 DEM 등록 (선택, 최초 1회): 국토지리정보원 DEM 등을 서버에 한 번 등록해 두면 사용자가 파일을 올리지 않고 분석 → 지형(DEM)의 "서버 DEM" 버튼으로 바로 씁니다. DEM 파일은 저장소·배포 압축에 들어 있지 않으므로 서버마다 등록합니다.
.\.venv\Scripts\python.exe -m backend.dem register "C:\경로\한반도.zip" korea-90m "국토지리정보원 DEM 90m (비영리·변경금지)"
이름(두 번째 값)은 영문 소문자·숫자·-·_만 씁니다. 자료의 이용 조건(국토지리정보원 90m는 CC BY-NC-ND)을 확인하고 등록하세요.
Docker (nginx + API)
docker compose up -d --build
- 구성:
compose.yaml,deploy/Dockerfile,deploy/nginx.conf - DEM 보관 폴더는 컨테이너의
/app/data/dem(필요하면 볼륨으로 유지) - 업로드 한도를 바꿀 때는 환경변수와 nginx 설정을 함께 바꿉니다.
배포 전 확인:
git status
npm run typecheck
npm test
npm run test:api
npm run build
9. 문제 해결 순서
- 브라우저 주소가
127.0.0.1:5173(개발)인지<서버 IP>:8080(사내)인지 확인합니다. /api/health가{"status":"ok"}를 돌려주는지 확인합니다. 아니면 해석 API가 꺼진 상태입니다.- 해석 오류는 메시지의
Error 2xx줄(EPANET 입력 오류)을 먼저 확인합니다. - 지도가 엉뚱한 곳에 그려지면 상단 좌표계 설정과 GIS 레이어의 원본 좌표계를 확인합니다.
- 새 기능이 화면에 안 보이면
start-lan.ps1 -Rebuild로 다시 빌드했는지 확인합니다. - DEM·GIS·도면 DXF 기능이 서버 오류를 내면
pip install -r backend\requirements.txt를 다시 실행했는지 확인합니다. DXF가 "간이 R12"로 저장되면 해석 API에 연결되지 않은 상태입니다. - 도면 글꼴이 다르게 보이면 그 PC에 HY울릉도M이 설치되어 있는지 확인하거나, 도면 출력 창에서 글꼴을 맑은 고딕으로 바꿉니다.
- 인터넷 표고(90m)·OSM 건물·배경지도만 실패하면 사용자 PC의 외부 인터넷 차단 여부를 확인합니다.
자료가 이상하다고 관망 파일이나 백업을 지우지 않습니다. 먼저 프로젝트 메뉴 > 백업 기록과 실행 취소로 되돌릴 수 있는지 확인합니다.
10. 상세 문서 목차
SERVER_SETUP.md: 다른 Windows PC를 사내 서버로 설치하는 절차deploy/README.md: Docker·nginx 배포docs/SPipe_패치내역_v2_2026-10-30.txt: 데모 v2 변경 내역 (공지·첨부용)docs/SPipe_패치내역_도면출력_2026-11-06.txt: 도면 출력 추가 변경 내역 (공지·첨부용)public/EXAMPLE_NETWORKS.md: 예제 관망 설명_worklog.md: 배포본 등록·변경 작업 기록
11. 저장소 구조
src/ React 웹 앱
App.tsx 상태와 화면 조립
inpModel.ts INP 파싱·생성, 편집 함수
inpExtras.ts 다중 수요·수질·에너지 등 구조화 섹션
worker.ts WASM 해석 (Web Worker)
Map.tsx 지도 표시·편집 (MapLibre)
*Section.tsx 분석 탭 화면 (편집 도구, DEM, GIS, 최적화 ...)
*Tools.ts 분석·편집·GIS 순수 로직 (Node 테스트 대상)
drawing.ts 도면 모델(mm), 표제란·범례, SVG·간이 DXF 출력
profileDrawing.ts, networkDrawing.ts 수리 종단면도, 관망도(자동 분할)
DrawingExportModal.tsx 도면 출력 창
backend/ FastAPI 해석 API
main.py API 진입점
epanet.py EPANET DLL ctypes 바인딩
batch.py, jobs.py 일괄 해석 프레임워크와 분석 Job
gisio.py, gisops.py GIS 입출력·연산 (GDAL)
dem.py DEM 보관·표고·지형 타일·유역
drawing_dxf.py 도면 → DXF (AutoCAD 2018, ezdxf)
blocksys/ 블록 분할 CLI
tests/ pytest
64bit/ EPANET 2.3.5 DLL
public/ 예제 관망 (Net1~3, 한글 CP949, 합성망)
tests/ Node 회귀 테스트
deploy/ Dockerfile, nginx.conf
data/ 서버 실행 중 생성 (DEM 보관, 커밋 제외)