I need to create and "ID" for items within a polygon that also takes into account the name of the polygon that the item is within, so what I need is something along the lines of: poly_X_Item 1-4, poly_Y_Item 1-4, poly_Z_Item 1-4.

I understand that I can use @row_number to create the "ID"s but its just adding the poly id to the field also that im having trouble with.

  • "Items" being what? Polygons, lines, points? Can you show a screenshot of what you have?
    – Babel
    Commented Jul 15, 2021 at 10:21
  • points. sorry my use of terminology might be a little off due to me being pretty new at all this. I cant really share screenshots or anything due to the somewhat sensitive nature of the project
    – snakey866
    Commented Jul 15, 2021 at 10:32

1 Answer 1


You can use an expression like the one that follows, concatenating four different elements using pipes (||) to "stick" them together: text-element poly_ (line 1), the id of the polygon the points are within (line 2), the text element _item_ (line 3) and the id of the point (line 4). Use this to create a new attribute with field calculator (Replace 'polygon' with the name of your polygon layer):

'poly_' || 
array_first ( overlay_within( 'polygon', $id)) || 
'_item_' || 

This preserves the unique id (point item no.) of the points. If it should start from 1 for each polygon, the expression is a bit more complicated:

'poly_' || 
array_first ( overlay_within( 'polygon', $id)) || 
'_item_' || 
to_string (array_find (array_agg (array_first (overlay_within ('polygon', $id))||'_'||-$id,array_first (overlay_within ('polygon', $id))),array_first (overlay_within ('polygon', $id))||'_'||-$id)+1)

Screenshot 1: the first expression used here directly in the label field that dynamically creates the label text: enter image description here

Screenshot 2: the second expression, numbering the items from 1 in each polygon. The number of points per polygong is varying: enter image description here


For the problem rised in the comment, use this expression:

array_first ( overlay_within( 'distribution_area', $id)) || 
'-MST12-' || 
to_string (array_find (array_agg (array_first (overlay_within ('distribution_area', $id))||
-$id,array_first (overlay_within ('distribution_area', $id))),array_first (overlay_within ('distribution_area', $id))||-$id)+1)
  • That's absolutely fantastic thank you so much. The only thing I need to do now is work out how to have this in an actual field as opposed to just in the labels but thanks so much I wasn't even aware that the overlay within part was an option
    – snakey866
    Commented Jul 15, 2021 at 13:47
  • 1
    Use field calculator with the exact same expression to generate it as attribute. Introducing it directly in the label was just for the screenshot/demonstration puropose.
    – Babel
    Commented Jul 15, 2021 at 13:48
  • I am once again using this expression to do the same thing however it is no longer increasing the count by 1 each time for the ID of the items any ideas why this may be? My current expression is as follows: '' || array_first ( overlay_within( 'distribution_area', "name")) || '-MST12-' || to_string (array_find (array_agg (array_first (overlay_within ('distribution_area', $id))||''||-$id,array_first (overlay_within ('disdtribution_area', $id))),array_first (overlay_within ('distribution_area', $id))||''||-$id)+1)
    – snakey866
    Commented Sep 10, 2021 at 13:53

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.