[gdal] GeoPackage 다루기

식빵·2024년 4월 8일
0

GIS

목록 보기
6/7
post-thumbnail

GDAL 을 통해서 어떻게 GeoPackage 를 어떻게 활용할 수 있는지 알아보겠습니다.

중요 참고사항

이 글에서는 CLI ToolWindow Terminal + Pwsh 7.4.1 을 사용합니다.

bash 사용자분들께서는 딱 하나만 주의하시기 바랍니다.
bash 에서는 new line\ 이지만, pwsh 는 new line 이 ` (백틱) 이라는 점
유의해서 보시면 bash 에서도 충분히 활용 가능합니다!



💾 샘플 데이터 출처

여기서 사용되는 샘플 연속지적도 Shapefilevworld 에서 다운로드 가능합니다.



🚀 Shapefile 에서 GeoPackage 로 변환

1. GPKG (= GeoPackage) 포맷 지원 확인

일단 제가 사용하는 ogr2ogrGeoPackageShapefile 포맷을 지원하는지
확인해보겠습니다. 아래 명령어를 입력해서 확인해보죠.

ogr2ogr --formats | select-String -Pattern 'GPKG|Shapefile'


2. 기본 - ShapeFile 데이터 GeoPackage 로 변환하기

단순하게 ShapeFile 을 GeoPackage 로 변환(또는 import) 하는 건 쉽습니다.
아래처럼 입력하면 끝입니다.

명령어 입력 방식 :

ogr2ogr -progress somesome.gpkg <# Transform 결과물 파일의 명칭 #>`
.\LSMD_CONT_LDREG_11_202311.shp <# 샘플 연속지적도(서울) shapeFile 사용 #>`
--config SHAPE_ENCODING "EUC-KR" <# 인코딩 틀리면 오류가 발생합니다!! #>`
-nlt MULTIPOLYGON -lco GEOMETRY_NAME=geom;

혹시라도 Warning 1: Passed SRS uses EPSG:5186 identification, but its definition is not compatible with ~생략~ 같은 문구가 나와도, 결과물은 제대로 나오니 크게 신경쓰지 마시기 바랍니다. 이 문구와 관련된 설명은 참고 사항 목차에 기록했습니다.



3. 응용 - gpkg 파일에 shapefile 컨텐츠 추가로 덧붙이기

GeoPackage 는 여러개의 SubSet(= Layer) 를 갖는 것을 전제로 만들어졌기 때문에
계속해서 데이터(Layer)를 덧붙일 수 있습니다!

명령어 입력 방식 :

## 제주특별자치도_연속지적도를 append(덧붙이기)
ogr2ogr -progress -append .\somesome.gpkg .\LSMD_CONT_LDREG_50_202311.shp `
--config SHAPE_ENCODING "EUC-KR" -nlt MULTIPOLYGON -lco GEOMETRY_NAME=geom 



4. 응용 - Subset(=Layer) 명칭 지정하면서 import 하기

명령어 입력 방식 :

ogr2ogr -progress somesome2.gpkg <# Transform 결과물 파일의 명칭 #>`
.\LSMD_CONT_LDREG_11_202311.shp <# 샘플 연속지적도(서울) shapeFile 사용 #>`
--config SHAPE_ENCODING "EUC-KR" <# 인코딩 틀리면 오류가 발생합니다!! #>`
-nlt MULTIPOLYGON -lco GEOMETRY_NAME=geom `
-nln 'seoul_ldreg'; # Subset(=Layer) Name 지정!

추후에 GeoPackage 에 여러 개의 Layer 가 생성되고, 각각의 Name 을 갖게 됩니다.
그런데 이러한 Layer Nameogr2ogr 명령어 실행 시, nln 옵션을 추가하지 않으면
*.shp 파일의 명칭을 그대로 Layer Name 으로 사용합니다.

만약에 이런 방식을 원하는 거면 괜찮지만
추후에 GeoPackagePostgresql 같은 곳에 import 할 경우에는 해당 명칭을
그대로 사용해서 Table 을 생성하기 때문에, 이름 충돌에 의한 오류를 뱉어낼 수도 있습니다.

만약에 GeoPackage 를 또 다른 곳에 import 할 예정이라면 직접 지정해주는게 좋습니다.





👀 GeoPackage Layer 조회

제대로 추출이 됐는지 확인하기 위해서 가볍게 ogrinfo -sql 을 사용해봅니다.
하지만 바로는 사용이 불가합니다.
-sql 을 사용하기 위해서는 from 절에 정확한 Subset(= Layer) 의 명칭을
적어야 합니다.

GeoPackage 는 기본적으로 여러개의 SubSet(=Layer) 를 갖을 수 있습니다.
그렇기 때문에 조회하고자 하는 특정 Subset(=Layer) 의 명칭을 정확히 알아야
ogrinfo -sql 문법을 사용할 수 있습니다.


1. Subset(=Layer) name 조회

## 먼저 현재 생성한 gpkg 파일에 어떤 Subset(=Layer) 가 있는지 알아야 합니다.
## geopackage 는 하나의 파일이지만 여러 Layer 를 갖을 수가 있습니다.

#### 1-1. 명령어 입력 ####
ogrinfo .\somesome.gpkg; # 저는 Shapefile 2개를 import 한 gpkg 를 사용합니다.

#### 1-2. 출력 ####
# INFO: Open of `.\somesome.gpkg'
#       using driver `GPKG' successful.
# 1: LSMD_CONT_LDREG_11_202311 (Multi Polygon) ## 서울시
# 2: LSMD_CONT_LDREG_50_202311 (Multi Polygon) ## 제주특별자치시

