Skip to content

Commit d12a0b4

Browse files
committedJan 14, 2016
[processing] fix Merge vector layers alg (fix #9978)
1 parent 2aa523d commit d12a0b4

File tree

1 file changed

+58
-51
lines changed
  • python/plugins/processing/algs/qgis

1 file changed

+58
-51
lines changed
 

‎python/plugins/processing/algs/qgis/Merge.py

Lines changed: 58 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -25,86 +25,93 @@
2525

2626
__revision__ = '$Format:%H$'
2727

28+
29+
from PyQt4.QtCore import QVariant
30+
from qgis.core import QgsFields, QgsVectorLayer
31+
2832
from processing.core.GeoAlgorithm import GeoAlgorithm
2933
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
30-
from processing.core.parameters import ParameterVector
34+
from processing.core.parameters import ParameterMultipleInput
3135
from processing.core.outputs import OutputVector
3236

3337
from processing.tools import dataobjects, vector
3438

3539

3640
class Merge(GeoAlgorithm):
37-
LAYER1 = 'LAYER1'
38-
LAYER2 = 'LAYER2'
41+
LAYERS = 'LAYERS'
3942
OUTPUT = 'OUTPUT'
4043

4144
def defineCharacteristics(self):
4245
self.name, self.i18n_name = self.trAlgorithm('Merge vector layers')
4346
self.group, self.i18n_group = self.trAlgorithm('Vector general tools')
4447

45-
self.addParameter(ParameterVector(self.LAYER1,
46-
self.tr('Input layer 1'), [ParameterVector.VECTOR_TYPE_ANY]))
47-
self.addParameter(ParameterVector(self.LAYER2,
48-
self.tr('Input layer 2'), [ParameterVector.VECTOR_TYPE_ANY]))
48+
self.addParameter(ParameterMultipleInput(self.LAYERS,
49+
self.tr('Layers to merge'), datatype=ParameterMultipleInput.TYPE_VECTOR_ANY))
4950

5051
self.addOutput(OutputVector(self.OUTPUT, self.tr('Merged')))
5152

5253
def processAlgorithm(self, progress):
53-
layer1 = dataobjects.getObjectFromUri(
54-
self.getParameterValue(self.LAYER1))
55-
layer2 = dataobjects.getObjectFromUri(
56-
self.getParameterValue(self.LAYER2))
57-
58-
if layer1.wkbType() != layer2.wkbType():
59-
raise GeoAlgorithmExecutionException(
60-
self.tr('Merged layers must have be same type of geometry'))
61-
62-
count = 0
63-
fields = []
64-
layers = [layer1, layer2]
65-
for layer in layers:
66-
count += layer.featureCount()
54+
inLayers = self.getParameterValue(self.LAYERS)
55+
paths = inLayers.split(';')
56+
57+
layers = []
58+
fields = QgsFields()
59+
totalFeatureCount = 0
60+
for x in xrange(0, len(paths)):
61+
layer = QgsVectorLayer(paths[x], unicode(x), 'ogr')
6762

68-
for sfield in layer.pendingFields():
63+
if (len(layers) > 0):
64+
if (layer.dataProvider().geometryType() != layers[0].dataProvider().geometryType()):
65+
raise GeoAlgorithmExecutionException(
66+
self.tr('All layers must have same geometry type!'))
67+
68+
layers.append(layer)
69+
totalFeatureCount += layer.featureCount()
70+
71+
for sindex, sfield in enumerate(layer.dataProvider().fields()):
6972
found = None
7073
for dfield in fields:
71-
if dfield.name() == sfield.name() and \
72-
dfield.type() == sfield.type():
74+
if (dfield.name().upper() == sfield.name().upper()):
7375
found = dfield
74-
break
76+
if (dfield.type() != sfield.type()):
77+
raise GeoAlgorithmExecutionException(
78+
self.tr('{} field in layer {} has different '
79+
'data type than in other layers.'))
7580

7681
if not found:
7782
fields.append(sfield)
7883

84+
total = 100.0 / float(totalFeatureCount)
7985
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
80-
fields, layer1.wkbType(), layer1.crs())
86+
fields.toList(), layers[0].dataProvider().geometryType(),
87+
layers[0].crs())
8188

82-
total = 100.0 / float(count)
83-
count = 0
89+
featureCount = 0
8490
for layer in layers:
85-
idx = {}
86-
for dfield in fields:
87-
i = 0
88-
for sfield in layer.pendingFields():
89-
if sfield.name() == dfield.name() and \
90-
sfield.type() == dfield.type():
91-
idx[dfield] = i
92-
break
93-
i += 1
94-
95-
features = vector.features(layer)
96-
for f in features:
97-
sAttributes = f.attributes()
98-
dAttributes = []
99-
for dfield in fields:
100-
if dfield in idx:
101-
dAttributes.append(sAttributes[idx[dfield]])
91+
for feature in layer.dataProvider().getFeatures():
92+
sattributes = feature.attributes()
93+
dattributes = []
94+
for dindex, dfield in enumerate(fields):
95+
if (dfield.type() == QVariant.Int):
96+
dattribute = 0
97+
elif (dfield.type() == QVariant.Double):
98+
dattribute = 0.0
10299
else:
103-
dAttributes.append(dfield.type())
104-
f.setAttributes(dAttributes)
105-
writer.addFeature(f)
106-
107-
count += 1
108-
progress.setPercentage(int(count * total))
100+
dattribute = ''
101+
102+
for sindex, sfield in enumerate(layer.dataProvider().fields()):
103+
if (sfield.name().upper() == dfield.name().upper()):
104+
if (sfield.type() != dfield.type()):
105+
raise GeoAlgorithmExecutionException(
106+
self.tr('Attribute type mismatch'))
107+
dattribute = sattributes[sindex]
108+
break
109+
110+
dattributes.append(dattribute)
111+
112+
feature.setAttributes(dattributes)
113+
writer.addFeature(feature)
114+
featureCount += 1
115+
progress.setPercentage(int(featureCount * total))
109116

110117
del writer

0 commit comments

Comments
 (0)
Please sign in to comment.