[QGIS Commit] r14678 - trunk/qgis/python/plugins/fTools/tools

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sun Nov 14 19:33:57 EST 2010


Author: cfarmer
Date: 2010-11-14 16:33:57 -0800 (Sun, 14 Nov 2010)
New Revision: 14678

Added:
   trunk/qgis/python/plugins/fTools/tools/doSimplify.py
   trunk/qgis/python/plugins/fTools/tools/frmSimplify.ui
Log:
commit missing files for new simplify implementation by alexbruy

Added: trunk/qgis/python/plugins/fTools/tools/doSimplify.py
===================================================================
--- trunk/qgis/python/plugins/fTools/tools/doSimplify.py	                        (rev 0)
+++ trunk/qgis/python/plugins/fTools/tools/doSimplify.py	2010-11-15 00:33:57 UTC (rev 14678)
@@ -0,0 +1,272 @@
+# -*- coding: utf-8 -*-
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+from qgis.core import *
+from qgis.gui import *
+
+import ftools_utils
+
+from ui_frmSimplify import Ui_Dialog
+
+class Dialog( QDialog, Ui_Dialog ):
+  def __init__( self, iface ):
+    QDialog.__init__( self )
+    self.setupUi( self )
+    self.iface = iface
+
+    self.simplifyThread = None
+
+    self.okButton = self.buttonBox.button( QDialogButtonBox.Ok )
+    self.closeButton = self.buttonBox.button( QDialogButtonBox.Close )
+
+    QObject.connect( self.writeShapefileCheck, SIGNAL( "stateChanged( int )" ), self.updateGui )
+    QObject.connect( self.btnSelectOutputFile, SIGNAL( "clicked()" ), self.selectOutputFile )
+
+    self.manageGui()
+
+  def manageGui( self ):
+    layers = ftools_utils.getLayerNames( [ QGis.Polygon, QGis.Line ] )
+    self.cmbInputLayer.addItems( layers )
+
+  def updateGui( self ):
+    if self.writeShapefileCheck.isChecked():
+      self.outputFileEdit.setEnabled( True )
+      self.btnSelectOutputFile.setEnabled( True )
+      self.addToCanvasCheck.setEnabled( True )
+    else:
+      self.outputFileEdit.setEnabled( False )
+      self.btnSelectOutputFile.setEnabled( False )
+      self.addToCanvasCheck.setEnabled( False )
+    self.encoding = None
+
+  def selectOutputFile( self ):
+    self.outputFileEdit.clear()
+    (self.shapefileName, self.encoding) = ftools_utils.saveDialog(self)
+    if self.shapefileName is None or self.encoding is None:
+      return
+    self.outputFileEdit.setText(QString(self.shapefileName))
+
+  def accept( self ):
+    vLayer = ftools_utils.getVectorLayerByName( self.cmbInputLayer.currentText() )
+
+    QApplication.setOverrideCursor( Qt.WaitCursor )
+    self.okButton.setEnabled( False )
+
+    if self.writeShapefileCheck.isChecked():
+      outFileName = self.outputFileEdit.text()
+      outFile = QFile( outFileName )
+      if outFile.exists():
+        if not QgsVectorFileWriter.deleteShapeFile( outFileName ):
+          QmessageBox.warning( self, self.tr( "Delete error" ), self.tr( "Can't delete file %1" ).arg( outFileName ) )
+          return
+      self.simplifyThread = GeneralizationThread( vLayer, self.useSelectionCheck.isChecked(), self.toleranceSpin.value(), True, outFileName, self.encoding )
+    else:
+      self.simplifyThread = GeneralizationThread( vLayer, self.useSelectionCheck.isChecked(), self.toleranceSpin.value(), False, None, None  )
+    QObject.connect( self.simplifyThread, SIGNAL( "rangeCalculated( PyQt_PyObject )" ), self.setProgressRange )
+    QObject.connect( self.simplifyThread, SIGNAL( "featureProcessed()" ), self.featureProcessed )
+    QObject.connect( self.simplifyThread, SIGNAL( "generalizationFinished( PyQt_PyObject )" ), self.generalizationFinished )
+    QObject.connect( self.simplifyThread, SIGNAL( "generalizationInterrupted()" ), self.generalizationInterrupted )
+
+    self.closeButton.setText( self.tr( "Cancel" ) )
+    QObject.disconnect( self.buttonBox, SIGNAL( "rejected()" ), self.reject )
+    QObject.connect( self.closeButton, SIGNAL( "clicked()" ), self.stopProcessing )
+
+    self.simplifyThread.start()
+
+  def setProgressRange( self, max ):
+    self.progressBar.setRange( 0, max )
+
+  def featureProcessed( self ):
+    self.progressBar.setValue( self.progressBar.value() + 1 )
+
+  def generalizationFinished( self, pointsCount ):
+    self.stopProcessing()
+
+    QMessageBox.information( self,
+                             self.tr( "Simplify results" ),
+                             self.tr( "There were %1 vertices in original dataset which\nwere reduced to %2 vertices after simplification" )
+                             .arg( pointsCount[ 0 ] )
+                             .arg( pointsCount[ 1 ] ) )
+
+    self.restoreGui()
+    if self.addToCanvasCheck.isEnabled() and self.addToCanvasCheck.isChecked():
+      if not ftools_utils.addShapeToCanvas( unicode( self.shapefileName ) ):
+        QMessageBox.warning( self, self.tr( "Merging" ),
+                             self.tr( "Error loading output shapefile:\n%1" )
+                             .arg( unicode( self.shapefileName ) ) )
+
+    self.iface.mapCanvas().refresh()
+    #self.restoreGui()
+
+  def generalizationInterrupted( self ):
+    self.restoreGui()
+
+  def stopProcessing( self ):
+    if self.simplifyThread != None:
+      self.simplifyThread.stop()
+      self.simplifyThread = None
+
+  def restoreGui( self ):
+    self.progressBar.setValue( 0 )
+    QApplication.restoreOverrideCursor()
+    QObject.connect( self.buttonBox, SIGNAL( "rejected()" ), self.reject )
+    self.closeButton.setText( self.tr( "Close" ) )
+    self.okButton.setEnabled( True )
+
+def geomVertexCount( geometry ):
+  geomType = geometry.type()
+  if geomType == 1: # line
+    points = geometry.asPolyline()
+    return len( points )
+  elif geomType == 2: # polygon
+    polylines = geometry.asPolygon()
+    points = []
+    for l in polylines:
+      points.extend( l )
+    return len( points )
+  else:
+    return None
+
+class GeneralizationThread( QThread ):
+  def __init__( self, inputLayer, useSelection, tolerance, writeShape, shapePath, shapeEncoding ):
+    QThread.__init__( self, QThread.currentThread() )
+    self.inputLayer = inputLayer
+    self.useSelection = useSelection
+    self.tolerance = tolerance
+    self.writeShape = writeShape
+    self.outputFileName = shapePath
+    self.outputEncoding = shapeEncoding
+
+    self.shapeFileWriter = None
+    self.pointsBefore = 0
+    self.pointsAfter = 0
+
+    self.mutex = QMutex()
+    self.stopMe = 0
+
+  def run( self ):
+    self.mutex.lock()
+    self.stopMe = 0
+    self.mutex.unlock()
+
+    interrupted = False
+
+    shapeFileWriter = None
+
+    if self.writeShape:
+      vProvider = self.inputLayer.dataProvider()
+      allAttrs = vProvider.attributeIndexes()
+      vProvider.select( allAttrs )
+      shapeFields = vProvider.fields()
+      crs = vProvider.crs()
+      wkbType = self.inputLayer.wkbType()
+      if not crs.isValid():
+        crs = None
+      shapeFileWriter = QgsVectorFileWriter( self.outputFileName, self.outputEncoding, shapeFields, wkbType, crs )
+      featureId = 0
+      if self.useSelection:
+        selection = self.inputLayer.selectedFeatures()
+        self.emit( SIGNAL( "rangeCalculated( PyQt_PyObject )" ), len( selection ) )
+        for f in selection:
+          featGeometry = QgsGeometry( f.geometry() )
+          attrMap = f.attributeMap()
+          self.pointsBefore += geomVertexCount( featGeometry )
+          newGeometry = featGeometry.simplify( self.tolerance )
+          self.pointsAfter += geomVertexCount( newGeometry )
+          feature = QgsFeature()
+          feature.setGeometry( newGeometry )
+          feature.setAttributeMap( attrMap )
+          shapeFileWriter.addFeature( feature )
+          featureId += 1
+          self.emit( SIGNAL( "featureProcessed()" ) )
+
+          self.mutex.lock()
+          s = self.stopMe
+          self.mutex.unlock()
+          if s == 1:
+            interrupted = True
+            break
+      else:
+        self.emit( SIGNAL( "rangeCalculated( PyQt_PyObject )" ), vProvider.featureCount() )
+        f = QgsFeature()
+        while vProvider.nextFeature( f ):
+          featGeometry = QgsGeometry( f.geometry() )
+          attrMap = f.attributeMap()
+          self.pointsBefore += geomVertexCount( featGeometry )
+          newGeometry = featGeometry.simplify( self.tolerance )
+          self.pointsAfter += geomVertexCount( newGeometry )
+          feature = QgsFeature()
+          feature.setGeometry( newGeometry )
+          feature.setAttributeMap( attrMap )
+          shapeFileWriter.addFeature( feature )
+          featureId += 1
+          self.emit( SIGNAL( "featureProcessed()" ) )
+
+          self.mutex.lock()
+          s = self.stopMe
+          self.mutex.unlock()
+          if s == 1:
+            interrupted = True
+            break
+    else: # modify existing shapefile
+      if not self.inputLayer.isEditable():
+        self.inputLayer.startEditing()
+      self.inputLayer.beginEditCommand( QString( "Simplify line(s)" ) )
+      if self.useSelection:
+        selection = self.inputLayer.selectedFeatures()
+        self.emit( SIGNAL( "rangeCalculated( PyQt_PyObject )" ), len( selection ) )
+        for f in selection:
+          featureId = f.id()
+          featGeometry = QgsGeometry( f.geometry() )
+          self.pointsBefore += geomVertexCount( featGeometry )
+          newGeometry = featGeometry.simplify( self.tolerance )
+          self.pointsAfter += geomVertexCount( newGeometry )
+          self.inputLayer.changeGeometry( featureId, newGeometry )
+          self.emit( SIGNAL( "featureProcessed()" ) )
+
+          self.mutex.lock()
+          s = self.stopMe
+          self.mutex.unlock()
+          if s == 1:
+            interrupted = True
+            break
+      else:
+        vProvider = self.inputLayer.dataProvider()
+        self.emit( SIGNAL( "rangeCalculated( PyQt_PyObject )" ), vProvider.featureCount() )
+        f = QgsFeature()
+        while vProvider.nextFeature( f ):
+          featureId = f.id()
+          featGeometry = QgsGeometry( f.geometry() )
+          self.pointsBefore += geomVertexCount( featGeometry )
+          newGeometry = featGeometry.simplify( self.tolerance )
+          self.pointsAfter += geomVertexCount( newGeometry )
+          self.inputLayer.changeGeometry( featureId, newGeometry )
+          self.emit( SIGNAL( "featureProcessed()" ) )
+
+          self.mutex.lock()
+          s = self.stopMe
+          self.mutex.unlock()
+          if s == 1:
+            interrupted = True
+            break
+
+    # cleanup
+    if self.inputLayer.isEditable():
+      self.inputLayer.endEditCommand()
+
+    if shapeFileWriter != None:
+      del shapeFileWriter
+
+    if not interrupted:
+      self.emit( SIGNAL( "generalizationFinished( PyQt_PyObject )" ), ( self.pointsBefore, self.pointsAfter ) )
+    else:
+      self.emit( SIGNAL( "generalizationInterrupted()" ) )
+
+  def stop( self ):
+    self.mutex.lock()
+    self.stopMe = 1
+    self.mutex.unlock()
+
+    QThread.wait( self )

