Skip to content

Commit 5e07667

Browse files
committedFeb 24, 2012
apply Merge Shapefiles fixes from master
1 parent fe3bb76 commit 5e07667

File tree

2 files changed

+78
-17
lines changed

2 files changed

+78
-17
lines changed
 

‎python/plugins/fTools/tools/doMergeShapes.py

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,22 @@
1212

1313
class Dialog( QDialog, Ui_Dialog ):
1414
def __init__( self, iface ):
15-
QDialog.__init__( self )
15+
QDialog.__init__( self, iface.mainWindow() )
1616
self.setupUi( self )
1717
self.iface = iface
1818

1919
self.mergeThread = None
2020
self.inputFiles = None
2121
self.outFileName = None
22+
self.inEncoding = None
2223

2324
self.btnOk = self.buttonBox.button( QDialogButtonBox.Ok )
2425
self.btnClose = self.buttonBox.button( QDialogButtonBox.Close )
2526

2627
QObject.connect( self.btnSelectDir, SIGNAL( "clicked()" ), self.inputDir )
2728
QObject.connect( self.btnSelectFile, SIGNAL( "clicked()" ), self.outFile )
2829
QObject.connect( self.chkListMode, SIGNAL( "stateChanged( int )" ), self.changeMode )
30+
QObject.connect( self.leOutShape, SIGNAL( "editingFinished()" ), self.updateOutFile )
2931

3032
def inputDir( self ):
3133
inDir = QFileDialog.getExistingDirectory( self,
@@ -56,8 +58,8 @@ def outFile( self ):
5658
self.leOutShape.setText( self.outFileName )
5759

5860
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:
6163
self.inputFiles = None
6264
return
6365

@@ -83,6 +85,11 @@ def changeMode( self ):
8385
self.lblGeometry.setEnabled( True )
8486
self.cmbGeometry.setEnabled( True )
8587

88+
def updateOutFile( self ):
89+
self.outFileName = self.leOutShape.text()
90+
settings = QSettings()
91+
self.outEncoding = settings.value( "/UI/encoding" ).toString()
92+
8693
def reject( self ):
8794
QDialog.reject( self )
8895

@@ -113,8 +120,6 @@ def accept( self ):
113120
self.inputFiles = ftools_utils.getShapesByGeometryType( baseDir, self.inputFiles, self.cmbGeometry.currentIndex() )
114121
self.progressFiles.setRange( 0, self.inputFiles.count() )
115122

116-
self.progressFiles.setRange( 0, self.inputFiles.count() )
117-
118123
outFile = QFile( self.outFileName )
119124
if outFile.exists():
120125
if not QgsVectorFileWriter.deleteShapeFile( self.outFileName ):
@@ -126,8 +131,11 @@ def accept( self ):
126131

127132
self.btnOk.setEnabled( False )
128133

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 )
131139
QObject.connect( self.mergeThread, SIGNAL( "featureProcessed()" ), self.featureProcessed )
132140
QObject.connect( self.mergeThread, SIGNAL( "shapeProcessed()" ), self.shapeProcessed )
133141
QObject.connect( self.mergeThread, SIGNAL( "processingFinished()" ), self.processingFinished )
@@ -139,13 +147,22 @@ def accept( self ):
139147

140148
self.mergeThread.start()
141149

142-
def setProgressRange( self, max ):
143-
self.progressFeatures.setRange( 0, max )
150+
def setFeatureProgressRange( self, maximum ):
151+
self.progressFeatures.setRange( 0, maximum )
144152
self.progressFeatures.setValue( 0 )
145153

154+
def setFeatureProgressFormat( self ):
155+
self.progressFeatures.setFormat( "Checking files: %p% ")
156+
157+
def resetFeatureProgressFormat( self ):
158+
self.progressFeatures.setFormat( "%p% ")
159+
146160
def featureProcessed( self ):
147161
self.progressFeatures.setValue( self.progressFeatures.value() + 1 )
148162

163+
def setShapeProgressFormat( self, fileName ):
164+
self.progressFiles.setFormat( "%p% " + fileName )
165+
149166
def shapeProcessed( self ):
150167
self.progressFiles.setValue( self.progressFiles.value() + 1 )
151168

@@ -154,7 +171,9 @@ def processingFinished( self ):
154171

155172
if self.chkAddToCanvas.isChecked():
156173
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 ) ) )
158177

159178
self.restoreGui()
160179

@@ -167,6 +186,7 @@ def stopProcessing( self ):
167186
self.mergeThread = None
168187

169188
def restoreGui( self ):
189+
self.progressFiles.setFormat( "%p%" )
170190
self.progressFeatures.setRange( 0, 100 )
171191
self.progressFeatures.setValue( 0 )
172192
self.progressFiles.setValue( 0 )
@@ -175,10 +195,11 @@ def restoreGui( self ):
175195
self.btnOk.setEnabled( True )
176196

