2

I'm really struggling trying to create a field which lists the neighbouring cells of my grid. I have a grid of 814 cells, and for most cells (i.e. the ones which are fully surrounded) there are eight neighbouring cells.

In the field calculator, I am setting the field type to string, and the field length to a number way higher than needed. The layer is called "Clip" and the output I want is a list of the "id" numbers which is a field in itself.

The preview of this code is correct. For most cells, the output is eight. But when I click Ok, the output in the new field is NULL. I've tried changing the filter to touches() and I've tried adding a buffer around the geometry(@parent) bit.

The code I'm using is...

aggregate(
    layer:= 'clip',
    aggregate:= 'concatenate',
    expression:= to_string("id"),
    concatenator:= ', ',
    filter:= intersects($geometry, geometry(@parent))
    )
Taras
  • 32,823
  • 4
  • 66
  • 137
user196896
  • 21
  • 1
  • 1
    I suggest to check @Babel's answers, i think once he answered the same question – Taras Nov 29 '21 at 10:51
  • Have you tried to convert this aggregate to string with array_to_string(your_current_code) ? – J. Monticolo Nov 29 '21 at 11:03
  • if it is not mandatory to work with aggregate(...) , one can use this expression: array_to_string(array_sort(overlay_touches(@layer, "id"))) – Taras Nov 29 '21 at 11:35
  • The array_to_string code is definitely a step in the right direction thank you!!! I opened the grid in a new QGIS project, so it didn't have all the other things going on around it. And I tried this code. I got some really good outputs, but mostly I have only 6 or 7 of the 8 neighbouring cells. Is there a way of indicating all cells which are within a given radius? – user196896 Nov 29 '21 at 11:48
  • 1
    do a buffer function with your $geometry. Beware of geographic CRS like WGS84, buffer function is better with cartesian and projected coordinate systems. – J. Monticolo Nov 29 '21 at 12:01
  • The function you are using outputs a string, but if you try to use it in a defined numeric field you will always get NULL. Then, try to create a new field and define it as a string. – pigreco Nov 29 '21 at 12:54
  • 1
    using virtual layers gives you more flexibility. Similar question here: https://gis.stackexchange.com/a/318205/7849 – PieterB Nov 29 '21 at 13:14
  • 1
    So the code which worked was array_to_string(array_sort(overlay_touches(@layer, "id"))). I'm not sure how to add a buffer to this. I'm working in WGS84. I did read the other post on SQL, but I don't have it downloaded and have no knowledge of how to use it. – user196896 Nov 29 '21 at 13:45

1 Answers1

3

Let's assume there is a polygon layer called 'grid_test' with its attribute table, see image below.

input

There is a method that may help you to achieve the desired output by means of the Field Calculator.

1. overlay_intersects()

array_to_string(array_sort(overlay_intersects(@layer, "id")))

2. aggregate()

As was mentioned by @J.Monticolo in his comment, one can use a small buffer around $geometry.

aggregate(
    layer:=@layer,
    aggregate:='concatenate',
    expression:=to_string("id"),
    concatenator:=',',
    filter:=intersects(buffer($geometry, 0.2), geometry(@parent))
        and geom_to_wkt($geometry) != geom_to_wkt(geometry(@parent))
    )

The output shall look as following:

Output:
result1

Taras
  • 32,823
  • 4
  • 66
  • 137