@@ -41,7 +41,6 @@ def __init__(self, iface):
41
41
self .setupUi (self )
42
42
QtCore .QObject .connect (self .toolOut , QtCore .SIGNAL ("clicked()" ), self .outFile )
43
43
QtCore .QObject .connect (self .inShape , QtCore .SIGNAL ("currentIndexChanged(QString)" ), self .update )
44
- QtCore .QObject .connect (self .writeShapefileCheck , QtCore .SIGNAL ("stateChanged(int)" ), self .on_writeShapefileCheck_stateChanged )
45
44
self .setWindowTitle (self .tr ("Eliminate sliver polygons" ))
46
45
self .buttonOk = self .buttonBox_2 .button (QtGui .QDialogButtonBox .Ok )
47
46
# populate layer list
@@ -53,43 +52,34 @@ def __init__(self, iface):
53
52
if len (layers ) > 0 :
54
53
self .update (layers [0 ])
55
54
56
- self .on_writeShapefileCheck_stateChanged (self .writeShapefileCheck .checkState ())
57
-
58
55
def update (self , inputLayer ):
59
56
changedLayer = ftools_utils .getVectorLayerByName (inputLayer )
60
57
selFeatures = changedLayer .selectedFeatureCount ()
61
58
self .selected .setText ( self .tr ("Selected features: %1" ).arg (selFeatures ))
62
59
63
- def on_writeShapefileCheck_stateChanged (self , newState ):
64
- doEnable = (newState == 2 )
65
- self .outShape .setEnabled (doEnable )
66
- self .toolOut .setEnabled (doEnable )
67
- self .addToCanvasCheck .setEnabled (doEnable )
68
-
69
60
def accept (self ):
70
61
self .buttonOk .setEnabled (False )
71
62
72
63
if self .inShape .currentText () == "" :
73
64
QtGui .QMessageBox .information (self , self .tr ("Eliminate" ), self .tr ("No input shapefile specified" ))
74
65
else :
66
+ outFileName = self .outShape .text ()
75
67
76
- if self .writeShapefileCheck .isChecked ():
77
- outFileName = self .outShape .text ()
78
-
79
- if outFileName == "" :
80
- QtGui .MessageBox .information (self , self .tr ("Eliminate" ), self .tr ("Please specify output shapefile" ))
81
- else :
82
- outFile = QtCore .QFile (outFileName )
68
+ if outFileName == "" :
69
+ QtGui .QMessageBox .information (self , self .tr ("Eliminate" ), self .tr ("Please specify output shapefile" ))
70
+ self .buttonOk .setEnabled (True )
71
+ return None
72
+ else :
73
+ outFile = QtCore .QFile (outFileName )
83
74
84
- if outFile .exists ():
85
- if not QgsVectorFileWriter .deleteShapeFile (outFileName ):
86
- QtGui .QMessageBox .warning (self , self .tr ("Delete error" ),
87
- self .tr ("Can't delete file %1" ).arg (outFileName ))
88
- return
75
+ if outFile .exists ():
76
+ if not QgsVectorFileWriter .deleteShapeFile (outFileName ):
77
+ QtGui .QMessageBox .warning (self , self .tr ("Delete error" ),
78
+ self .tr ("Can't delete file %1" ).arg (outFileName ))
79
+ self .buttonOk .setEnabled (True )
80
+ return None
89
81
90
- outFileName = unicode (outFileName )
91
- else :
92
- outFileName = None
82
+ outFileName = unicode (outFileName )
93
83
94
84
inLayer = ftools_utils .getVectorLayerByName (unicode (self .inShape .currentText ()))
95
85
@@ -109,13 +99,23 @@ def outFile(self):
109
99
self .outShape .clear ()
110
100
(outFileName , self .encoding ) = ftools_utils .saveDialog (self )
111
101
if outFileName is None or self .encoding is None :
112
- return
102
+ return None
113
103
self .outShape .setText (outFileName )
114
104
115
- def eliminate (self , inLayer , boundary , progressBar , outFileName = None ):
105
+ def saveChanges (self , outLayer ):
106
+ if outLayer .commitChanges ():
107
+ return True
108
+ else :
109
+ msg = ""
110
+ for aStrm in outLayer .commitErrors ():
111
+ msg = msg + "\n " + aStrm
112
+ QtGui .QMessageBox .warning (self , self .tr ("Eliminate" ), self .tr ("Commit error:\n %1" ).arg (msg ))
113
+ outLayer .rollBack ()
114
+ return False
115
+
116
+ def eliminate (self , inLayer , boundary , progressBar , outFileName ):
116
117
# keep references to the features to eliminate
117
118
fidsToEliminate = inLayer .selectedFeaturesIds ()
118
- fidsToProcess = inLayer .selectedFeaturesIds ()
119
119
120
120
if outFileName : # user wants a new shape file to be created as result
121
121
provider = inLayer .dataProvider ()
@@ -128,12 +128,20 @@ def eliminate(self, inLayer, boundary, progressBar, outFileName = None):
128
128
outLayer = QgsVectorLayer (outFileName , QtCore .QFileInfo (outFileName ).completeBaseName (), "ogr" )
129
129
130
130
else :
131
- outLayer = inLayer
132
- outLayer . removeSelection ( False )
131
+ QtGui . QMessageBox . information ( self , self . tr ( "Eliminate" ), self . tr ( "Please specify output shapefile" ))
132
+ return None
133
133
134
+ # delete features to be eliminated in outLayer
135
+ outLayer .setSelectedFeatures (fidsToEliminate )
134
136
outLayer .startEditing ()
135
- doCommit = True
136
137
138
+ if outLayer .deleteSelectedFeatures ():
139
+ if self .saveChanges (outLayer ):
140
+ outLayer .startEditing ()
141
+ else :
142
+ QtGui .QMessageBox .warning (self , self .tr ("Eliminate" ), self .tr ("Could not delete features" ))
143
+ return None
144
+
137
145
# ANALYZE
138
146
start = 20.00
139
147
progressBar .setValue (start )
@@ -144,103 +152,92 @@ def eliminate(self, inLayer, boundary, progressBar, outFileName = None):
144
152
145
153
# we go through the list and see if we find any polygons we can merge the selected with
146
154
# if we have no success with some we merge and then restart the whole story
147
- while (lastLen != len (fidsToProcess )): #check if we made any progress
148
- lastLen = len (fidsToProcess )
149
- fidsNotEliminated = []
150
- fidsToDelete = []
155
+ while (lastLen != inLayer .selectedFeatureCount ()): #check if we made any progress
156
+ lastLen = inLayer .selectedFeatureCount ()
157
+ fidsToDeselect = []
151
158
152
159
#iterate over the polygons to eliminate
153
- for fid in fidsToProcess :
160
+ for fid2Eliminate in inLayer . selectedFeaturesIds () :
154
161
feat = QgsFeature ()
155
162
156
- if outLayer .featureAtId (fid , feat , True , False ):
157
- geom = feat .geometry ()
158
- bbox = geom .boundingBox ()
163
+ if inLayer .featureAtId (fid2Eliminate , feat , True , False ):
164
+ geom2Eliminate = feat .geometry ()
165
+ bbox = geom2Eliminate .boundingBox ()
159
166
outLayer .select (bbox , False ) # make a new selection
160
167
mergeWithFid = None
161
168
mergeWithGeom = None
162
169
max = 0
163
170
164
171
for selFid in outLayer .selectedFeaturesIds ():
165
- if fid != selFid :
166
- #check if this feature is to be eliminated, too
167
- try :
168
- found = fidsToEliminate .index (selFid )
169
- except ValueError : #selFid is not in fidsToEliminate
170
- # check whether the geometry to eliminate and the other geometry intersect
171
- selFeat = QgsFeature ()
172
-
173
- if outLayer .featureAtId (selFid , selFeat , True , False ):
174
- selGeom = selFeat .geometry ()
175
-
176
- if geom .intersects (selGeom ): # we have a candidate
177
- iGeom = geom .intersection (selGeom )
178
-
179
- if boundary :
180
- selValue = iGeom .length ()
181
- else :
182
- # we need a common boundary
183
- if 0 < iGeom .length ():
184
- selValue = selGeom .area ()
185
- else :
186
- selValue = 0
187
-
188
- if selValue > max :
189
- max = selValue
190
- mergeWithFid = selFid
191
- mergeWithGeom = QgsGeometry (selGeom ) # deep copy of the geometry
192
-
172
+ selFeat = QgsFeature ()
173
+
174
+ if outLayer .featureAtId (selFid , selFeat , True , False ):
175
+ selGeom = selFeat .geometry ()
176
+
177
+ if geom2Eliminate .intersects (selGeom ): # we have a candidate
178
+ iGeom = geom2Eliminate .intersection (selGeom )
179
+
180
+ if boundary :
181
+ selValue = iGeom .length ()
182
+ else :
183
+ # we need a common boundary
184
+ if 0 < iGeom .length ():
185
+ selValue = selGeom .area ()
186
+ else :
187
+ selValue = 0
188
+
189
+ if selValue > max :
190
+ max = selValue
191
+ mergeWithFid = selFid
192
+ mergeWithGeom = QgsGeometry (selGeom ) # deep copy of the geometry
193
+
193
194
if mergeWithFid != None : # a successful candidate
194
- try :
195
- geomList = geomsToMerge [mergeWithFid ]
196
- except KeyError :
197
- geomList = [mergeWithGeom ]
195
+ newGeom = mergeWithGeom .combine (geom2Eliminate )
198
196
199
- geomList .append (QgsGeometry (geom )) # deep copy of the geom
200
- geomsToMerge [mergeWithFid ] = geomList
201
- fidsToDelete .append (fid )
197
+ if outLayer .changeGeometry (mergeWithFid , newGeom ):
198
+ # write change back to disc
199
+ if self .saveChanges (outLayer ):
200
+ outLayer .startEditing ()
201
+ else :
202
+ return None
202
203
204
+ # mark feature as eliminated in inLayer
205
+ fidsToDeselect .append (fid2Eliminate )
206
+ else :
207
+ QtGui .QMessageBox .warning (self , self .tr ("Eliminate" ),
208
+ self .tr ("Could not replace geometry of feature with id %1" ).arg ( mergeWithFid ))
209
+ return None
210
+
203
211
start = start + add
204
212
progressBar .setValue (start )
205
- else :
206
- fidsNotEliminated .append (fid )
213
+ # end for fid2Eliminate
207
214
208
- # PROCESS
209
- for aFid in geomsToMerge .iterkeys ():
210
- geomList = geomsToMerge [aFid ]
215
+ # deselect features that are already eliminated in inLayer
216
+ for aFid in fidsToDeselect :
217
+ inLayer .deselect (aFid , False )
218
+
219
+ #end while
211
220
212
- if len (geomList ) > 1 :
213
- for i in range (len (geomList )):
214
- aGeom = geomList [i ]
221
+ if inLayer .selectedFeatureCount () > 0 :
222
+ # copy all features that could not be eliminated to outLayer
223
+ if outLayer .addFeatures (inLayer .selectedFeatures ()):
224
+ # inform user
225
+ fidList = QtCore .QString ()
215
226
216
- if i == 0 :
217
- newGeom = aGeom
218
- else :
219
- newGeom = newGeom .combine (aGeom )
220
-
221
- # replace geometry in outLayer
222
- if not outLayer .changeGeometry (aFid , newGeom ):
223
- QtGui .QMessageBox .warning (self , self .tr ("Eliminate" ),
224
- self .tr ("Could not replace geometry of feature with id %1" ).arg ( aFid ))
225
- doCommit = False
226
- break
227
-
228
- # delete eliminated features
229
- for aFid in fidsToDelete :
230
- if not outLayer .deleteFeature (aFid ):
231
- QtGui .QMessageBox .warning (self , self .tr ("Eliminate" ),
232
- self .tr ("Could not delete feature with id %1" ).arg ( aFid ))
233
- doCommit = False
234
- break
235
- # prepare array for the next loop
236
- fidsToProcess = fidsNotEliminated
237
-
238
- # SAVE CHANGES
239
- if doCommit :
240
- if not outLayer .commitChanges ():
241
- QtGui .QMessageBox .warning (self , self .tr ("Commit error" ), self .tr ("Commit error" ))
242
- else :
243
- outLayer .rollBack ()
227
+ for fid in inLayer .selectedFeaturesIds ():
228
+ if not fidList .isEmpty ():
229
+ fidList .append (", " )
230
+
231
+ fidList .append (str (fid ))
232
+
233
+ QtGui .QMessageBox .information (self , self .tr ("Eliminate" ),
234
+ self .tr ("Could not eliminate features with these ids:\n %1" ).arg (fidList ))
235
+ else :
236
+ QtGui .QMessageBox .warning (self , self .tr ("Eliminate" ), self .tr ("Could not add features" ))
237
+
238
+ # stop editing outLayer and commit any pending changes
239
+ if not self .saveChanges (outLayer ):
240
+ return None
244
241
245
242
if outFileName :
246
243
if self .addToCanvasCheck .isChecked ():
@@ -249,17 +246,4 @@ def eliminate(self, inLayer, boundary, progressBar, outFileName = None):
249
246
QtGui .QMessageBox .information (self , self .tr ("Eliminate" ),
250
247
self .tr ("Created output shapefile:\n %1" ).arg (outFileName ))
251
248
252
- # inform user
253
- if len (fidsNotEliminated ) > 0 :
254
- fidList = QtCore .QString ()
255
-
256
- for fid in fidsNotEliminated :
257
- if not fidList .isEmpty ():
258
- fidList .append (", " )
259
-
260
- fidList .append (str (fid ))
261
-
262
- QtGui .QMessageBox .information (self , self .tr ("Eliminate" ),
263
- self .tr ("Could not eliminate features with these ids:\n %1" ).arg (fidList ))
264
-
265
249
self .iface .mapCanvas ().refresh ()
0 commit comments