177197
class ShapeMergeThread( QThread ):
178-
def __init__( self, dir, shapes, outputFileName, outputEncoding ):
198+
def __init__( self, dir, shapes, inputEncoding, outputFileName, outputEncoding ):
179199
QThread.__init__( self, QThread.currentThread() )
180200
self.baseDir = dir
181201
self.shapes = shapes
202+
self.inputEncoding = inputEncoding
182203
self.outputFileName = outputFileName
183204
self.outputEncoding = outputEncoding
184205

@@ -192,13 +213,38 @@ def run( self ):
192213

193214
interrupted = False
194215

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+
195241
# get information about shapefiles
196242
layerPath = QFileInfo( self.baseDir + "/" + self.shapes[ 0 ] ).absoluteFilePath()
197243
newLayer = QgsVectorLayer( layerPath, QFileInfo( layerPath ).baseName(), "ogr" )
198244
self.crs = newLayer.crs()
199245
self.geom = newLayer.wkbType()
200246
vprovider = newLayer.dataProvider()
201-
self.fields = vprovider.fields()
247+
self.fields = mergedFields
202248

203249
writer = QgsVectorFileWriter( self.outputFileName, self.outputEncoding,
204250
self.fields, self.geom, self.crs )
@@ -209,18 +255,27 @@ def run( self ):
209255
if not newLayer.isValid():
210256
continue
211257
vprovider = newLayer.dataProvider()
258+
vprovider.setEncoding( self.inputEncoding )
259+
layerFields = vprovider.fields()
212260
allAttrs = vprovider.attributeIndexes()
213261
vprovider.select( allAttrs )
214262
nFeat = vprovider.featureCount()
215263
self.emit( SIGNAL( "rangeChanged( PyQt_PyObject )" ), nFeat )
264+
self.emit( SIGNAL( "fileNameChanged( PyQt_PyObject )" ), fileName )
216265
inFeat = QgsFeature()
217266
outFeat = QgsFeature()
218267
inGeom = QgsGeometry()
219268
while vprovider.nextFeature( inFeat ):
220269
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 ]
221276
inGeom = QgsGeometry( inFeat.geometry() )
222277
outFeat.setGeometry( inGeom )
223-
outFeat.setAttributeMap( atMap )
278+
outFeat.setAttributeMap( mergedAttrs )
224279
writer.addFeature( outFeat )
225280
self.emit( SIGNAL( "featureProcessed()" ) )
226281

‎python/plugins/fTools/tools/ftools_utils.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def getUniqueValues( provider, index ):
255255
return values
256256

257257
# Generate a save file dialog with a dropdown box for choosing encoding style
258-
def saveDialog( parent, filtering="Shapefiles (*.shp)"):
258+
def saveDialog( parent, filtering="Shapefiles (*.shp *.SHP)"):
259259
settings = QSettings()
260260
dirName = settings.value( "/UI/lastShapefileDir" ).toString()
261261
encode = settings.value( "/UI/encoding" ).toString()
@@ -271,18 +271,24 @@ def saveDialog( parent, filtering="Shapefiles (*.shp)"):
271271
return ( unicode( files.first() ), unicode( fileDialog.encoding() ) )
272272

273273
# Generate a save file dialog with a dropdown box for choosing encoding style
274-
def openDialog( parent, filtering="Shapefiles (*.shp)"):
274+
# with mode="SingleFile" will allow to select only one file, in other cases - several files
275+
def openDialog( parent, filtering="Shapefiles (*.shp *.SHP)", dialogMode="SingleFile"):
275276
settings = QSettings()
276277
dirName = settings.value( "/UI/lastShapefileDir" ).toString()
277278
encode = settings.value( "/UI/encoding" ).toString()
278279
fileDialog = QgsEncodingFileDialog( parent, "Save output shapefile", dirName, QString(filtering), encode )
279-
fileDialog.setFileMode( QFileDialog.AnyFile )
280+
#fileDialog.setFileMode( QFileDialog.AnyFile )
281+
fileDialog.setFileMode( QFileDialog.ExistingFiles )
280282
fileDialog.setAcceptMode( QFileDialog.AcceptOpen )
281283
if not fileDialog.exec_() == QDialog.Accepted:
282284
return None, None
283285
files = fileDialog.selectedFiles()
284286
settings.setValue("/UI/lastShapefileDir", QVariant( QFileInfo( unicode( files.first() ) ).absolutePath() ) )
285-
return ( unicode( files.first() ), unicode( fileDialog.encoding() ) )
287+
#return ( unicode( files.first() ), unicode( fileDialog.encoding() ) )
288+
if dialogMode == "SingleFile":
289+
return ( unicode( files.first() ), unicode( fileDialog.encoding() ) )
290+
else:
291+
return ( files, unicode( fileDialog.encoding() ) )
286292

287293
# Generate a select directory dialog with a dropdown box for choosing encoding style
288294
def dirDialog( parent ):

0 commit comments

Comments
 (0)
Please sign in to comment.