12
12
13
13
class Dialog ( QDialog , Ui_Dialog ):
14
14
def __init__ ( self , iface ):
15
- QDialog .__init__ ( self )
15
+ QDialog .__init__ ( self , iface . mainWindow () )
16
16
self .setupUi ( self )
17
17
self .iface = iface
18
18
19
19
self .mergeThread = None
20
20
self .inputFiles = None
21
21
self .outFileName = None
22
+ self .inEncoding = None
22
23
23
24
self .btnOk = self .buttonBox .button ( QDialogButtonBox .Ok )
24
25
self .btnClose = self .buttonBox .button ( QDialogButtonBox .Close )
25
26
26
27
QObject .connect ( self .btnSelectDir , SIGNAL ( "clicked()" ), self .inputDir )
27
28
QObject .connect ( self .btnSelectFile , SIGNAL ( "clicked()" ), self .outFile )
28
29
QObject .connect ( self .chkListMode , SIGNAL ( "stateChanged( int )" ), self .changeMode )
30
+ QObject .connect ( self .leOutShape , SIGNAL ( "editingFinished()" ), self .updateOutFile )
29
31
30
32
def inputDir ( self ):
31
33
inDir = QFileDialog .getExistingDirectory ( self ,
@@ -56,8 +58,8 @@ def outFile( self ):
56
58
self .leOutShape .setText ( self .outFileName )
57
59
58
60
def inputFile ( self ):
59
- files = QFileDialog . getOpenFileNames ( self , self .tr ( "Select files to merge" ), "." , "Shapefiles(*.shp *.SHP)" )
60
- if files . isEmpty () :
61
+ ( files , self .inEncoding ) = ftools_utils . openDialog ( self , dialogMode = "ManyFiles" )
62
+ if files is None or self . inEncoding is None :
61
63
self .inputFiles = None
62
64
return
63
65
@@ -83,6 +85,11 @@ def changeMode( self ):
83
85
self .lblGeometry .setEnabled ( True )
84
86
self .cmbGeometry .setEnabled ( True )
85
87
88
+ def updateOutFile ( self ):
89
+ self .outFileName = self .leOutShape .text ()
90
+ settings = QSettings ()
91
+ self .outEncoding = settings .value ( "/UI/encoding" ).toString ()
92
+
86
93
def reject ( self ):
87
94
QDialog .reject ( self )
88
95
@@ -113,8 +120,6 @@ def accept( self ):
113
120
self .inputFiles = ftools_utils .getShapesByGeometryType ( baseDir , self .inputFiles , self .cmbGeometry .currentIndex () )
114
121
self .progressFiles .setRange ( 0 , self .inputFiles .count () )
115
122
116
- self .progressFiles .setRange ( 0 , self .inputFiles .count () )
117
-
118
123
outFile = QFile ( self .outFileName )
119
124
if outFile .exists ():
120
125
if not QgsVectorFileWriter .deleteShapeFile ( self .outFileName ):
@@ -126,8 +131,11 @@ def accept( self ):
126
131
127
132
self .btnOk .setEnabled ( False )
128
133
129
- self .mergeThread = ShapeMergeThread ( baseDir , self .inputFiles , self .outFileName , self .encoding )
130
- QObject .connect ( self .mergeThread , SIGNAL ( "rangeChanged( PyQt_PyObject )" ), self .setProgressRange )
134
+ self .mergeThread = ShapeMergeThread ( baseDir , self .inputFiles , self .inEncoding , self .outFileName , self .encoding )
135
+ QObject .connect ( self .mergeThread , SIGNAL ( "rangeChanged( PyQt_PyObject )" ), self .setFeatureProgressRange )
136
+ QObject .connect ( self .mergeThread , SIGNAL ( "checkStarted()" ), self .setFeatureProgressFormat )
137
+ QObject .connect ( self .mergeThread , SIGNAL ( "checkFinished()" ), self .resetFeatureProgressFormat )
138
+ QObject .connect ( self .mergeThread , SIGNAL ( "fileNameChanged( PyQt_PyObject )" ), self .setShapeProgressFormat )
131
139
QObject .connect ( self .mergeThread , SIGNAL ( "featureProcessed()" ), self .featureProcessed )
132
140
QObject .connect ( self .mergeThread , SIGNAL ( "shapeProcessed()" ), self .shapeProcessed )
133
141
QObject .connect ( self .mergeThread , SIGNAL ( "processingFinished()" ), self .processingFinished )
@@ -139,13 +147,22 @@ def accept( self ):
139
147
140
148
self .mergeThread .start ()
141
149
142
- def setProgressRange ( self , max ):
143
- self .progressFeatures .setRange ( 0 , max )
150
+ def setFeatureProgressRange ( self , maximum ):
151
+ self .progressFeatures .setRange ( 0 , maximum )
144
152
self .progressFeatures .setValue ( 0 )
145
153
154
+ def setFeatureProgressFormat ( self ):
155
+ self .progressFeatures .setFormat ( "Checking files: %p% " )
156
+
157
+ def resetFeatureProgressFormat ( self ):
158
+ self .progressFeatures .setFormat ( "%p% " )
159
+
146
160
def featureProcessed ( self ):
147
161
self .progressFeatures .setValue ( self .progressFeatures .value () + 1 )
148
162
163
+ def setShapeProgressFormat ( self , fileName ):
164
+ self .progressFiles .setFormat ( "%p% " + fileName )
165
+
149
166
def shapeProcessed ( self ):
150
167
self .progressFiles .setValue ( self .progressFiles .value () + 1 )
151
168
@@ -154,7 +171,9 @@ def processingFinished( self ):
154
171
155
172
if self .chkAddToCanvas .isChecked ():
156
173
if not ftools_utils .addShapeToCanvas ( unicode ( self .outFileName ) ):
157
- QMessageBox .warning ( self , self .tr ( "Merging" ), self .tr ( "Error loading output shapefile:\n %1" ).arg ( unicode ( self .outFileName ) ) )
174
+ QMessageBox .warning ( self , self .tr ( "Merging" ),
175
+ self .tr ( "Error loading output shapefile:\n %1" )
176
+ .arg ( unicode ( self .outFileName ) ) )
158
177
159
178
self .restoreGui ()
160
179
@@ -167,6 +186,7 @@ def stopProcessing( self ):
167
186
self .mergeThread = None
168
187
169
188
def restoreGui ( self ):
189
+ self .progressFiles .setFormat ( "%p%" )
170
190
self .progressFeatures .setRange ( 0 , 100 )
171
191
self .progressFeatures .setValue ( 0 )
172
192
self .progressFiles .setValue ( 0 )
@@ -175,10 +195,11 @@ def restoreGui( self ):
175
195
self .btnOk .setEnabled ( True )
176
196
177
197
class ShapeMergeThread ( QThread ):
178
- def __init__ ( self , dir , shapes , outputFileName , outputEncoding ):
198
+ def __init__ ( self , dir , shapes , inputEncoding , outputFileName , outputEncoding ):
179
199
QThread .__init__ ( self , QThread .currentThread () )
180
200
self .baseDir = dir
181
201
self .shapes = shapes
202
+ self .inputEncoding = inputEncoding
182
203
self .outputFileName = outputFileName
183
204
self .outputEncoding = outputEncoding
184
205
@@ -192,13 +213,38 @@ def run( self ):
192
213
193
214
interrupted = False
194
215
216
+ # create attribute list with uniquie fields
217
+ # from all selected layers
218
+ mergedFields = {}
219
+ count = 0
220
+ self .emit ( SIGNAL ( "rangeChanged( PyQt_PyObject )" ), len ( self .shapes ) )
221
+ self .emit ( SIGNAL ( "checkStarted()" ) )
222
+ for fileName in self .shapes :
223
+ layerPath = QFileInfo ( self .baseDir + "/" + fileName ).absoluteFilePath ()
224
+ newLayer = QgsVectorLayer ( layerPath , QFileInfo ( layerPath ).baseName (), "ogr" )
225
+ if not newLayer .isValid ():
226
+ continue
227
+ vprovider = newLayer .dataProvider ()
228
+ layerFields = vprovider .fields ()
229
+ for layerIndex , layerField in layerFields .iteritems ():
230
+ fieldFound = False
231
+ for mergedIndex , mergedField in mergedFields .iteritems ():
232
+ if ( mergedField .name () == layerField .name () ) and ( mergedField .type () == layerField .type () ):
233
+ fieldFound = True
234
+
235
+ if not fieldFound :
236
+ mergedFields [ count ] = layerField
237
+ count += 1
238
+ self .emit ( SIGNAL ( "featureProcessed()" ) )
239
+ self .emit ( SIGNAL ( "checkFinished()" ) )
240
+
195
241
# get information about shapefiles
196
242
layerPath = QFileInfo ( self .baseDir + "/" + self .shapes [ 0 ] ).absoluteFilePath ()
197
243
newLayer = QgsVectorLayer ( layerPath , QFileInfo ( layerPath ).baseName (), "ogr" )
198
244
self .crs = newLayer .crs ()
199
245
self .geom = newLayer .wkbType ()
200
246
vprovider = newLayer .dataProvider ()
201
- self .fields = vprovider . fields ()
247
+ self .fields = mergedFields
202
248
203
249
writer = QgsVectorFileWriter ( self .outputFileName , self .outputEncoding ,
204
250
self .fields , self .geom , self .crs )
@@ -209,18 +255,27 @@ def run( self ):
209
255
if not newLayer .isValid ():
210
256
continue
211
257
vprovider = newLayer .dataProvider ()
258
+ vprovider .setEncoding ( self .inputEncoding )
259
+ layerFields = vprovider .fields ()
212
260
allAttrs = vprovider .attributeIndexes ()
213
261
vprovider .select ( allAttrs )
214
262
nFeat = vprovider .featureCount ()
215
263
self .emit ( SIGNAL ( "rangeChanged( PyQt_PyObject )" ), nFeat )
264
+ self .emit ( SIGNAL ( "fileNameChanged( PyQt_PyObject )" ), fileName )
216
265
inFeat = QgsFeature ()
217
266
outFeat = QgsFeature ()
218
267
inGeom = QgsGeometry ()
219
268
while vprovider .nextFeature ( inFeat ):
220
269
atMap = inFeat .attributeMap ()
270
+ mergedAttrs = {}
271
+ # fill available attributes with values
272
+ for layerIndex , layerField in layerFields .iteritems ():
273
+ for mergedIndex , mergedField in self .fields .iteritems ():
274
+ if ( mergedField .name () == layerField .name () ) and ( mergedField .type () == layerField .type () ):
275
+ mergedAttrs [ mergedIndex ] = atMap [ layerIndex ]
221
276
inGeom = QgsGeometry ( inFeat .geometry () )
222
277
outFeat .setGeometry ( inGeom )
223
- outFeat .setAttributeMap ( atMap )
278
+ outFeat .setAttributeMap ( mergedAttrs )
224
279
writer .addFeature ( outFeat )
225
280
self .emit ( SIGNAL ( "featureProcessed()" ) )
226
281
0 commit comments