diff --git a/python/plugins/fTools/tools/doEliminate.py b/python/plugins/fTools/tools/doEliminate.py
index 7330dc7a789..d526e6987a0 100644
--- a/python/plugins/fTools/tools/doEliminate.py
+++ b/python/plugins/fTools/tools/doEliminate.py
@@ -41,7 +41,6 @@ class Dialog(QtGui.QDialog, Ui_Dialog):
self.setupUi(self)
QtCore.QObject.connect(self.toolOut, QtCore.SIGNAL("clicked()"), self.outFile)
QtCore.QObject.connect(self.inShape, QtCore.SIGNAL("currentIndexChanged(QString)"), self.update)
- QtCore.QObject.connect(self.writeShapefileCheck, QtCore.SIGNAL("stateChanged(int)"), self.on_writeShapefileCheck_stateChanged)
self.setWindowTitle(self.tr("Eliminate sliver polygons"))
self.buttonOk = self.buttonBox_2.button(QtGui.QDialogButtonBox.Ok)
# populate layer list
@@ -53,43 +52,34 @@ class Dialog(QtGui.QDialog, Ui_Dialog):
if len(layers) > 0:
self.update(layers[0])
- self.on_writeShapefileCheck_stateChanged(self.writeShapefileCheck.checkState())
-
def update(self, inputLayer):
changedLayer = ftools_utils.getVectorLayerByName(inputLayer)
selFeatures = changedLayer.selectedFeatureCount()
self.selected.setText( self.tr("Selected features: %1").arg(selFeatures))
- def on_writeShapefileCheck_stateChanged(self, newState):
- doEnable = (newState == 2)
- self.outShape.setEnabled(doEnable)
- self.toolOut.setEnabled(doEnable)
- self.addToCanvasCheck.setEnabled(doEnable)
-
def accept(self):
self.buttonOk.setEnabled(False)
if self.inShape.currentText() == "":
QtGui.QMessageBox.information(self, self.tr("Eliminate"), self.tr("No input shapefile specified"))
else:
+ outFileName = self.outShape.text()
- if self.writeShapefileCheck.isChecked():
- outFileName = self.outShape.text()
-
- if outFileName == "":
- QtGui.MessageBox.information(self, self.tr("Eliminate"), self.tr("Please specify output shapefile"))
- else:
- outFile = QtCore.QFile(outFileName)
-
- if outFile.exists():
- if not QgsVectorFileWriter.deleteShapeFile(outFileName):
- QtGui.QMessageBox.warning(self, self.tr("Delete error"),
- self.tr("Can't delete file %1").arg(outFileName))
- return
-
- outFileName = unicode(outFileName)
+ if outFileName == "":
+ QtGui.QMessageBox.information(self, self.tr("Eliminate"), self.tr("Please specify output shapefile"))
+ self.buttonOk.setEnabled(True)
+ return None
else:
- outFileName = None
+ outFile = QtCore.QFile(outFileName)
+
+ if outFile.exists():
+ if not QgsVectorFileWriter.deleteShapeFile(outFileName):
+ QtGui.QMessageBox.warning(self, self.tr("Delete error"),
+ self.tr("Can't delete file %1").arg(outFileName))
+ self.buttonOk.setEnabled(True)
+ return None
+
+ outFileName = unicode(outFileName)
inLayer = ftools_utils.getVectorLayerByName(unicode(self.inShape.currentText()))
@@ -109,13 +99,23 @@ class Dialog(QtGui.QDialog, Ui_Dialog):
self.outShape.clear()
(outFileName, self.encoding) = ftools_utils.saveDialog(self)
if outFileName is None or self.encoding is None:
- return
+ return None
self.outShape.setText(outFileName)
- def eliminate(self, inLayer, boundary, progressBar, outFileName = None):
+ def saveChanges(self, outLayer):
+ if outLayer.commitChanges():
+ return True
+ else:
+ msg = ""
+ for aStrm in outLayer.commitErrors():
+ msg = msg + "\n" + aStrm
+ QtGui.QMessageBox.warning(self, self.tr("Eliminate"), self.tr("Commit error:\n %1").arg(msg))
+ outLayer.rollBack()
+ return False
+
+ def eliminate(self, inLayer, boundary, progressBar, outFileName):
# keep references to the features to eliminate
fidsToEliminate = inLayer.selectedFeaturesIds()
- fidsToProcess = inLayer.selectedFeaturesIds()
if outFileName: # user wants a new shape file to be created as result
provider = inLayer.dataProvider()
@@ -128,12 +128,20 @@ class Dialog(QtGui.QDialog, Ui_Dialog):
outLayer = QgsVectorLayer(outFileName, QtCore.QFileInfo(outFileName).completeBaseName(), "ogr")
else:
- outLayer = inLayer
- outLayer.removeSelection(False)
+ QtGui.QMessageBox.information(self, self.tr("Eliminate"), self.tr("Please specify output shapefile"))
+ return None
+ # delete features to be eliminated in outLayer
+ outLayer.setSelectedFeatures(fidsToEliminate)
outLayer.startEditing()
- doCommit = True
+ if outLayer.deleteSelectedFeatures():
+ if self.saveChanges(outLayer):
+ outLayer.startEditing()
+ else:
+ QtGui.QMessageBox.warning(self, self.tr("Eliminate"), self.tr("Could not delete features"))
+ return None
+
# ANALYZE
start = 20.00
progressBar.setValue(start)
@@ -144,103 +152,92 @@ class Dialog(QtGui.QDialog, Ui_Dialog):
# we go through the list and see if we find any polygons we can merge the selected with
# if we have no success with some we merge and then restart the whole story
- while (lastLen != len(fidsToProcess)): #check if we made any progress
- lastLen = len(fidsToProcess)
- fidsNotEliminated = []
- fidsToDelete = []
+ while (lastLen != inLayer.selectedFeatureCount()): #check if we made any progress
+ lastLen = inLayer.selectedFeatureCount()
+ fidsToDeselect = []
#iterate over the polygons to eliminate
- for fid in fidsToProcess:
+ for fid2Eliminate in inLayer.selectedFeaturesIds():
feat = QgsFeature()
- if outLayer.featureAtId(fid, feat, True, False):
- geom = feat.geometry()
- bbox = geom.boundingBox()
+ if inLayer.featureAtId(fid2Eliminate, feat, True, False):
+ geom2Eliminate = feat.geometry()
+ bbox = geom2Eliminate.boundingBox()
outLayer.select(bbox, False) # make a new selection
mergeWithFid = None
mergeWithGeom = None
max = 0
for selFid in outLayer.selectedFeaturesIds():
- if fid != selFid:
- #check if this feature is to be eliminated, too
- try:
- found = fidsToEliminate.index(selFid)
- except ValueError: #selFid is not in fidsToEliminate
- # check whether the geometry to eliminate and the other geometry intersect
- selFeat = QgsFeature()
+ selFeat = QgsFeature()
- if outLayer.featureAtId(selFid, selFeat, True, False):
- selGeom = selFeat.geometry()
+ if outLayer.featureAtId(selFid, selFeat, True, False):
+ selGeom = selFeat.geometry()
- if geom.intersects(selGeom): # we have a candidate
- iGeom = geom.intersection(selGeom)
+ if geom2Eliminate.intersects(selGeom): # we have a candidate
+ iGeom = geom2Eliminate.intersection(selGeom)
- if boundary:
- selValue = iGeom.length()
- else:
- # we need a common boundary
- if 0 < iGeom.length():
- selValue = selGeom.area()
- else:
- selValue = 0
-
- if selValue > max:
- max = selValue
- mergeWithFid = selFid
- mergeWithGeom = QgsGeometry(selGeom) # deep copy of the geometry
+ if boundary:
+ selValue = iGeom.length()
+ else:
+ # we need a common boundary
+ if 0 < iGeom.length():
+ selValue = selGeom.area()
+ else:
+ selValue = 0
+ if selValue > max:
+ max = selValue
+ mergeWithFid = selFid
+ mergeWithGeom = QgsGeometry(selGeom) # deep copy of the geometry
+
if mergeWithFid != None: # a successful candidate
- try:
- geomList = geomsToMerge[mergeWithFid]
- except KeyError:
- geomList = [mergeWithGeom]
+ newGeom = mergeWithGeom.combine(geom2Eliminate)
- geomList.append(QgsGeometry(geom)) # deep copy of the geom
- geomsToMerge[mergeWithFid] = geomList
- fidsToDelete.append(fid)
+ if outLayer.changeGeometry(mergeWithFid, newGeom):
+ # write change back to disc
+ if self.saveChanges(outLayer):
+ outLayer.startEditing()
+ else:
+ return None
+ # mark feature as eliminated in inLayer
+ fidsToDeselect.append(fid2Eliminate)
+ else:
+ QtGui.QMessageBox.warning(self, self.tr("Eliminate"),
+ self.tr("Could not replace geometry of feature with id %1").arg( mergeWithFid ))
+ return None
+
start = start + add
progressBar.setValue(start)
- else:
- fidsNotEliminated.append(fid)
+ # end for fid2Eliminate
- # PROCESS
- for aFid in geomsToMerge.iterkeys():
- geomList = geomsToMerge[aFid]
+ # deselect features that are already eliminated in inLayer
+ for aFid in fidsToDeselect:
+ inLayer.deselect(aFid, False)
+
+ #end while
- if len(geomList) > 1:
- for i in range(len(geomList)):
- aGeom = geomList[i]
+ if inLayer.selectedFeatureCount() > 0:
+ # copy all features that could not be eliminated to outLayer
+ if outLayer.addFeatures(inLayer.selectedFeatures()):
+ # inform user
+ fidList = QtCore.QString()
- if i == 0:
- newGeom = aGeom
- else:
- newGeom = newGeom.combine(aGeom)
+ for fid in inLayer.selectedFeaturesIds():
+ if not fidList.isEmpty():
+ fidList.append(", ")
- # replace geometry in outLayer
- if not outLayer.changeGeometry(aFid, newGeom):
- QtGui.QMessageBox.warning(self, self.tr("Eliminate"),
- self.tr("Could not replace geometry of feature with id %1").arg( aFid ))
- doCommit = False
- break
+ fidList.append(str(fid))
- # delete eliminated features
- for aFid in fidsToDelete:
- if not outLayer.deleteFeature(aFid):
- QtGui.QMessageBox.warning(self, self.tr("Eliminate"),
- self.tr("Could not delete feature with id %1").arg( aFid ))
- doCommit = False
- break
- # prepare array for the next loop
- fidsToProcess = fidsNotEliminated
+ QtGui.QMessageBox.information(self, self.tr("Eliminate"),
+ self.tr("Could not eliminate features with these ids:\n%1").arg(fidList))
+ else:
+ QtGui.QMessageBox.warning(self, self.tr("Eliminate"), self.tr("Could not add features"))
- # SAVE CHANGES
- if doCommit:
- if not outLayer.commitChanges():
- QtGui.QMessageBox.warning(self, self.tr("Commit error"), self.tr("Commit error"))
- else:
- outLayer.rollBack()
+ # stop editing outLayer and commit any pending changes
+ if not self.saveChanges(outLayer):
+ return None
if outFileName:
if self.addToCanvasCheck.isChecked():
@@ -249,17 +246,4 @@ class Dialog(QtGui.QDialog, Ui_Dialog):
QtGui.QMessageBox.information(self, self.tr("Eliminate"),
self.tr("Created output shapefile:\n%1").arg(outFileName))
- # inform user
- if len(fidsNotEliminated) > 0:
- fidList = QtCore.QString()
-
- for fid in fidsNotEliminated:
- if not fidList.isEmpty():
- fidList.append(", ")
-
- fidList.append(str(fid))
-
- QtGui.QMessageBox.information(self, self.tr("Eliminate"),
- self.tr("Could not eliminate features with these ids:\n%1").arg(fidList))
-
self.iface.mapCanvas().refresh()
diff --git a/python/plugins/fTools/tools/frmEliminate.ui b/python/plugins/fTools/tools/frmEliminate.ui
index 3bd17430dad..4b4fe44eda6 100644
--- a/python/plugins/fTools/tools/frmEliminate.ui
+++ b/python/plugins/fTools/tools/frmEliminate.ui
@@ -6,8 +6,8 @@
0
0
- 377
- 243
+ 436
+ 218
@@ -15,52 +15,21 @@
-
-
-
- area
-
-
-
- -
-
-
- Selected features:
-
-
-
- -
-
-
- Input vector layer
-
-
-
- -
common boundary
- -
+
-
Merge selection with the neighbouring polygon with the largest
- -
-
-
- -
+
-
-
-
-
-
- Save to new file
-
-
-
-
@@ -77,14 +46,17 @@
- -
-
-
- Add result to canvas
+
-
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Close|QDialogButtonBox::Ok
- -
+
-
0
@@ -94,13 +66,45 @@
- -
-
-
- Qt::Horizontal
+
-
+
+
-
+
+
+ Input vector layer
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ -
+
+
+ Add result to canvas
-
- QDialogButtonBox::Close|QDialogButtonBox::Ok
+
+
+ -
+
+
+ Selected features:
+
+
+
+ -
+
+
+ area