[QGIS Commit] r15712 - trunk/qgis/python/plugins/GdalTools/tools

svn_qgis at osgeo.org svn_qgis at osgeo.org
Fri Apr 15 13:58:00 EDT 2011


Author: brushtyler
Date: 2011-04-15 10:58:00 -0700 (Fri, 15 Apr 2011)
New Revision: 15712

Modified:
   trunk/qgis/python/plugins/GdalTools/tools/GdalTools_utils.py
   trunk/qgis/python/plugins/GdalTools/tools/dialogBase.py
   trunk/qgis/python/plugins/GdalTools/tools/doClipper.py
   trunk/qgis/python/plugins/GdalTools/tools/doMerge.py
   trunk/qgis/python/plugins/GdalTools/tools/widgetClipper.ui
Log:
add cutline option to clipper to fix #3066


Modified: trunk/qgis/python/plugins/GdalTools/tools/GdalTools_utils.py
===================================================================
--- trunk/qgis/python/plugins/GdalTools/tools/GdalTools_utils.py	2011-04-15 17:09:46 UTC (rev 15711)
+++ trunk/qgis/python/plugins/GdalTools/tools/GdalTools_utils.py	2011-04-15 17:58:00 UTC (rev 15712)
@@ -1,10 +1,6 @@
 # -*- coding: utf-8 -*-
 
 # Utility functions
-# -------------------------------------------------
-# getLastUsedDir()
-# setLastUsedDir( QString *file_or_dir path )
-# -------------------------------------------------
 
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *
@@ -137,28 +133,32 @@
        LayerRegistry.layers = []
        self.emit( SIGNAL( "layersChanged" ) )
 
+    @classmethod
+    def isRaster(self, layer):
+      # only gdal raster layers
+      if layer.type() != layer.RasterLayer:
+        return False
+      if layer.usesProvider() and layer.providerKey() != 'gdal':
+        return False
+      return True
+
     def getRasterLayers(self):
-      layers = []
-      names = []
+      layers = filter( self.isRaster, LayerRegistry.layers )
+      names = map( lambda x: x.name(), layers )
+      return ( layers, names )
 
-      for layer in LayerRegistry.layers:
-        # only gdal raster layers
-        if layer.type() == layer.RasterLayer:
-          if layer.usesProvider() and layer.providerKey() != 'gdal':
-            continue
-          layers.append(layer)
-          names.append(layer.name())
-      return (layers, names)
+    @classmethod
+    def isVector(self, layer):
+      if layer.type() != layer.VectorLayer:
+        return False
+      return True
 
     def getVectorLayers(self):
-      layers = []
-      names = []
-      for layer in LayerRegistry.layers:
-        if layer.type() == layer.VectorLayer:
-          layers.append(layer)
-          names.append(layer.name())
-      return (layers, names)
+      layers = filter( self.isVector, LayerRegistry.layers )
+      names = map( lambda x: x.name(), layers )
+      return ( layers, names )
 
+
 def getRasterFiles(path, recursive=False):
   rasters = QStringList()
   if not QFileInfo(path).exists():
@@ -271,6 +271,30 @@
     srs = info[ 0 ] + ":" + info[ 1 ]
     return srs
 
+def getRasterExtent(parent, fileName):
+    processSRS = QProcess( parent )
+    processSRS.start( "gdalinfo", QStringList() << fileName, QIODevice.ReadOnly )
+    arr = QByteArray()
+    if processSRS.waitForFinished():
+      arr = processSRS.readAllStandardOutput()
+      processSRS.close()
+      
+    if arr.isEmpty():
+      return
+      
+    info = QString( arr ).split( "\n" )
+    ulCoord = info[ info.indexOf( QRegExp( "^Upper\sLeft.*" ) ) ].simplified()
+    lrCoord = info[ info.indexOf( QRegExp( "^Lower\sRight.*" ) ) ].simplified()
+    ulCoord = ulCoord[ulCoord.indexOf( "(" ) + 1 : ulCoord.indexOf( ")" ) - 1].split( "," )
+    lrCoord = lrCoord[lrCoord.indexOf( "(" ) + 1 : lrCoord.indexOf( ")" ) - 1].split( "," )
+    xUL = ulCoord[0].toDouble()[0]
+    yUL = ulCoord[1].toDouble()[0]
+    xLR = lrCoord[0].toDouble()[0]
+    yLR = lrCoord[1].toDouble()[0]
+
+    return QgsRectangle( xUL, yLR, xLR, yUL )
+
+
 # This class is used to replace the QFileDialog class.
 # Its static methods are used in place of the respective QFileDialog ones to:
 # 1. set the last used directory

