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?
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') b_layer = QgsMapLayerRegistry.instance().mapLayersByName('B') # 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.
You've got a few options depending on how your data is organized.
You can perform a table join/relate using a common field between your data sets (with the .dbf of shape file A as the table being joined to shape B) or if your .dbf's present data for the exact same shapes in the exact same order you should be able to replace the .dbf from one to another.
If you are replacing the .dbf manually, be sure to save a copy of it in case it doesn't work and if you do perform a table join, you'll want to make your shape file editable so as to remove any redundant columns. You should end up with a shape file B that has the new geometries and the attributes from shape file A.
Here are three easy methods I am now aware of to do this: 1. (easiest) Using the "Plain Geometry Editor" plugin, display and copy the WKT from a feature in Layer B. Then, using the same plugin, replace the WKT of a feature in Layer A with the copied WKT from Layer B. 2. (in QGIS 3.0 where the above plugin is not available) Using the GetWKT plugin, display and copy the WKT from a feature in Layer B. GetWKT does not have a paste function; so, in Layer A use the Field Calculator to update the field of a selected feature, by calling the function geom_from_wkt('[paste the copied WKT here]'). More details here. 3. Alternatively, use OpenJUMP to directly edit, copy or paste the WKT geometry.