CODEKILLER

알림 : [namoosystem.com] Codekiller 나무의사 빨간펜 인강, 재해위험성 검토의견서 QGIS 강의

반응형

재해위험성 검토의견서

GIS 소프트웨어를 개발하다 보면 벡터 데이터를 어떻게 읽고, 어떻게 화면에 그리고, 어떻게 관리할지가 핵심 과제가 됩니다. SharkGeo는 WPF 기반 데스크탑 앱이라 웹 기반 GIS 라이브러리를 바로 가져다 쓸 수도 없고, ESRI ArcObjects 같은 상용 SDK는 과한 선택이죠. 결국 "필요한 부분만, 직접 만들자"는 방향으로 가게 됐습니다. 더군다나 포맷 파싱 관련부분들은 어느정도 널려 있기도 하고 AI 역시 이러한 파싱 부분에서는 뛰어납니다.

지원포맷과 파싱 아키텍처

포맷 확장자 파서
ESRI Shapefile .shp NetTopologySuite.IO.ShapeFile (NuGet)
GeoPackage .gpkg SQLite + 직접 GPKG 바이너리 파싱
GeoJSON .geojson System.Text.Json 수동 파싱
AutoCAD DXF .dxf 자체 스트리밍 파서 (DxfParserService)

DXF 직접 파싱 (DxfParserService)

DXF는 텍스트 기반 포맷입니다. 그룹코드(int)와 값(string)이 2줄씩 반복되는 단순한 구조입니다. 이 구조를 StreamReader로 한 줄씩 읽는 스트리밍 방식으로 파싱합니다. 대용량 DXF 파일도 메모리에 전체를 올리지 않기 때문에 효율적입니다.

파싱 순서:
SECTION TABLES → 레이어명 / 색상 추출
SECTION BLOCKS → 블록 정의 파싱 (INSERT 참조용)
SECTION ENTITIES → LINE / LWPOLYLINE / CIRCLE / ARC / TEXT / INSERT

GeoPackage 바이너리 헤더 파싱

GPKG는 SQLite를 컨테이너로 쓰는 OGC 표준 포맷인데, geometry 컬럼의 바이너리 앞에 GPKG 전용 헤더가 붙어 있어서 WKB 오프셋을 직접 계산해야 했습니다. (표준 문서에도 이 부분이 모호하게 적혀 있습니다.)

// GPKG binary header
// magic(2) + version(1) + flags(1) + srsId(4) + envelope(가변)
byte flags    = header[3];
int  envType  = (flags & 0x0E) >> 1;
int  envBytes = envType switch
{
    0 => 0,    // 없음
    1 => 32,   // XY
    2 => 48,   // XYZ
    3 => 64,   // XYZM
    4 => 48,   // XYM
    _ => 0
};
int wkbOffset = 8 + envBytes;

DXF 객체 모델 (DxfDocument)

모든 벡터 데이터는 DxfDocument 하나로 표현됩니다. 처음에는 NTS(NetTopologySuite)의 Geometry를 그대로 쓸까도 했지만, WPF 렌더링에 최적화된 경량 모델이 필요해서 직접 설계했습니다. 제가 모든 모델을 가지고 QGIS와 같은 작업을 할껀 아니기에 필요한 객체들만 모델링하는 것이 맵상에서 상당히 빠름을 유지합니다. 제가 필요했던 모델은 "레이어 정보", "전체 엔티티 플랫 리스트", "블록 정의", "전체 바운딩 박스" 이정도 였고, 개발하면서 더 필요하면 모델을 늘려 나가야할 것 같네요.

렌더링??? (가장 문제 였던 부분)

WPF에서 벡터 데이터를 그리는 방법은 여러 가지입니다.

  • Canvas에 Line, Polyline 등 UIElement 추가 → 수만 개부터 느려짐
  • DrawingVisual + DrawingContext  GDI 수준의 성능
  • WriteableBitmap에 직접 픽셀 쓰기 → 빠르지만 안티앨리어싱 없음

SharkGeo는 DrawingVisual 방식을 선택했습니다. UIElement 트리 없이 렌더링 명령만 기록하기 때문에 수십만 개의 폴리라인도 처리 가능합니다. 맵은 정상적으로 빠르게 올라왔지만, 그 이후가 문제였습니다. 패닝에서 상당한 부하가 걸리기에 이러 부하를 줄이기 위해서 쉬링크(너무 작아서 안보이면 스킵 하는 기술ㅋㅋ)라고 하는 것도 넣어보고, 레이어를 따로 관리하는 패널도 넣어보고, 움직이는 동안에는 블러처리도 해보고 현재는 스스로 빠르게 느꼈던 부분을 기준에 최적으로 맞춰놓은 상태입니다. 

 

어차피 실제 맵작업을 할때는 '군'이나 '시'정도 사이즈의 벡터를 가지고 작업을 하지는 않고, 범위로 벡터를 잘라서 사용하게 되지만, 어떤 것을 맵컨트롤에 올리던지 빠르면 기분이 좋겠죠!!

결론

마무리하며, 

첫번째, Vworld 위성지도를 띄워 놓습니다. 

Vworld 위성지도

 

두번째, 어떤 파일이든지 마우스 Drag & Drop으로 편하게 작업을 해야하기에 .shp 파일 맵 컨트롤에 던져봅니다.

레이어추가.

세번째, 새롭게 추가되는 레이어의 좌표가 프로젝트 좌표와 맞지 않다면 프로젝트 좌표계 팝업이 바로 올라옵니다.

좌표계설정
Vworld와 지적도 좌표계 맞추기

 

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band