mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
add cutline option to clipper to fix #3066
git-svn-id: http://svn.osgeo.org/qgis/trunk@15712 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
aeb751988b
commit
adbcbcbb76
@ -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,27 +133,31 @@ class LayerRegistry(QObject):
|
||||
LayerRegistry.layers = []
|
||||
self.emit( SIGNAL( "layersChanged" ) )
|
||||
|
||||
def getRasterLayers(self):
|
||||
layers = []
|
||||
names = []
|
||||
@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
|
||||
|
||||
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)
|
||||
def getRasterLayers(self):
|
||||
layers = filter( self.isRaster, LayerRegistry.layers )
|
||||
names = map( lambda x: x.name(), layers )
|
||||
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()
|
||||
@ -271,6 +271,30 @@ def getRasterSRS( parent, fileName ):
|
||||
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
|
||||
|
@ -37,6 +37,7 @@ class GdalToolsBaseDialog(QDialog, Ui_Dialog):
|
||||
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,19 +52,19 @@ class GdalToolsBaseDialog(QDialog, Ui_Dialog):
|
||||
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.arguments = QStringList()
|
||||
self.helpFileName = cmd + ".html"
|
||||
|
||||
def reject(self):
|
||||
if self.process.state() != QProcess.NotRunning:
|
||||
|
@ -20,34 +20,56 @@ class GdalToolsDialog(QWidget, Ui_Widget, BasePluginWidget):
|
||||
|
||||
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 @@ class GdalToolsDialog(QWidget, Ui_Widget, BasePluginWidget):
|
||||
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 @@ class GdalToolsDialog(QWidget, Ui_Widget, BasePluginWidget):
|
||||
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 @@ class GdalToolsDialog(QWidget, Ui_Widget, BasePluginWidget):
|
||||
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 @@ class GdalToolsDialog(QWidget, Ui_Widget, BasePluginWidget):
|
||||
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())
|
||||
|
||||
|
@ -110,29 +110,6 @@ class GdalToolsDialog(QWidget, Ui_Widget, BasePluginWidget):
|
||||
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 @@ class GdalToolsDialog(QWidget, Ui_Widget, BasePluginWidget):
|
||||
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
|
||||
|
||||
|
@ -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,11 +109,96 @@
|
||||
<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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user