#### 참고: 더 자세한 정보를 원하시면 ==> ogrinfo .\somesome.gpkg -al -so;
  • 출력결과 분석:
    • LSMD_CONT_LDREG_11_202311, LSMD_CONT_LDREG_50_202311
    • 두 개의 Subset(Layer) Name 이 확인됩니다!

2. GeoPackage 에서 특정 Subset(=Layer) 조회

#################### 2. 특정 Layer 정보조회 ####################
## 앞서 확인한 Layer name 중 하나를 사용해서 ogrinifo -sql 을 
## 사용하면 아래와 같습니다. ##

### 2-1. 명령어 입력 ###
ogrinfo -sql "select * from LSMD_CONT_LDREG_11_202311 limit 1" .\somesome.gpkg -q

### 2-2. 출력 결과물 ###
# Layer name: SELECT
# OGRFeature(SELECT):1
#   SGG_OID (Integer) = 393351
#   JIBUN (String) = 868-1 도
#   BCHK (String) = 1
#   PNU (String) = 1129013300108680001
#   COL_ADM_SE (String) = 11290
#   MULTIPOLYGON (((199678.398625629 556650.395783019,199 ... 생략 ...




💽 PostgreSQL 로 Import

생성한 GeoPackage 를 PostgreSQL 에 import 를 해보겠습니다.
저희 회사는 PostgreSQL (PostGIS) 가 사실상 표준 DB 여서 이를 사용했습니다.

ogr2ogr -overwrite -progress --config PG_USE_COPY YES -f PostgreSQL `
"PG:host=localhost port=5432 user=postgres 
 password=postgres dbname=postgres schemas=coding_toast" `
.\somesome.gpkg `
-lco GEOMETRY_NAME=geom -nlt MULTIPOLYGON `
--config SHAPE_ENCODING "EUC-KR";

# 주의! "-nln LSMD_CONT_LDREG" 처럼 테이블 명을 정해버리면 SubSet 중 하나만
# import 가 되버럽니다. 그렇기 때문에 -nln 옵션을 사용하면 안됩니다!

결과적으로 SubSet 이 여러개면 여러 테이블이 생성되고,
그렇지 않으면 하나의 테이블만 생성됩니다.

저 같은 경우는 Subset 이 2 개여서 import 후 아래처럼 테이블이 2개 생성되었습니다.

  • Layer Name 을 사용해서 테이블명이 지정된 것도 유의해서 봐두시길 바랍니다~

QGIS 를 통해서 좌표계도 정확히 잘 맞는 건지 가볍게 확인합니다.
서울, 제주 데이터가 아래 그림처럼 자기 위치에 잘 랜더링되는 것을
보니 별문제는 없는듯 합니다.




💾 PostgreSQL 에서 GeoPackage 로 Export

이번에는 이전 목차의 반대 작업을 해보겠습니다.
이 작업은 맨 처음 저희가 ShapeFileGeoPackage 로 변환하던
ogr2ogr 문법과 크게 다르지 않습니다.

ogr2ogr -progress .\from_database.gpkg <# Transform 결과물 파일의 명칭 #>`
"PG:host=localhost port=5432 user=postgres 
 password=postgres dbname=postgres schemas=coding_toast" `
-nlt MULTIPOLYGON -lco GEOMETRY_NAME=geom;

## 이후에 gpkg 파일의 내용을 보면...?
# ogrinfo .\from_database.gpkg
# INFO: Open of `.\from_database.gpkg'
#       using driver `GPKG' successful.
# 1: lsmd_cont_ldreg_11_202311 (Multi Polygon)
# 2: lsmd_cont_ldreg_50_202311 (Multi Polygon)
  • coding_toast 라는 DB 스키마에 있는 모든 테이블이
    하나의 gpkg 파일로 import 된 것을 확인할 수 있습니다.





📝 참고 사항

1. Shape Import 할 때 나오는 경고문

아마 저랑 똑같이 실습하시거나, 또는 다른 Shape 으로 작업할 때
아래와 같은 경고문이 나올 수도 있습니다.

Warning 1: 
Passed SRS uses EPSG:5186 identification, 
but its definition is not compatible with the official definition of the object. 
Registering it as a non-EPSG entry into the database.

이건 정상적인 반응입니다. 사실 저 문구가 나와도 출력되는 gpkg 파일에는 좌표계가
정상적으로 반영되어 있습니다.

이런 경고문이 나오는 이유는 (제 추측이지만) gdal 이 내장하는
다양한 좌표계 정보 및 prj 형식이 이미 존재하는 상태인데,

현재 변환하려는 Shapefile 의 prj 형식이 그와 달라서 그렇습니다.
비록 같은 prj 지만 서로 다른 포맷을 갖을 수 있습니다.

이는 epsg.io 에서 알 수 있습니다.
아래 그림을 같이 보시죠.

  • 좌측에 Export 라는 문구 밑으로 뭔가 목록들이 보이시죠?
  • 이 목록 각각이 prj 의 서로 다른 포맷이라고 이해하면 됩니다.

테스트해본 결과 gdal gpgk 파일을 추출할 때 쓰는 좌표계 형식은 OGC WKT 2
것으로 확인되었습니다. 정말 그런지 보고 싶다면 shape file 의 prj 파일의 내용을
OGC WKT 2 의 문자열로 바꿔치기 하고 import 해보시기 바랍니다.
아마 경고문이 안 나올 겁니다.

솔직히 큰 문제를 일으키지는 않기 때문에 딱히 신경 쓸 필요는 없습니다.



2. 참고 링크

profile
백엔드를 계속 배우고 있는 개발자입니다 😊

0개의 댓글