I have two polygon layers, A and B, that have the same features but totally different attributes. I want to use the attributes from layer A, but I want them to have the more accurate geometry from layer B. How can I copy the geometry from a feature in layer B and paste it onto the attributes of the same feature in layer A?
Answer
I propose two different ways.
Using processing tools: see my answer to another question. It is not difficult to adapt it to your problem, since it is about polygon overlays
A Python script to copy&paste into Python console or to run from Python editor
The script get 2 layers A, B. Replace them with the names of your layers. B is the one providing the additional attributes. The resulting features go to a new memory layer with all attributes from both layers. Then it loops over all features from A searching for features from B, that contain the centroid of the A features. If such a B is found, take the geometry from A, and attributes from A and B , and write it to memory layer AB.
# get layers
a_layer = QgsMapLayerRegistry.instance().mapLayersByName('A')[0]
b_layer = QgsMapLayerRegistry.instance().mapLayersByName('B')[0]
# prepare result layer
ab_layer = QgsVectorLayer('Polygon?crs=epsg:4326', 'AB', 'memory')
ab_fields = a_layer.dataProvider().fields()
ab_fields.extend( b_layer.dataProvider().fields())
ab_prov = ab_layer.dataProvider()
ab_layer.startEditing()
ab_prov.addAttributes(ab_fields)
ab_layer.commitChanges()
ab_feats = []
# replace with a_layer.selectedFeatures() if you want seleted features only
for feat in a_layer.getFeatures():
# to increase performance filter possible candidates
beefs = b_layer.getFeatures(QgsFeatureRequest().setFilterRect(feat.geometry().boundingBox()))
for beef in beefs:
# check if centroid of A is in B
if feat.geometry().centroid().within(beef.geometry()):
ab_feat = QgsFeature(ab_fields)
ab_attrib = feat.attributes()
ab_attrib.extend(beef.attributes())
ab_feat.setAttributes(ab_attrib)
ab_feat.setGeometry(beef.geometry())
ab_feats.append(ab_feat)
break
# add features to layer
ab_prov.addFeatures(ab_feats)
QgsMapLayerRegistry.instance().addMapLayers([ab_layer])
The script could be used as a template for other topological related feature comparisons as well.
No comments:
Post a Comment