| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| class QgsVectorFieldSymbolLayer: QgsMarkerSymbolLayerV2 | ||
| { | ||
| %TypeHeaderCode | ||
| #include <qgsvectorfieldsymbollayer.h> | ||
| %End | ||
| public: | ||
| enum VectorFieldType | ||
| { | ||
| Cartesian = 0, | ||
| Polar, | ||
| Height | ||
| }; | ||
|
|
||
| enum AngleOrientation | ||
| { | ||
| ClockwiseFromNorth = 0, | ||
| CounterclockwiseFromEast | ||
| }; | ||
|
|
||
| enum AngleUnits | ||
| { | ||
| Degrees = 0, | ||
| Radians | ||
| }; | ||
|
|
||
| QgsVectorFieldSymbolLayer(); | ||
| ~QgsVectorFieldSymbolLayer(); | ||
|
|
||
| static QgsSymbolLayerV2* create( const QgsStringMap& properties ); | ||
|
|
||
| QString layerType() const; | ||
|
|
||
| bool setSubSymbol( QgsSymbolV2* symbol ); | ||
| QgsSymbolV2* subSymbol(); | ||
|
|
||
| void renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ); | ||
| void startRender( QgsSymbolV2RenderContext& context ); | ||
| void stopRender( QgsSymbolV2RenderContext& context ); | ||
|
|
||
| QgsSymbolLayerV2* clone() const; | ||
| QgsStringMap properties() const; | ||
|
|
||
| void drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size ); | ||
|
|
||
| QSet<QString> usedAttributes() const; | ||
|
|
||
| //setters and getters | ||
| void setXAttribute( const QString& attribute ); | ||
| QString xAttribute() const; | ||
| void setYAttribute( const QString& attribute ); | ||
| QString yAttribute() const; | ||
| void setScale( double s ); | ||
| double scale() const; | ||
| void setVectorFieldType( VectorFieldType type ); | ||
| VectorFieldType vectorFieldType() const; | ||
| void setAngleOrientation( AngleOrientation orientation ); | ||
| AngleOrientation angleOrientation() const; | ||
| void setAngleUnits( AngleUnits units ); | ||
| AngleUnits angleUnits() const; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <ui version="4.0"> | ||
| <class>GdalToolsWidget</class> | ||
| <widget class="QWidget" name="GdalToolsWidget"> | ||
| <property name="geometry"> | ||
| <rect> | ||
| <x>0</x> | ||
| <y>0</y> | ||
| <width>368</width> | ||
| <height>300</height> | ||
| </rect> | ||
| </property> | ||
| <property name="sizePolicy"> | ||
| <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="windowTitle"> | ||
| <string>Fill Nodata</string> | ||
| </property> | ||
| <layout class="QGridLayout" name="gridLayout"> | ||
| <item row="0" column="0" colspan="2"> | ||
| <widget class="QCheckBox" name="batchCheck"> | ||
| <property name="text"> | ||
| <string>Batch mode (for processing whole directory)</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="1" column="0"> | ||
| <widget class="QLabel" name="label"> | ||
| <property name="text"> | ||
| <string>&Input Layer</string> | ||
| </property> | ||
| <property name="buddy"> | ||
| <cstring>inSelector</cstring> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="1" column="1"> | ||
| <widget class="GdalToolsInOutSelector" name="inSelector" native="true"/> | ||
| </item> | ||
| <item row="2" column="0"> | ||
| <widget class="QLabel" name="label_1"> | ||
| <property name="text"> | ||
| <string>&Output file</string> | ||
| </property> | ||
| <property name="buddy"> | ||
| <cstring>outSelector</cstring> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="2" column="1"> | ||
| <widget class="GdalToolsInOutSelector" name="outSelector" native="true"/> | ||
| </item> | ||
| <item row="3" column="0"> | ||
| <widget class="QLabel" name="formatLabel"> | ||
| <property name="frameShape"> | ||
| <enum>QFrame::NoFrame</enum> | ||
| </property> | ||
| <property name="text"> | ||
| <string>Output format</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="3" column="1"> | ||
| <widget class="QComboBox" name="formatCombo"> | ||
| <property name="sizePolicy"> | ||
| <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="4" column="0"> | ||
| <widget class="QCheckBox" name="distanceCheck"> | ||
| <property name="text"> | ||
| <string>Search distance</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="4" column="1"> | ||
| <widget class="QSpinBox" name="distanceSpin"> | ||
| <property name="minimum"> | ||
| <number>1</number> | ||
| </property> | ||
| <property name="maximum"> | ||
| <number>1000000</number> | ||
| </property> | ||
| <property name="value"> | ||
| <number>100</number> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="5" column="0"> | ||
| <widget class="QCheckBox" name="smoothCheck"> | ||
| <property name="text"> | ||
| <string>Smooth iterations</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="5" column="1"> | ||
| <widget class="QSpinBox" name="smoothSpin"> | ||
| <property name="minimum"> | ||
| <number>0</number> | ||
| </property> | ||
| <property name="value"> | ||
| <number>0</number> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="6" column="0"> | ||
| <widget class="QCheckBox" name="bandCheck"> | ||
| <property name="text"> | ||
| <string>Band to operate on</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="6" column="1"> | ||
| <widget class="QSpinBox" name="bandSpin"> | ||
| <property name="minimum"> | ||
| <number>1</number> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="7" column="0"> | ||
| <widget class="QCheckBox" name="maskCheck"> | ||
| <property name="text"> | ||
| <string>Validity mask</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="7" column="1"> | ||
| <widget class="GdalToolsInOutSelector" name="maskSelector" native="true"/> | ||
| </item> | ||
| <item row="8" column="0" colspan="2"> | ||
| <widget class="QCheckBox" name="nomaskCheck"> | ||
| <property name="text"> | ||
| <string>Do not use the default validity mask</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="9" column="0" colspan="2"> | ||
| <widget class="QProgressBar" name="progressBar"/> | ||
| </item> | ||
| </layout> | ||
| </widget> | ||
| <customwidgets> | ||
| <customwidget> | ||
| <class>GdalToolsInOutSelector</class> | ||
| <extends>QWidget</extends> | ||
| <header>inOutSelector</header> | ||
| <container>1</container> | ||
| </customwidget> | ||
| </customwidgets> | ||
| <resources/> | ||
| <connections/> | ||
| </ui> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,223 @@ | ||
| # -*- coding: utf-8 -*- | ||
|
|
||
| """ | ||
| *************************************************************************** | ||
| doSpatialIndex.py - build spatial index for vector layers or files | ||
| -------------------------------------- | ||
| Date : 11-Nov-2011 | ||
| Copyright : (C) 2011 by Alexander Bruy | ||
| Email : alexander dot bruy at gmail dot com | ||
| *************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| *************************************************************************** | ||
| """ | ||
|
|
||
| from PyQt4.QtCore import * | ||
| from PyQt4.QtGui import * | ||
|
|
||
| from qgis.core import * | ||
| from qgis.gui import * | ||
|
|
||
| import ftools_utils | ||
|
|
||
| from ui_frmSpatialIndex import Ui_Dialog | ||
|
|
||
| class Dialog( QDialog, Ui_Dialog ): | ||
| def __init__( self, iface ): | ||
| QDialog.__init__( self ) | ||
| self.setupUi( self ) | ||
| self.iface = iface | ||
|
|
||
| self.workThread = None | ||
|
|
||
| self.btnOk = self.buttonBox.button( QDialogButtonBox.Ok ) | ||
| self.btnClose = self.buttonBox.button( QDialogButtonBox.Close ) | ||
|
|
||
| QObject.connect( self.chkExternalFiles, SIGNAL( "stateChanged( int )" ), self.toggleExternalFiles ) | ||
| QObject.connect( self.btnSelectFiles, SIGNAL( "clicked()" ), self.selectFiles ) | ||
| QObject.connect( self.lstLayers, SIGNAL( "itemSelectionChanged()" ), self.updateLayerList ) | ||
| QObject.connect( self.btnSelectAll, SIGNAL( "clicked()" ), self.selectAll ) | ||
| QObject.connect( self.btnSelectNone, SIGNAL( "clicked()" ), self.selectNone ) | ||
| QObject.connect( self.btnClearList, SIGNAL( "clicked()" ), self.clearList ) | ||
|
|
||
| self.manageGui() | ||
|
|
||
| def manageGui( self ): | ||
| self.btnSelectFiles.setEnabled( False ) | ||
| self.btnClearList.setEnabled( False ) | ||
|
|
||
| self.fillLayersList() | ||
|
|
||
| def fillLayersList( self ): | ||
| self.lstLayers.clear() | ||
| layers = ftools_utils.getLayerNames( [ QGis.Line, QGis.Point, QGis.Polygon ] ) | ||
| for lay in layers: | ||
| source = ftools_utils.getVectorLayerByName( lay ).source() | ||
| item = QListWidgetItem( lay, self.lstLayers ) | ||
| item.setData( Qt.UserRole, source ) | ||
| item.setData( Qt.ToolTipRole, source ) | ||
|
|
||
| def toggleExternalFiles( self ): | ||
| if self.chkExternalFiles.isChecked(): | ||
| self.btnSelectFiles.setEnabled( True ) | ||
| self.btnClearList.setEnabled( True ) | ||
| self.btnSelectAll.setEnabled( False ) | ||
| self.btnSelectNone.setEnabled( False ) | ||
|
|
||
| self.lstLayers.clear() | ||
| self.lstLayers.setSelectionMode( QAbstractItemView.NoSelection ) | ||
| self.layers = [] | ||
| else: | ||
| self.btnSelectFiles.setEnabled( False ) | ||
| self.btnClearList.setEnabled( False ) | ||
| self.btnSelectAll.setEnabled( True ) | ||
| self.btnSelectNone.setEnabled( True ) | ||
|
|
||
| self.fillLayersList() | ||
| self.lstLayers.setSelectionMode( QAbstractItemView.ExtendedSelection ) | ||
| self.updateLayerList() | ||
|
|
||
| def updateLayerList( self ): | ||
| self.layers = [] | ||
| selection = self.lstLayers.selectedItems() | ||
| for item in selection: | ||
| self.layers.append( item.text() ) | ||
|
|
||
| def selectFiles( self ): | ||
| filters = QgsProviderRegistry.instance().fileVectorFilters() | ||
| ( files, self.encoding ) = ftools_utils.openDialog( self, filtering = filters, dialogMode = "MultipleFiles" ) | ||
| if files is None: | ||
| return | ||
|
|
||
| self.layers.extend( [ unicode( f ) for f in files ] ) | ||
| self.lstLayers.addItems( files ) | ||
|
|
||
| def selectAll( self ): | ||
| self.lstLayers.selectAll() | ||
|
|
||
| def selectNone( self ): | ||
| self.lstLayers.clearSelection() | ||
|
|
||
| def clearList( self ): | ||
| self.layers = [] | ||
| self.lstLayers.clear() | ||
|
|
||
| def accept( self ): | ||
| QApplication.setOverrideCursor( Qt.WaitCursor ) | ||
| self.btnOk.setEnabled( False ) | ||
|
|
||
| self.workThread = SpatialIdxThread( self.layers, self.chkExternalFiles.isChecked() ) | ||
| self.progressBar.setRange( 0, len( self.layers ) ) | ||
|
|
||
| QObject.connect( self.workThread, SIGNAL( "layerProcessed()" ), self.layerProcessed ) | ||
| QObject.connect( self.workThread, SIGNAL( "processFinished( PyQt_PyObject )" ), self.processFinished ) | ||
| QObject.connect( self.workThread, SIGNAL( "processInterrupted()" ), self.processInterrupted ) | ||
|
|
||
| self.btnClose.setText( self.tr( "Cancel" ) ) | ||
| QObject.disconnect( self.buttonBox, SIGNAL( "rejected()" ), self.reject ) | ||
| QObject.connect( self.btnClose, SIGNAL( "clicked()" ), self.stopProcessing ) | ||
|
|
||
| self.workThread.start() | ||
|
|
||
| def layerProcessed( self ): | ||
| self.progressBar.setValue( self.progressBar.value() + 1 ) | ||
|
|
||
| def processInterrupted( self ): | ||
| self.restoreGui() | ||
|
|
||
| def processFinished( self, errors ): | ||
| self.stopProcessing() | ||
| self.restoreGui() | ||
|
|
||
| if not errors.isEmpty(): | ||
| msg = QString( "Processing of the following layers/files ended with error:<br><br>" ).append( errors.join( "<br>" ) ) | ||
| QErrorMessage( self ).showMessage( msg ) | ||
|
|
||
| QMessageBox.information( self, self.tr( "Finished" ), self.tr( "Processing completed." ) ) | ||
|
|
||
| def stopProcessing( self ): | ||
| if self.workThread != None: | ||
| self.workThread.stop() | ||
| self.workThread = None | ||
|
|
||
| def restoreGui( self ): | ||
| self.progressBar.setValue( 0 ) | ||
| QApplication.restoreOverrideCursor() | ||
| QObject.connect( self.buttonBox, SIGNAL( "rejected()" ), self.reject ) | ||
| self.btnClose.setText( self.tr( "Close" ) ) | ||
| self.btnOk.setEnabled( True ) | ||
|
|
||
| if self.chkExternalFiles.isChecked(): | ||
| self.clearList() | ||
|
|
||
| class SpatialIdxThread( QThread ): | ||
| def __init__( self, layers, isFiles ): | ||
| QThread.__init__( self, QThread.currentThread() ) | ||
| self.layers = layers | ||
| self.isFiles = isFiles | ||
|
|
||
| self.mutex = QMutex() | ||
| self.stopMe = 0 | ||
|
|
||
| self.errors = QStringList() | ||
|
|
||
| def run( self ): | ||
| self.mutex.lock() | ||
| self.stopMe = 0 | ||
| self.mutex.unlock() | ||
|
|
||
| interrupted = False | ||
|
|
||
| if self.isFiles: | ||
| for layer in self.layers: | ||
| vl = QgsVectorLayer( layer, "tmp", "ogr" ) | ||
| provider = vl.dataProvider() | ||
| if provider.capabilities() & QgsVectorDataProvider.CreateSpatialIndex: | ||
| if not provider.createSpatialIndex(): | ||
| self.errors.append( layer ) | ||
| else: | ||
| self.errors.append( layer ) | ||
|
|
||
| self.emit( SIGNAL( "layerProcessed()" ) ) | ||
|
|
||
| self.mutex.lock() | ||
| s = self.stopMe | ||
| self.mutex.unlock() | ||
| if s == 1: | ||
| interrupted = True | ||
| break | ||
| else: | ||
| for layer in self.layers: | ||
| vl = ftools_utils.getVectorLayerByName( layer ) | ||
| provider = vl.dataProvider() | ||
| if provider.capabilities() & QgsVectorDataProvider.CreateSpatialIndex: | ||
| if not provider.createSpatialIndex(): | ||
| self.errors.append( layer ) | ||
| else: | ||
| self.errors.append( layer ) | ||
|
|
||
| self.emit( SIGNAL( "layerProcessed()" ) ) | ||
|
|
||
| self.mutex.lock() | ||
| s = self.stopMe | ||
| self.mutex.unlock() | ||
| if s == 1: | ||
| interrupted = True | ||
| break | ||
|
|
||
| if not interrupted: | ||
| self.emit( SIGNAL( "processFinished( PyQt_PyObject )" ), self.errors ) | ||
| else: | ||
| self.emit( SIGNAL( "processInterrupted()" ) ) | ||
|
|
||
| def stop( self ): | ||
| self.mutex.lock() | ||
| self.stopMe = 1 | ||
| self.mutex.unlock() | ||
|
|
||
| QThread.wait( self ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <ui version="4.0"> | ||
| <class>Dialog</class> | ||
| <widget class="QDialog" name="Dialog"> | ||
| <property name="geometry"> | ||
| <rect> | ||
| <x>0</x> | ||
| <y>0</y> | ||
| <width>351</width> | ||
| <height>272</height> | ||
| </rect> | ||
| </property> | ||
| <property name="windowTitle"> | ||
| <string>Build spatial index</string> | ||
| </property> | ||
| <layout class="QVBoxLayout" name="verticalLayout"> | ||
| <item> | ||
| <layout class="QHBoxLayout" name="horizontalLayout"> | ||
| <item> | ||
| <widget class="QCheckBox" name="chkExternalFiles"> | ||
| <property name="text"> | ||
| <string>Select files from disk</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QPushButton" name="btnSelectFiles"> | ||
| <property name="text"> | ||
| <string>Select files...</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| <item> | ||
| <widget class="QListWidget" name="lstLayers"> | ||
| <property name="editTriggers"> | ||
| <set>QAbstractItemView::NoEditTriggers</set> | ||
| </property> | ||
| <property name="alternatingRowColors"> | ||
| <bool>true</bool> | ||
| </property> | ||
| <property name="selectionMode"> | ||
| <enum>QAbstractItemView::ExtendedSelection</enum> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||
| <item> | ||
| <widget class="QPushButton" name="btnSelectAll"> | ||
| <property name="text"> | ||
| <string>Select all</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QPushButton" name="btnSelectNone"> | ||
| <property name="text"> | ||
| <string>Select none</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QPushButton" name="btnClearList"> | ||
| <property name="text"> | ||
| <string>Clear list</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| <item> | ||
| <widget class="QProgressBar" name="progressBar"> | ||
| <property name="value"> | ||
| <number>0</number> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QDialogButtonBox" name="buttonBox"> | ||
| <property name="orientation"> | ||
| <enum>Qt::Horizontal</enum> | ||
| </property> | ||
| <property name="standardButtons"> | ||
| <set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </widget> | ||
| <resources/> | ||
| <connections> | ||
| <connection> | ||
| <sender>buttonBox</sender> | ||
| <signal>accepted()</signal> | ||
| <receiver>Dialog</receiver> | ||
| <slot>accept()</slot> | ||
| <hints> | ||
| <hint type="sourcelabel"> | ||
| <x>248</x> | ||
| <y>254</y> | ||
| </hint> | ||
| <hint type="destinationlabel"> | ||
| <x>157</x> | ||
| <y>274</y> | ||
| </hint> | ||
| </hints> | ||
| </connection> | ||
| <connection> | ||
| <sender>buttonBox</sender> | ||
| <signal>rejected()</signal> | ||
| <receiver>Dialog</receiver> | ||
| <slot>reject()</slot> | ||
| <hints> | ||
| <hint type="sourcelabel"> | ||
| <x>316</x> | ||
| <y>260</y> | ||
| </hint> | ||
| <hint type="destinationlabel"> | ||
| <x>286</x> | ||
| <y>274</y> | ||
| </hint> | ||
| </hints> | ||
| </connection> | ||
| </connections> | ||
| </ui> |