Modified: trunk/qgis/python/plugins/GdalTools/tools/dialogBase.py
===================================================================
--- trunk/qgis/python/plugins/GdalTools/tools/dialogBase.py	2011-04-15 17:09:46 UTC (rev 15711)
+++ trunk/qgis/python/plugins/GdalTools/tools/dialogBase.py	2011-04-15 17:58:00 UTC (rev 15712)
@@ -37,6 +37,7 @@
       self.connect(self.process, SIGNAL("finished(int, QProcess::ExitStatus)"), self.processFinished)
 
       self.setupUi(self)
+      self.arguments = QStringList()
 
       self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
       self.connect(self.buttonBox, SIGNAL("accepted()"), self.accept)
@@ -51,20 +52,20 @@
       self.plugin.setFocus()
 
       self.setWindowTitle(pluginName)
+      self.setPluginCommand(pluginCommand)
 
+  def setPluginCommand(self, cmd):
       # on Windows replace the .py with .bat extension
-      if platform.system() == "Windows" and pluginCommand[-3:] == ".py":
-        self.command = pluginCommand[:-3] + ".bat"
+      if platform.system() == "Windows" and cmd[-3:] == ".py":
+        self.command = cmd[:-3] + ".bat"
       else:
-        self.command = pluginCommand
+        self.command = cmd
 
-      if pluginCommand[-3:] == ".py":
-        self.helpFileName = pluginCommand[:-3] + ".html"
+      if cmd[-3:] == ".py":
+        self.helpFileName = cmd[:-3] + ".html"
       else:
-        self.helpFileName = pluginCommand + ".html"
+        self.helpFileName = cmd + ".html"
 
-      self.arguments = QStringList()
-
   def reject(self):
       if self.process.state() != QProcess.NotRunning:
         ret = QMessageBox.warning(self, self.tr( "Warning" ), self.tr( "The command is still running. \nDo you want terminate it anyway?" ), QMessageBox.Yes | QMessageBox.No)

Modified: trunk/qgis/python/plugins/GdalTools/tools/doClipper.py
===================================================================
--- trunk/qgis/python/plugins/GdalTools/tools/doClipper.py	2011-04-15 17:09:46 UTC (rev 15711)
+++ trunk/qgis/python/plugins/GdalTools/tools/doClipper.py	2011-04-15 17:58:00 UTC (rev 15712)
@@ -20,34 +20,56 @@
 
       self.extentSelector.setCanvas(self.canvas)
       self.outputFormat = Utils.fillRasterOutputFormat()
+      self.layers = []
+      self.maskLayers = []
 
       self.setParamsStatus(
         [
           (self.inputLayerCombo, [SIGNAL("currentIndexChanged(int)"), SIGNAL("editTextChanged(const QString &)")] ),
           (self.outputFileEdit, SIGNAL("textChanged(const QString &)")), 
-          (self.noDataSpin, SIGNAL("valueChanged(int)"), self.noDataCheck),
-          ( self.extentSelector, [SIGNAL("selectionStarted()"), SIGNAL("newExtentDefined()")] )
+          (self.noDataSpin, SIGNAL("valueChanged(int)"), self.noDataCheck, "1.7.0"),
+          (self.maskLayerCombo, [SIGNAL("currentIndexChanged(int)"), SIGNAL("editTextChanged(const QString &)")], self.maskModeRadio, "1.6.0"),
+          ( self.extentSelector, [SIGNAL("selectionStarted()"), SIGNAL("newExtentDefined()")] ), 
+          (self.modeStackedWidget, SIGNAL("currentIndexChanged(int)"))
         ]
       )
 
       self.connect(self.selectInputFileButton, SIGNAL("clicked()"), self.fillInputFileEdit)
       self.connect(self.selectOutputFileButton, SIGNAL("clicked()"), self.fillOutputFileEdit)
+      self.connect(self.selectMaskFileButton, SIGNAL("clicked()"), self.fillMaskFileEdit)
       self.connect(self.extentSelector, SIGNAL("newExtentDefined()"), self.checkRun)
       self.connect(self.extentSelector, SIGNAL("selectionStarted()"), self.checkRun)
 
+      self.connect(self.extentModeRadio, SIGNAL("toggled(bool)"), self.switchClippingMode)
+
   def show_(self):
-      self.extentSelector.start()
+      self.switchClippingMode()
       BasePluginWidget.show_(self)
 
   def onClosing(self):
       self.extentSelector.stop()
       BasePluginWidget.onClosing(self)
 
