5

In QGIS 3.x how to copy the attributes from a point layer to a polygon layer where the point is within the polygon? In PostGIS I would do:

UPDATE poly_layer SET poly_layer.attribute = point_layer.attribute
FROM point_layer WHERE ST_Within( point_layer.geom, poly_layer.geom );

I realize that there is the "Join Attributes By Location" tool but it creates a new layer which is not convenient for my workflow. And I realize that if my two layers were both PostGIS layers I could simply execute my query in the DB Manager. But in this case I'm trying to copy attributes from a DXF point layer into an existing PostGIS polygon layer.

3
  • So you want to have polygon and point in the same layer ? I t's not possible to mix geometry types in layers in QGIS. You will need to add separate layers.
    – Nil
    Dec 31, 2020 at 7:17
  • Probably best to upload that point layer (Drag'n'Drop in QGIS Browser, or, if you do this regularly, create an import table, COPY the data, and TRUNCATE afterwards), UPDATE (index powered; I also suggest to use plain ST_Intersects - except you expect points falling onto a line with sub-atomic precision*[this is only ever possible for highly modeled cases like regular grids]), and drop the point table again. AFAIK, in the *Field calculator you can only create virtual fields on DB layer sources - not sure rn if you can persist these as columns.
    – geozelot
    Dec 31, 2020 at 8:25
  • Btw., that UPDATE will randomly select from a set of rows in cases where more than one point intersects a Polygon.
    – geozelot
    Dec 31, 2020 at 8:33

1 Answer 1

5

You may use Field calculator to collect attributes from other layer. For example I have two layers county (polygons) and city (points) and I would like to copy city names from city layer to county layer if the city is within the county.

Open the attribute table of county and open Field calculator enter image description here The expression

 aggregate( layer:='city', aggregate:='concatenate', concatenator:=',',expression:="NEV", filter:=contains(geometry(@parent), $geometry))

will collect the "NEV" attributes of all cities inside the county (comma separated). If you have only one point in each polygon or one city name is enough for you then you can use min as aggregate:

 aggregate( layer:='city', aggregate:='min', expression:="NEV", filter:=contains(geometry(@parent), $geometry))
2
  • I was hoping for a pure SQL solution but this certainly does what I need to do. Thank you. Is it possible to limit it to operating on only the selected rows of in the two tables? Dec 31, 2020 at 15:28
  • Oops - I see the toggle to "Only update xx selected features". Dec 31, 2020 at 15:32

Your Answer

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

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