Added: trunk/qgis/python/plugins/fTools/tools/frmSimplify.ui
===================================================================
--- trunk/qgis/python/plugins/fTools/tools/frmSimplify.ui	                        (rev 0)
+++ trunk/qgis/python/plugins/fTools/tools/frmSimplify.ui	2010-11-15 00:33:57 UTC (rev 14678)
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+  <property name="windowModality">
+   <enum>Qt::WindowModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>269</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Simplify geometries</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Input line or polygon layer</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QComboBox" name="cmbInputLayer">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="useSelectionCheck">
+     <property name="text">
+      <string>Use only selected features</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Simplify tolerance</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDoubleSpinBox" name="toleranceSpin">
+       <property name="decimals">
+        <number>4</number>
+       </property>
+       <property name="minimum">
+        <double>0.000000000000000</double>
+       </property>
+       <property name="maximum">
+        <double>10000000.000000000000000</double>
+       </property>
+       <property name="value">
+        <double>0.000100000000000</double>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QCheckBox" name="writeShapefileCheck">
+       <property name="text">
+        <string>Save to new file</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="outputFileEdit">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="btnSelectOutputFile">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+       <property name="text">
+        <string>Browse</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="addToCanvasCheck">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="text">
+      <string>Add result to canvas</string>
+     </property>
+    </widget>
+   </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>



More information about the QGIS-commit mailing list