이 게시물은 이전 게시물(공식 GDAL 이미지로 GIS & Python 개발환경 구축하기)에 이어지는 내용이며, 이전 글에서 구축하지 못한 PostGIS 관련 내용을 추가적으로 작성한 겁니다.
이 글에서는 앞으로 공식 GDAL 이미지로 GIS & Python 개발환경 구축하기
에서 생성한gis+python 개발환경이 구축된 container
를
gdal container
라고 짧게 부르겠습니다!
GDAL Container
와 통신할 PostGIS Container
를 하나 생성하겠습니다.
# 제가 글 쓸 당시에 가장 높은 버전(17-3.5)을 선택했습니다.
docker pull postgis/postgis:17-3.5
docker run --name postgis -p 5432:5432 -d \
-e POSTGRES_PASSWORD=postgres -e TZ=Asia/Seoul \
postgis/postgis:17-3.5
다른 버전을 쓰고 싶으면 PostGis Container 링크를 참고해주세요.
GDAL
에서 PostGIS
컨테이너로 데이터를 upload 하기 위해서는
네트워크로 연결이 된 상태여야 합니다.
이 문제는 docker network
로 쉽게 해결이 가능합니다.
geonet
이라는 이름의 Docker network
를 하나 생성하고,
gdal
와 postgis
컨테이너 2개를 연결하겠습니다.
docker network create geonet
docker network connect geonet postgis
docker network connect geonet gdal
컨테이너 간 통신 테스트를 위해서 gdal -> postgis
방향으로
간단한 네트워크 요청을 하나 보내보겠습니다.
docker exec gdal ogrinfo \
PG:"host=postgis user=postgres dbname=postgres password=postgres" \
-sql "select 1"
잘되네요 👍
마지막으로 Gdal Container
를 통해서 Postgis Container
에
샘플 데이터를 하나 넣어보겠습니다.
먼저 VWorld
에서 [법정동 경계(읍면동) - 서울] 데이터를 다운로드 받겠습니다.
저는 여러 시도 중에서 서울 데이터를 다운로드 받도록하겠습니다.
참고: 다운로드를 받기 위해서는 Vworld 로그인이 필요합니다
해당 파일을 gdal container
내부로 copy 를 합니다.
만약에
docker run
할 때 이미-v
옵션으로 마운팅한 host 경로가 있다면,
해당 경로에 파일을 넣고 작업하시면 됩니다.
# gdal container 에 샘픔 shp 데이터를 넣기 위한 디렉토리 생성
docker exec gdal mkdir /sample_data
# 샘플 데이터를 gdal container 안으로 복사하기
docker cp ./LSMD_ADM_SECT_UMD_서울.zip gdal:/sample_data
# 샘플 데이터 unzip 수행
docker exec gdal unzip /sample_data/LSMD_ADM_SECT_UMD_서울.zip -d /sample_data
# shp data 를 db 로 import, 참고로 -nln 옵션을 통해서 명시적으로 테이블 이름을
# 줬습니다. LSMD_ADM_SECT_UMD_11 라는 이름의 테이블이 생성될 겁니다.
docker exec gdal ogr2ogr -overwrite -progress \
--config PG_USE_COPY YES -f PostgreSQL \
"PG:host=postgis user=postgres password=postgres dbname=postgres schemas=public" \
'/sample_data/LSMD_ADM_SECT_UMD_11_202504.shp' \
-lco GEOMETRY_NAME=geom -nlt MULTIPOLYGON -makevalid \
--config SHAPE_ENCODING "CP949" -nln LSMD_ADM_SECT_UMD_11
## 출력이 아래처럼 나오면 성공한겁니다.
## 0...10...20...30...40...50...60...70...80...90...100 - done.
## 마지막으로 PostGIS container 에 쿼리를 날려서 잘
docker exec postgis psql -U postgres -c \
"select
ogc_fid, emd_cd, col_adm_se, emd_nm, sgg_oid,
ST_GeometryType(geom),
ST_SRID(geom)
from public.LSMD_ADM_SECT_UMD_11
limit 1"
docker exec postgis psql -U postgres -c \
"\d public.LSMD_ADM_SECT_UMD_11"
PostGis
와 관련된 준비는 모두 끝났습니다.
이제 gdal container
에 설치된 python
에서
postgis container
로 쿼리를 날려보겠습니다.
python
에서 postgres db
에 쿼리를 날릴 때는 주로
psycopg2
패키지를 사용합니다.
그럼 해당 패키지를 설치부터 해보겠습니다.
아래와 같이 docker exec
명령어로 gdal container
내부에
접속해서 설치 명령어를 입력해주세요.
docker exec -it gdal bash # 컨테이너 내부로 접속
## psycopg2 설치를 위한 dependency 추가
apt install -y libpq-dev
# 파이썬 가상환경(venv) 활성화
source /app_workspace/.venv/bin/activate
## psycopg2 설치
pip install psycopg2
Dev Container
플러그인을 사용해서 gdal container
에 attach
된 상태의
vs code
를 열고 jupyter notebook
을 생성하고 간단한 쿼리를 날려보겠습니다.
import psycopg2
from psycopg2 import sql
# using context manager
with psycopg2.connect(
host="postgis",
port="5432",
database="postgres",
user="postgres",
password="postgres"
) as conn:
cur = conn.cursor()
query = sql.SQL("select now();")
cur.execute(query)
result = cur.fetchone()
print("result => ", result[0])
# 출력결과:
# result => 2025-04-22 10:30:07.795021+09:00
PostGIS 의 ST_*
관련 메소드도 정상동작하는지 테스트해보겠습니다.
# using context manager
with psycopg2.connect(
host="postgis",
port="5432",
database="postgres",
user="postgres",
password="postgres"
) as conn:
# Perform database operation
cur = conn.cursor()
query = sql.SQL("select ST_AsText(geom, 1) from public.LSMD_ADM_SECT_UMD_11 limit 1;")
cur.execute(query)
result = cur.fetchone()
print("result => ", result)
# 출력결과:
# result => ('MULTIPOLYGON(((197377.9 553847.1,197388.4 ... 생략! 너무 기네요!