diff --git a/python/plugins/GdalTools/GdalTools.py b/python/plugins/GdalTools/GdalTools.py index 94f5907d2ce8..9e6aba778196 100644 --- a/python/plugins/GdalTools/GdalTools.py +++ b/python/plugins/GdalTools/GdalTools.py @@ -180,6 +180,12 @@ def initGui( self ): QObject.connect( self.nearBlack, SIGNAL( "triggered()" ), self.doNearBlack ) self.analysisMenu.addAction( self.nearBlack ) + if self.GdalVersion >= "1.7": + self.fillNodata = QAction( QIcon(":/icons/fillnodata.png"), QCoreApplication.translate( "GdalTools", "Fill nodata" ), self.iface.mainWindow() ) + self.fillNodata.setStatusTip( QCoreApplication.translate( "GdalTools", "Fill raster regions by interpolation from edges") ) + QObject.connect( self.fillNodata, SIGNAL( "triggered()" ), self.doFillNodata ) + self.analysisMenu.addAction( self.fillNodata ) + if self.GdalVersion >= "1.6": self.proximity = QAction( QIcon(":/icons/proximity.png"), QCoreApplication.translate( "GdalTools", "Proximity (Raster distance)" ), self.iface.mainWindow() ) self.proximity.setStatusTip( QCoreApplication.translate( "GdalTools", "Produces a raster proximity map") ) @@ -295,6 +301,11 @@ def doNearBlack( self ): d = NearBlack( self.iface ) self.runToolDialog( d ) + def doFillNodata( self ): + from tools.doFillNodata import GdalToolsDialog as FillNodata + d = FillNodata( self.iface ) + self.runToolDialog( d ) + def doWarp( self ): from tools.doWarp import GdalToolsDialog as Warp d = Warp( self.iface ) diff --git a/python/plugins/GdalTools/icons/fillnodata.png b/python/plugins/GdalTools/icons/fillnodata.png new file mode 100644 index 000000000000..08ec6f46faa3 Binary files /dev/null and b/python/plugins/GdalTools/icons/fillnodata.png differ diff --git a/python/plugins/GdalTools/resources.qrc b/python/plugins/GdalTools/resources.qrc index a0ed3d5c92a2..2986d9b0ab17 100644 --- a/python/plugins/GdalTools/resources.qrc +++ b/python/plugins/GdalTools/resources.qrc @@ -21,6 +21,7 @@ icons/about.png icons/dem.png icons/projection-export.png + icons/fillnodata.png icons/edit.png icons/reset.png diff --git a/python/plugins/GdalTools/tools/doFillNodata.py b/python/plugins/GdalTools/tools/doFillNodata.py new file mode 100644 index 000000000000..5fee01018e87 --- /dev/null +++ b/python/plugins/GdalTools/tools/doFillNodata.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- +from PyQt4.QtCore import * +from PyQt4.QtGui import * +from qgis.core import * +from qgis.gui import * + +from ui_widgetFillNodata import Ui_GdalToolsWidget as Ui_Widget +from widgetBatchBase import GdalToolsBaseBatchWidget as BaseBatchWidget +import GdalTools_utils as Utils + +import os.path + +class GdalToolsDialog( QWidget, Ui_Widget, BaseBatchWidget ): + def __init__( self, iface ): + QWidget.__init__( self ) + self.iface = iface + + self.setupUi( self ) + BaseBatchWidget.__init__( self, self.iface, "gdal_fillnodata.py" ) + + self.inSelector.setType( self.inSelector.FILE_LAYER ) + self.outSelector.setType( self.outSelector.FILE ) + self.maskSelector.setType( self.maskSelector.FILE ) + + self.progressBar.setValue(0) + self.progressBar.hide() + self.formatLabel.hide() + self.formatCombo.hide() + + self.outputFormat = Utils.fillRasterOutputFormat() + + self.setParamsStatus( + [ + ( self.inSelector, SIGNAL( "filenameChanged()" ) ), + ( self.outSelector, SIGNAL( "filenameChanged()" ) ), + ( self.maskSelector, SIGNAL( "filenameChanged()" ), self.maskCheck ), + ( self.distanceSpin, SIGNAL( "valueChanged( int )" ), self.distanceCheck ), + ( self.smoothSpin, SIGNAL( "valueChanged( int )" ), self.smoothCheck ), + ( self.bandSpin, SIGNAL( "valueChanged( int )" ), self.bandCheck ), + ( self.nomaskCheck, SIGNAL( "stateChanged( int )" ) ) + ] + ) + + self.connect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFile ) + self.connect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputFile) + self.connect( self.maskSelector, SIGNAL( "selectClicked()" ), self.fillMaskFile) + self.connect( self.batchCheck, SIGNAL( "stateChanged( int )" ), self.switchToolMode ) + + # add raster filters to combo + self.formatCombo.addItems( Utils.FileFilter.allRastersFilter().split( ";;" ) ) + + + def switchToolMode( self ): + self.setCommandViewerEnabled( not self.batchCheck.isChecked() ) + self.progressBar.setVisible( self.batchCheck.isChecked() ) + self.formatLabel.setVisible( self.batchCheck.isChecked() ) + self.formatCombo.setVisible( self.batchCheck.isChecked() ) + + self.inSelector.setType( self.inSelector.FILE if self.batchCheck.isChecked() else self.inSelector.FILE_LAYER ) + self.outSelector.clear() + + if self.batchCheck.isChecked(): + self.inFileLabel = self.label.text() + self.outFileLabel = self.label_1.text() + self.label.setText( QCoreApplication.translate( "GdalTools", "&Input directory" ) ) + self.label_1.setText( QCoreApplication.translate( "GdalTools", "&Output directory" ) ) + + QObject.disconnect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFile ) + QObject.disconnect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputFile ) + + QObject.connect( self.inSelector, SIGNAL( "selectClicked()" ), self. fillInputDir ) + QObject.connect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputDir ) + else: + self.label.setText( self.inFileLabel ) + self.label_1.setText( self.outFileLabel ) + + QObject.disconnect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputDir ) + QObject.disconnect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputDir ) + + QObject.connect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFile ) + QObject.connect( self.outSelector, SIGNAL( "selectClicked()" ), self.fillOutputFile ) + + def fillInputFile( self ): + lastUsedFilter = Utils.FileFilter.lastUsedRasterFilter() + inputFile = Utils.FileDialog.getOpenFileName( self, + self.tr( "Select the files to analyse" ), + Utils.FileFilter.allRastersFilter(), + lastUsedFilter ) + if inputFile.isEmpty(): + return + Utils.FileFilter.setLastUsedRasterFilter( lastUsedFilter ) + self.inSelector.setFilename( inputFile ) + + def fillOutputFile( self ): + lastUsedFilter = Utils.FileFilter.lastUsedRasterFilter() + outputFile = Utils.FileDialog.getSaveFileName( self, self.tr( "Select the raster file to save the results to" ), Utils.FileFilter.allRastersFilter(), lastUsedFilter ) + if outputFile.isEmpty(): + return + Utils.FileFilter.setLastUsedRasterFilter( lastUsedFilter ) + + self.outputFormat = Utils.fillRasterOutputFormat( lastUsedFilter, outputFile ) + self.outSelector.setFilename( outputFile ) + + def fillMaskFile( self ): + lastUsedFilter = Utils.FileFilter.lastUsedRasterFilter() + inputFile = Utils.FileDialog.getOpenFileName( self, + self.tr( "Select the files to analyse" ), + Utils.FileFilter.allRastersFilter(), + lastUsedFilter ) + if inputFile.isEmpty(): + return + Utils.FileFilter.setLastUsedRasterFilter( lastUsedFilter ) + self.maskSelector.setFilename( inputFile ) + + def fillInputDir( self ): + inputDir = Utils.FileDialog.getExistingDirectory( self, self.tr( "Select the input directory with files" )) + if inputDir.isEmpty(): + return + self.inSelector.setFilename( inputDir ) + + def fillOutputDir( self ): + outputDir = Utils.FileDialog.getExistingDirectory( self, self.tr( "Select the output directory to save the results to" ) ) + if outputDir.isEmpty(): + return + self.outSelector.setFilename( outputDir ) + + def getArguments(self): + arguments = QStringList() + maskFile = self.maskSelector.filename() + if self.distanceCheck.isChecked() and self.distanceSpin.value() != 0: + arguments << "-md" + arguments << self.distanceSpin.text() + if self.smoothCheck.isChecked() and self.smoothSpin.value() != 0: + arguments << "-si" + arguments << str( self.smoothSpin.value() ) + if self.bandCheck.isChecked() and self.bandSpin.value() != 0: + arguments << "-b" + arguments << str( self.bandSpin.value() ) + if self.maskCheck.isChecked() and not maskFile.isEmpty(): + arguments << "-mask" + arguments << maskFile + if self.nomaskCheck.isChecked(): + arguments << "-nomask" + if self.isBatchEnabled(): + if self.formatCombo.currentIndex() != 0: + arguments << "-of" + arguments << Utils.fillRasterOutputFormat( self.formatCombo.currentText() ) + return arguments + else: + outputFn = self.getOutputFileName() + if not outputFn.isEmpty(): + arguments << "-of" + arguments << self.outputFormat + arguments << self.getInputFileName() + arguments << outputFn + return arguments + + def onLayersChanged( self ): + self.inSelector.setLayers( Utils.LayerRegistry.instance().getRasterLayers() ) + + def getInputFileName(self): + return self.inSelector.filename() + + def getOutputFileName(self): + return self.outSelector.filename() + + def addLayerIntoCanvas(self, fileInfo): + self.iface.addRasterLayer(fileInfo.filePath()) + + def isBatchEnabled(self): + return self.batchCheck.isChecked() + + def setProgressRange(self, maximum): + self.progressBar.setRange(0, maximum) + + def updateProgress(self, index, total): + if index < total: + self.progressBar.setValue( index + 1 ) + else: + self.progressBar.setValue( 0 ) + + def batchRun(self): + exts = self.formatCombo.currentText().remove( QRegExp('^.*\(') ).remove( QRegExp('\).*$') ).split( " " ) + if not exts.isEmpty() and exts != "*" and exts != "*.*": + outExt = exts[ 0 ].remove( "*" ) + else: + outExt = ".tif" + + self.base.enableRun( False ) + self.base.setCursor( Qt.WaitCursor ) + + inDir = self.getInputFileName() + outDir = self.getOutputFileName() + + extensions = Utils.getRasterExtensions() + workDir = QDir( inDir ) + workDir.setFilter( QDir.Files | QDir.NoSymLinks | QDir.NoDotAndDotDot ) + workDir.setNameFilters( extensions ) + files = workDir.entryList() + + self.inFiles = [] + self.outFiles = [] + + for f in files: + self.inFiles.append( inDir + "/" + f ) + if outDir != None: + outFile = f.replace( QRegExp( "\.[a-zA-Z0-9]{2,4}" ), outExt ) + self.outFiles.append( outDir + "/" + outFile ) + + self.errors = QStringList() + self.batchIndex = 0 + self.batchTotal = len( self.inFiles ) + self.setProgressRange( self.batchTotal ) + + self.runItem( self.batchIndex, self.batchTotal ) diff --git a/python/plugins/GdalTools/tools/widgetFillNodata.ui b/python/plugins/GdalTools/tools/widgetFillNodata.ui new file mode 100644 index 000000000000..bdc42a1462fb --- /dev/null +++ b/python/plugins/GdalTools/tools/widgetFillNodata.ui @@ -0,0 +1,159 @@ + + + GdalToolsWidget + + + + 0 + 0 + 368 + 300 + + + + + 0 + 0 + + + + Fill Nodata + + + + + + Batch mode (for processing whole directory) + + + + + + + &Input Layer + + + inSelector + + + + + + + + + + &Output file + + + outSelector + + + + + + + + + + QFrame::NoFrame + + + Output format + + + + + + + + 0 + 0 + + + + + + + + Search distance + + + + + + + 1 + + + 1000000 + + + 100 + + + + + + + Smooth iterations + + + + + + + 0 + + + 0 + + + + + + + Band to operate on + + + + + + + 1 + + + + + + + Validity mask + + + + + + + + + + Do not use the default validity mask + + + + + + + + + + + GdalToolsInOutSelector + QWidget +
inOutSelector
+ 1 +
+
+ + +