+  def switchClippingMode(self):
+      if self.extentModeRadio.isChecked():
+        index = 0
+        self.extentSelector.start()
+      else:
+        self.extentSelector.stop()
+        index = 1
+      self.modeStackedWidget.setCurrentIndex( index )
+      self.checkRun()
+
   def checkRun(self):
-      self.base.enableRun( self.extentSelector.getExtent() != None )
+      if self.extentModeRadio.isChecked():
+        enabler = self.extentSelector.isCoordsValid()
+      else:
+        enabler = not self.getMaskFileName().isEmpty()
+      self.base.enableRun( enabler )
 
   def onLayersChanged(self):
       self.fillInputLayerCombo()
+      self.fillMaskLayerCombo()
 
   def fillInputLayerCombo(self):
       self.inputLayerCombo.clear()
@@ -74,12 +96,35 @@
       self.outputFormat = Utils.fillRasterOutputFormat(lastUsedFilter, outputFile)
       self.outputFileEdit.setText(outputFile)
 
+  def fillMaskLayerCombo(self):
+      self.maskLayerCombo.clear()
+      self.maskLayers = filter( lambda x: x.geometryType() == QGis.Polygon, Utils.LayerRegistry.instance().getVectorLayers()[0] )
+      self.maskLayerCombo.addItems( map( lambda x: x.name(), self.maskLayers ) )
+      self.checkRun()
+
+  def fillMaskFileEdit( self ):
+      lastUsedFilter = Utils.FileFilter.lastUsedVectorFilter()
+      maskFile = Utils.FileDialog.getOpenFileName(self, self.tr( "Select the mask file" ), Utils.FileFilter.allVectorsFilter(), lastUsedFilter )
+      if maskFile.isEmpty():
+        return
+      Utils.FileFilter.setLastUsedVectorFilter(lastUsedFilter)
+
+      self.maskLayerCombo.setCurrentIndex(-1)
+      self.maskLayerCombo.setEditText( maskFile )
+      self.checkRun()
+
   def getArguments(self):
+      if not self.extentModeRadio.isChecked():
+        return self.getArgsModeMask()
+      return self.getArgsModeExtent()
+
+  def getArgsModeExtent(self):
+      self.base.setPluginCommand( "gdal_translate" )
       arguments = QStringList()
       if self.noDataCheck.isChecked():
         arguments << "-a_nodata"
         arguments << str(self.noDataSpin.value())
-      if self.extentSelector.isCoordsValid():
+      if self.extentModeRadio.isChecked() and self.extentSelector.isCoordsValid():
         rect = self.extentSelector.getExtent()
         if rect != None:
           arguments << "-projwin"
@@ -87,6 +132,8 @@
           arguments << str(rect.yMaximum())
           arguments << str(rect.xMaximum())
           arguments << str(rect.yMinimum())
+      if Utils.GdalConfig.version() >= "1.7.0":
+        arguments << "-q"
       if not self.getOutputFileName().isEmpty():
         arguments << "-of"
         arguments << self.outputFormat
@@ -94,6 +141,28 @@
       arguments << self.getOutputFileName()
       return arguments
 
+  def getArgsModeMask(self):
+      self.base.setPluginCommand( "gdalwarp" )
+      arguments = QStringList()
+      if self.noDataCheck.isChecked():
+        arguments << "-dstnodata"
+        arguments << str(self.noDataSpin.value())
+      if self.maskModeRadio.isChecked():
+        mask = self.getMaskFileName()
+        if not mask.isEmpty():
+          arguments << "-q"
+          arguments << "-cutline"
+          arguments << mask
+          arguments << "-dstalpha"
+
+      outputFn = self.getOutputFileName()
+      if not outputFn.isEmpty():
+        arguments << "-of"
+        arguments << self.outputFormat
+      arguments << self.getInputFileName()
+      arguments << outputFn
+      return arguments
+
   def getOutputFileName(self):
       return self.outputFileEdit.text()
 
@@ -102,6 +171,11 @@
         return self.layers[self.inputLayerCombo.currentIndex()].source()
       return self.inputLayerCombo.currentText()
 
+  def getMaskFileName(self):
+      if self.maskLayerCombo.currentIndex() >= 0:
+        return self.maskLayers[self.maskLayerCombo.currentIndex()].source()
+      return self.maskLayerCombo.currentText()
+
   def addLayerIntoCanvas(self, fileInfo):
       self.iface.addRasterLayer(fileInfo.filePath())
 

Modified: trunk/qgis/python/plugins/GdalTools/tools/doMerge.py
===================================================================
--- trunk/qgis/python/plugins/GdalTools/tools/doMerge.py	2011-04-15 17:09:46 UTC (rev 15711)
+++ trunk/qgis/python/plugins/GdalTools/tools/doMerge.py	2011-04-15 17:58:00 UTC (rev 15712)
@@ -110,29 +110,6 @@
   def addLayerIntoCanvas(self, fileInfo):
       self.iface.addRasterLayer(fileInfo.filePath())
 
