31
31
from PyQt4 .QtCore import *
32
32
from PyQt4 .QtGui import *
33
33
from qgis .core import *
34
- #import os, sys, string, math
35
34
import ftools_utils
36
35
from ui_frmVectorSplit import Ui_Dialog
37
36
38
37
class Dialog (QDialog , Ui_Dialog ):
39
38
def __init__ (self , iface ):
40
39
QDialog .__init__ (self )
41
40
self .iface = iface
42
- # Set up the user interface from Designer.
41
+
43
42
self .setupUi (self )
43
+ self .setWindowTitle (self .tr ("Split vector layer" ))
44
+
44
45
QObject .connect (self .toolOut , SIGNAL ("clicked()" ), self .outFile )
45
46
QObject .connect (self .inShape , SIGNAL ("currentIndexChanged(QString)" ), self .update )
46
- self .setWindowTitle (self .tr ("Split vector layer" ))
47
- self .buttonOk = self .buttonBox_2 .button ( QDialogButtonBox .Ok )
47
+
48
+ self .workThread = None
49
+
50
+ self .btnOk = self .buttonBox_2 .button ( QDialogButtonBox .Ok )
51
+ self .btnClose = self .buttonBox_2 .button ( QDialogButtonBox .Close )
52
+
48
53
# populate layer list
49
- self .progressBar .setValue (0 )
50
54
mapCanvas = self .iface .mapCanvas ()
51
55
layers = ftools_utils .getLayerNames ([QGis .Point , QGis .Line , QGis .Polygon ])
52
56
self .inShape .addItems (layers )
@@ -58,63 +62,151 @@ def update(self, inputLayer):
58
62
for i in changedField :
59
63
self .inField .addItem (unicode (changedField [i ].name ()))
60
64
61
- def accept (self ):
62
- self .buttonOk .setEnabled ( False )
63
- if self .inShape .currentText () == "" :
64
- QMessageBox .information (self , self .tr ("Vector Split" ), self .tr ("No input shapefile specified" ))
65
- elif self .outShape .text () == "" :
66
- QMessageBox .information (self , self .tr ("Vector Split" ), self .tr ("Please specify output shapefile" ))
67
- else :
68
- inField = self .inField .currentText ()
69
- inLayer = ftools_utils .getVectorLayerByName (unicode (self .inShape .currentText ()))
70
- self .progressBar .setValue (5 )
71
- outPath = QString (self .folderName )
72
- self .progressBar .setValue (10 )
73
- if outPath .contains ("\\ " ):
74
- outPath .replace ("\\ " , "/" )
75
- self .progressBar .setValue (15 )
76
- if not outPath .endsWith ("/" ): outPath = outPath + "/"
77
- self .split (inLayer , unicode (outPath ), unicode (inField ), self .progressBar )
78
- self .progressBar .setValue (100 )
79
- self .outShape .clear ()
80
- QMessageBox .information (self , self .tr ("Vector Split" ), self .tr ("Created output shapefiles in folder:\n %1" ).arg ( outPath ))
81
- self .progressBar .setValue (0 )
82
- self .buttonOk .setEnabled ( True )
83
-
84
65
def outFile (self ):
85
66
self .outShape .clear ()
86
67
( self .folderName , self .encoding ) = ftools_utils .dirDialog ( self )
87
68
if self .folderName is None or self .encoding is None :
88
69
return
89
70
self .outShape .setText ( QString ( self .folderName ) )
90
71
91
- def split (self , vlayer , outPath , inField , progressBar ):
92
- provider = vlayer .dataProvider ()
93
- #unique = []
94
- index = provider .fieldNameIndex (inField )
95
- #provider.uniqueValues(index, unique)
96
- unique = ftools_utils .getUniqueValues (vlayer .dataProvider (), int (index ))
97
- baseName = unicode ( outPath + vlayer .name () + "_" + inField + "_" )
72
+ def accept (self ):
73
+ inShape = self .inShape .currentText ()
74
+ outDir = self .outShape .text ()
75
+ if inShape == "" :
76
+ QMessageBox .information (self , self .tr ("Vector Split" ),
77
+ self .tr ("No input shapefile specified" ))
78
+ return
79
+ elif outDir == "" :
80
+ QMessageBox .information (self , self .tr ("Vector Split" ),
81
+ self .tr ("Please specify output shapefile" ))
82
+ return
83
+
84
+ self .btnOk .setEnabled ( False )
85
+
86
+ vLayer = ftools_utils .getVectorLayerByName (unicode (self .inShape .currentText ()))
87
+ self .workThread = SplitThread (vLayer , self .inField .currentText (), self .encoding , outDir )
88
+
89
+ QObject .connect (self .workThread , SIGNAL ("rangeCalculated(PyQt_PyObject)" ), self .setProgressRange )
90
+ QObject .connect (self .workThread , SIGNAL ("valueProcessed()" ), self .valueProcessed )
91
+ QObject .connect (self .workThread , SIGNAL ("processFinished(PyQt_PyObject)" ), self .processFinished )
92
+ QObject .connect (self .workThread , SIGNAL ("processInterrupted()" ), self .processInterrupted )
93
+
94
+ self .btnClose .setText (self .tr ("Cancel" ))
95
+ QObject .disconnect (self .buttonBox_2 , SIGNAL ("rejected()" ), self .reject )
96
+ QObject .connect (self .btnClose , SIGNAL ("clicked()" ), self .stopProcessing )
97
+
98
+ self .workThread .start ()
99
+
100
+ def setProgressRange (self , maximum ):
101
+ self .progressBar .setRange (0 , maximum )
102
+
103
+ def valueProcessed (self ):
104
+ self .progressBar .setValue (self .progressBar .value () + 1 )
105
+
106
+ def restoreGui (self ):
107
+ self .progressBar .setValue (0 )
108
+ self .outShape .clear ()
109
+ QObject .connect (self .buttonBox_2 , SIGNAL ("rejected()" ), self .reject )
110
+ self .btnClose .setText (self .tr ("Close" ))
111
+ self .btnOk .setEnabled (True )
112
+
113
+ def stopProcessing (self ):
114
+ if self .workThread != None :
115
+ self .workThread .stop ()
116
+ self .workThread = None
117
+
118
+ def processInterrupted ( self ):
119
+ self .restoreGui ()
120
+
121
+ def processFinished (self , errors ):
122
+ self .stopProcessing ()
123
+ outPath = self .outShape .text ()
124
+ self .restoreGui ()
125
+
126
+ if not errors .isEmpty ():
127
+ msg = QString ( "Processing of the following layers/files ended with error:<br><br>" ).append ( errors .join ( "<br>" ) )
128
+ QErrorMessage ( self ).showMessage ( msg )
129
+
130
+ QMessageBox .information (self , self .tr ("Vector Split" ),
131
+ self .tr ("Created output shapefiles in folder:\n %1" ).arg (outPath ))
132
+
133
+ class SplitThread (QThread ):
134
+ def __init__ (self , layer , splitField , encoding , outDir ):
135
+ QThread .__init__ (self , QThread .currentThread ())
136
+ self .layer = layer
137
+ self .field = splitField
138
+ self .encoding = encoding
139
+ self .outDir = outDir
140
+
141
+ self .mutex = QMutex ()
142
+ self .stopMe = 0
143
+
144
+ self .errors = QStringList ()
145
+
146
+ def run (self ):
147
+ self .mutex .lock ()
148
+ self .stopMe = 0
149
+ self .mutex .unlock ()
150
+
151
+ interrupted = False
152
+
153
+ outPath = QString (self .outDir )
154
+
155
+ if outPath .contains ("\\ " ):
156
+ outPath .replace ("\\ " , "/" )
157
+
158
+ if not outPath .endsWith ("/" ):
159
+ outPath = outPath + "/"
160
+
161
+ provider = self .layer .dataProvider ()
162
+ index = provider .fieldNameIndex (self .field )
163
+ unique = ftools_utils .getUniqueValues (provider , int (index ))
164
+ baseName = unicode ( outPath + self .layer .name () + "_" + self .field + "_" )
98
165
allAttrs = provider .attributeIndexes ()
99
166
provider .select (allAttrs )
100
- fieldList = ftools_utils .getFieldList (vlayer )
167
+ fieldList = ftools_utils .getFieldList (self . layer )
101
168
sRs = provider .crs ()
169
+ geom = self .layer .wkbType ()
102
170
inFeat = QgsFeature ()
103
- progressBar . setValue ( 20 )
104
- start = 20.00
105
- add = 80.00 / len ( unique )
171
+
172
+ self . emit ( SIGNAL ( "rangeCalculated(PyQt_PyObject)" ), len ( unique ))
173
+
106
174
for i in unique :
107
- check = QFile (baseName + "_" + unicode (i ) + ".shp" )
175
+ print "I" , i
176
+ print "INDEX" , index
177
+ check = QFile (baseName + "_" + unicode (i .toString ().trimmed ()) + ".shp" )
178
+ fName = check .fileName ()
108
179
if check .exists ():
109
- if not QgsVectorFileWriter .deleteShapeFile (baseName + "_" + unicode (i .toString ().trimmed ()) + ".shp" ):
110
- return
111
- writer = QgsVectorFileWriter (baseName + "_" + unicode (i .toString ().trimmed ()) + ".shp" , self .encoding , fieldList , vlayer .dataProvider ().geometryType (), sRs )
180
+ if not QgsVectorFileWriter .deleteShapeFile (fName ):
181
+ self .errors .append ( fName )
182
+ continue
183
+
184
+ writer = QgsVectorFileWriter (fName , self .encoding , fieldList , geom , sRs )
112
185
provider .rewind ()
113
186
while provider .nextFeature (inFeat ):
114
187
atMap = inFeat .attributeMap ()
115
- #changed from QVariant(i) to below:
188
+ #print "AtMAP", atMAP
116
189
if atMap [index ] == i :
117
190
writer .addFeature (inFeat )
118
191
del writer
119
- start = start + add
120
- progressBar .setValue (start )
192
+
193
+ self .emit (SIGNAL ("valueProcessed()" ))
194
+
195
+ self .mutex .lock ()
196
+ s = self .stopMe
197
+ self .mutex .unlock ()
198
+ if s == 1 :
199
+ interrupted = True
200
+ break
201
+
202
+ if not interrupted :
203
+ self .emit (SIGNAL ("processFinished( PyQt_PyObject )" ), self .errors )
204
+ else :
205
+ self .emit (SIGNAL ("processInterrupted()" ))
206
+
207
+ def stop (self ):
208
+ self .mutex .lock ()
209
+ self .stopMe = 1
210
+ self .mutex .unlock ()
211
+
212
+ QThread .wait (self )
0 commit comments