안녕하세요? 이번 글에서는 QGIS에서 플러그인을 개발하는 과정을 정리해보고록 하겠습니다.
저는 UAV 기반 RGB 영상에서 식생지수를 도출하는 Vegetation UAV 플러그인을 개발해 보고자 합니다.
앞서 QGIS 플러그인 개발을 위한 Plugin Builder와 Plugin Reloader 사용법을
정리했었는데요(바로가기: http://blog.daum.net/geoscience/987),
윗 글의 내용을 기반으로 'Vegetation UAV' 플러그인 기본 설정을 마쳤습니다.
아래와 같이 '플러그인 > Vegetation UAV > Vegetation UAV'를 클릭하면,
아래와 같은 실행 창이 셋팅되어 있습니다.
플러그인 아이콘은 Map Icons Collection을 참조하였습니다.
바로가기: https://mapicons.mapsmarker.com/markers/nature/natural-marvels/tree/
이제 할 일은 1) comboBox에 래스터 레이어 목록을 추가하고,
2) pushButton을 클릭했을 때 출력파일의 경로, 이름을 지정하여 이 정보를 lineEdit로 전달한 후,
3) 확인을 클릭했을 때, comboBox에서 선택된 래스터로부터 식생지수를 계산하여 새 파일로 저장하는 것입니다.
Plugin Builder를 통해 자동 생성된 vegetation_uav.py를 열어보면 def run(self) 함수가 있는데요,
이 함수 내에서 코딩을 진행해 주시면 되겠습니다. 일단, comnboBox와 lineEdit를 초기화 합니다.
# Reset inputs
self.dlg.comboBox.clear()
self.dlg.lineEdit.clear()
comboBox에 래스터 레이어를 추가해보도록 하겠습니다.
# Add raster layer to comboBox layers = self.iface.legendInterface().layers() layer_list = [] for layer in layers: if layer.type() == layer.RasterLayer: layer_list.append(layer.name()) self.dlg.comboBox.addItems(layer_list)
아래와 같이 comboBox에 래스터 레이어 목록이 자동 추가됩니다. 간단하죠?!
이어서 pushButton을 클릭했을 때 실행되는 대화상자를 아래 함수로 설정합니다.
def select_output_file(self): fileName = QFileDialog.getSaveFileName(self.dlg, "Select output file ","", '*.tif') self.dlg.lineEdit.setText(fileName)
pushButton을 클릭했을 때 위 함수를 호출하는 코드입니다.
# Select output file
self.dlg.pushButton.clicked.connect(self.select_output_file)
코드는 문제가 없는데, 아래와 같이 QFileDialog 임포트 오류가 발생하였습니다.
Plugin Builder를 통해 생성된 파일은 아래와 같은 기본 설정을 가지고 있는데요,
from PyQt4.QtCore import QSettings, QTranslator, qVersion, QCoreApplication from PyQt4.QtGui import QAction, QIcon
여기서 PyQt4.QtGui 임포트 목록에 QFileDialog를 추가하면 오류는 해결됩니다.
저는 아래와 같이 임포트를 지정하고, qgis.core와 qgis.analysis도 설정하도록 하겠습니다.
from PyQt4.QtCore import * from PyQt4.QtGui import * from qgis.core import * from qgis.analysis import *
아래와 같이 pushButton과 lineEdit도 의도한 대로 잘 작동됩니다.
이제 위 실행 창에서 '확인' 버튼을 클릭했을 때 식생지수를 계산해야 하는데요,
이 부분은 def run(self) 함수의 아래 영역에서 해당 코드를 입력해주시면 되겠습니다.
# See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass
저는 ExG-ExR(Excess Green minus Excess Red) 지수를 계산하도록 하겠습니다.
이 부분과 관련되 설명은 앞서 작성한 아래 글을 참고하시면 되겠습니다.
QGIS 파이썬 콘솔에서 UAV 기반 RGB 영상의 식생지수 계산하기: http://blog.daum.net/geoscience/961
# Add raster layer selectedLayerIndex = self.dlg.comboBox.currentIndex() bohLayer = layers[selectedLayerIndex] entries = [] # Definition of Band 1(Red) boh1 = QgsRasterCalculatorEntry() boh1.ref = 'boh@1' boh1.raster = bohLayer boh1.bandNumber = 1 entries.append(boh1) #Definition of Band 2(Green) boh2 = QgsRasterCalculatorEntry() boh2.ref = 'boh@2' boh2.raster = bohLayer boh2.bandNumber = 2 entries.append(boh2) #Definition of Band 3(Blue) boh3 = QgsRasterCalculatorEntry() boh3.ref = 'boh@3' boh3.raster = bohLayer boh3.bandNumber = 3 entries.append(boh3) # ExG-ExR calculation: ExG=2*g-r-b, ExR=1.4*r-b outputLayer = self.dlg.lineEdit.text() calc = QgsRasterCalculator('(2 * (boh@2/(boh@1+boh@2+boh@3)) - (boh@1/(boh@1+boh@2+boh@3)) - (boh@3/(boh@1+boh@2+boh@3))) - (1.4 * (boh@1/(boh@1+boh@2+boh@3)) - (boh@3/(boh@1+boh@2+boh@3)))', outputLayer, 'GTiff', bohLayer.extent(), bohLayer.width(), bohLayer.height(), entries) calc.processCalculation() # Output file fileInfo = QFileInfo(outputLayer) baseName = fileInfo.baseName() rLayer = QgsRasterLayer(outputLayer, baseName) QgsMapLayerRegistry.instance().addMapLayer(rLayer)
아래와 같이 UAV 기반 RGB 영상이 ExG-ExR 색상 식생지수로 자동 변환됩니다.