I have two polygon layers of the same area, which represent census subdivisions from two different census years. Between the two census, the precision of the polygons has improved a bit, so that the polygons don't perfectly match. also, some polygons have disappeared and new ones have been created.

Is there a way, in QGIS, to incorporate the data from the old census boundaries into the polygons boundaries of the new one, despite bouderies differences?

  • You could use the Point on Surface tool, with the create point on surface for each part checked to create points with the polygon attributes. This avoids the problem of centroids being outside a shape. You could then spatially join that to your newer census polygons. Due to shape differences it is still possible a point from the old is outside a corresponding new polygon, a quick check with the count points in polygons tool will indicate if any poly gets 2 points. In an edit session move any of these points to be in the correct polygon. Then run the spatial join.
    – John
    Aug 4, 2022 at 20:10

1 Answer 1


To copy the attributes from one polygon layer to another where both polygons more or less - but not perfectly - overlap can be done by defining a point inside the polygon of one of the layer (here: the one called new) and check within which polygon of the other layer (here: old) this point is. Like this you reduce the problem of not-perfectly-overlapping to a point and ignore the (slightly) differing shapes of the two versions of polygons.

Once identified the polygons belonging togethis in this way, it is easy to copy the attributes from the old one to the new one. This can be done using QGIS expressions with Field calculator - see below for the expression to use.

Red labels come from the attribute table of layer old, blue labels are generated on the new layer using the expression below: enter image description here

Use this expression on the new layer and replace old with the name of your old polyon layer:

attribute (
    get_feature_by_id (
        array_max (
            array_foreach (
                overlay_nearest ('old', $id, limit:=12),
                if (
                    within (
                        point_on_surface ($geometry),
                        geometry (
                            get_feature_by_id ('old',@element)
  • Wow, thank you so much! I'll try it out :)
    – Lucien S.
    Aug 8, 2022 at 14:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.