-  def getRectangle( self, file ):
-    processSRS = QProcess( self )
-    processSRS.start( "gdalinfo", QStringList() << file, QIODevice.ReadOnly )
-    arr = QByteArray()
-    if processSRS.waitForFinished():
-      arr = processSRS.readAllStandardOutput()
-      processSRS.close()
-      
-    if arr.isEmpty():
-      return None
-      
-    info = QString( arr ).split( "\n" )
-    ulCoord = info[ info.indexOf( QRegExp( "^Upper\sLeft.*" ) ) ].simplified()
-    lrCoord = info[ info.indexOf( QRegExp( "^Lower\sRight.*" ) ) ].simplified()
-    ulCoord = ulCoord[ulCoord.indexOf( "(" ) + 1 : ulCoord.indexOf( ")" ) - 1].split( "," )
-    lrCoord = lrCoord[lrCoord.indexOf( "(" ) + 1 : lrCoord.indexOf( ")" ) - 1].split( "," )
-    xUL = ulCoord[0].toDouble()[0]
-    yUL = ulCoord[1].toDouble()[0]
-    xLR = lrCoord[0].toDouble()[0]
-    yLR = lrCoord[1].toDouble()[0]
-
-    return QgsRectangle( xUL, yLR, xLR, yUL )
-
   def getExtent( self ):
     files = self.inputFilesEdit.text().split( "," )
 
@@ -140,11 +117,12 @@
     res = rect2 = None
     for fileName in files:
       if res == None:
-        res = self.getRectangle( fileName )
+        res = Utils.getRasterExtent( self, fileName )
         continue
-      rect2 = self.getRectangle( fileName )
+      rect2 = Utils.getRasterExtent( self, fileName )
       if rect2 == None:
         continue
       res = res.intersect( rect2 )
 
     return res
+

Modified: trunk/qgis/python/plugins/GdalTools/tools/widgetClipper.ui
===================================================================
--- trunk/qgis/python/plugins/GdalTools/tools/widgetClipper.ui	2011-04-15 17:09:46 UTC (rev 15711)
+++ trunk/qgis/python/plugins/GdalTools/tools/widgetClipper.ui	2011-04-15 17:58:00 UTC (rev 15712)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>338</width>
-    <height>172</height>
+    <height>227</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -109,12 +109,97 @@
    <item>
     <widget class="QGroupBox" name="extentGroup">
      <property name="title">
-      <string>Extent</string>
+      <string>Clipping mode</string>
      </property>
      <layout class="QGridLayout" name="gridLayout_2">
       <item row="0" column="0">
-       <widget class="GdalToolsExtentSelector" name="extentSelector" native="true"/>
+       <widget class="QRadioButton" name="extentModeRadio">
+        <property name="text">
+         <string>Extent</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
       </item>
+      <item row="0" column="1">
+       <widget class="QRadioButton" name="maskModeRadio">
+        <property name="text">
+         <string>Mask layer</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0" colspan="2">
+       <widget class="QStackedWidget" name="modeStackedWidget">
+        <property name="currentIndex">
+         <number>0</number>
+        </property>
+        <widget class="QWidget" name="page">
+         <layout class="QGridLayout" name="gridLayout_3">
+          <property name="margin">
+           <number>0</number>
+          </property>
+          <item row="0" column="0">
+           <widget class="GdalToolsExtentSelector" name="extentSelector" native="true"/>
+          </item>
+         </layout>
+        </widget>
+        <widget class="QWidget" name="page_2">
+         <layout class="QGridLayout" name="gridLayout_4">
+          <property name="margin">
+           <number>0</number>
+          </property>
+          <item row="0" column="1">
+           <layout class="QHBoxLayout" name="horizontalLayout_5">
+            <item>
+             <widget class="QComboBox" name="maskLayerCombo">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="editable">
+               <bool>true</bool>
+              </property>
+              <property name="insertPolicy">
+               <enum>QComboBox::NoInsert</enum>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QPushButton" name="selectMaskFileButton">
+              <property name="text">
+               <string>Select...</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item row="1" column="0">
+           <spacer name="verticalSpacer">
+            <property name="orientation">
+             <enum>Qt::Vertical</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>20</width>
+              <height>40</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="0" column="0">
+           <widget class="QLabel" name="label">
+            <property name="text">
+             <string>Mask layer</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>



More information about the QGIS-commit mailing list