REMOTE SENSING

QGIS 파이썬 콘솔을 이용하여 래스터 영상 병합하기

유병혁 2017. 6. 18. 01:29

이번 글에서는 QGIS 파이썬 콘솔을 이용하여 래스터 영상을 병합(merge)하는 방법을 학습해 보도록 하겠습니다.

시계열 위성영상을 다룰 때 반복적인 연산을 수행해야 하는 경우가 많은데요, 이럴 때 이 방법을 이용하시면 되겠습니다.


저는 프로바브이(PROBA-V) 위성 1km 해상도 영상을 다운로드 받고 있는데요, 우리나라는 4개 타일을 병합해야 합니다.

이런 병합을 날짜별로 반복해서 처리해야 하기 때문에, 필요한 파이썬 코드를 작성하여 처리해보고자 합니다.


먼저, 래스터 데이터를 파이썬을 통해 열어보는 방법부터 알아볼까요?!

QGIS에서 '래스터 레이어 추가' 버튼은 아래와 같은데요,


위 버튼을 클릭하고 해당 경로에 위치한 래스터 파일들을 선택할 수 있습니다.


이것을 파이선 콘솔로 처리해 보겠습니다. QGIS 상단 메뉴에서 '플러그인 > 파이썬 콘솔'을 클릭하고,


아래와 같이 파이썬 코드를 작성하여 래스터 레이어를 추가해 보도록 하겠습니다.

래스터 파일과 이름을 정의한 후, 해당 래스터의 유효성을 확인한 후에 레이어 패널 목록에 추가합니다.

# 소스 파일과 레이어 이름 정의
srcFile = "D:/PROBA-V_1km/20160101/PROBAV_S10_TOC_X30Y03_20160101_1KM_NDVI_V101_NDVI.tif" # source file
lyrName = "PROBA-V S10 TOC X30Y03 20160101 1KM NDVI V101" # layer name
# 레이어 생성
from qgis.core import QgsRasterLayer
rasterLyr = QgsRasterLayer(srcFile, lyrName)
# 레이어 유효성 확인: 맞다면 True를 반환
rasterLyr.isValid()
# 목록에 레이어 추가
QgsMapLayerRegistry.instance().addMapLayers([rasterLyr])


위 내용을 하나의 함수로 만들어 보겠습니다. 필요할 때 호출해서 사용하면 되겠죠?!

# 레이어 생성, 유효성 확인 후 추가하는 함수 정의
def addRasterLayer(srcFile, lyrName):
    rasterLyr = QgsRasterLayer(srcFile, lyrName)
    rasterLyr.isValid()
    QgsMapLayerRegistry.instance().addMapLayers([rasterLyr])
addRasterLayer(srcFile, lyrName)


이번에는 본 글의 주제인 래스터 병합을 파이썬 콘솔로 처리해 보겠습니다.

제가 파이썬으로 처리할 QGIS 기능은 SAGA(2.1.2) geoalgothms에 위치하고 있습니다.

아래와 같이 'SAGA (2.1.2) > Raster tools > Mosaic raster layers'를 클릭해 볼까요?! 


래스터 병합의 각종 매개 변수들이 보이는데요,


Input Grids를 선택하고 앞서 추가한 4개 래스터 레이어를 선택해 보겠습니다.


매개 변수를 설정한 후, Run을 실행하면 Mosaicked Grid가 생성됩니다.


4개 래스터 파일이 하나로 합쳐졌죠?! 이것을 파이썬 콘솔에서 구현해 보겠습니다.


처리 코드는 아래와 같습니다. 병합할 때 범위(extent)는 북위 33~43˚, 동경 124~132˚로 지정하였습니다.

# 폴더와 하부폴더
folder = "D:/PROBA-V_1km"
subfolder = "20160101"
# Input Grids와 Mosaicked Grid
rasterGrid = ""
mosaicGrid = folder + "/PROBA-V_1km_" + subfolder + ".tif"
# Input Grids 생성
rNum = 0
import glob
rLim = len(glob.glob(folder + "/" + subfolder + "/*.tif"))
for raster in glob.glob(folder + "/" + subfolder + "/*.tif"):
    rNum = rNum + 1    
    if rNum < rLim:
        rasterGrid = rasterGrid + raster + ";"
    else:
    rasterGrid = rasterGrid + raster
# Mosaic raster layers
import processing
processing.runalg("saga:mosaickrasterlayers", rasterGrid, None, 7, 0, 1, 10, 0, 0, "124, 132, 33, 43", mosaicGrid)
# 목록에 레이어 추가
addRasterLayer(mosaicGrid, subfolder)


이번에는 위 코드를 약간 수정하여 날짜별 폴더에 위치한 래스터 파일들을 반복적으로 병합하도록 하겠습니다.

import os
# 폴더별 래스터 병합 반복하기
for subfolder in os.listdir(folder):
    rasterGrid = ""
    mosaicGrid = folder + "/PROBA-V_1km_" + subfolder + ".tif"
    rNum = 0
    rLim = len(glob.glob(folder + "/" + subfolder + "/*.tif"))
    for raster in glob.glob(folder + "/" + subfolder + "/*.tif"):
        rNum = rNum + 1    
        if rNum < rLim:
            rasterGrid = rasterGrid + raster + ";"
        else:
        rasterGrid = rasterGrid + raster
    processing.runalg("saga:mosaickrasterlayers", rasterGrid, None, 7, 0, 1, 10, 0, 0, "124, 132, 33, 43", mosaicGrid)
    addRasterLayer(mosaicGrid, subfolder)


아래와 같이 하부폴더 별로 래스터 병합이 반복적으로 처리되고 레이어 패널에 자동 추가되었습니다. 간단하지만 알아두면 유용하겠죠?!