Read my previous posts Summary Aggregate and Spatial Filters and Advanced Aggregate Expressions to Automate QA to learn more about the powerful aggregate function.

The aggregate function in QGIS was designed to work with 2 separate input vector layers, but we can also make it work with a single layer. Essentially performing spatial queries for features within the layer.

Consider this problem. In a layer containing zip codes, we want to find all neighboring zip codes for every polygon. This can be done very easily by creating a new field with an expression with the aggregate function – using the layer itself as the parent layer.

Below is the Zip Codes shapefile from the City of Seattle Open Data Portal. Our task is to add another field which contains all neighboring zip codes for each feature. Note the layer name is Zip_Codes

Open the Attribute Table for the layer. Note the field name containing the 5-digit zip code is ZIPCODE . Open Field Calculator.

Create a new field with the following expression. The key here is the spatial filter touches($geometry, geometry(@parent)) that finds all polygons from the layer that touch the feature being processed.

aggregate(
 layer:= 'Zip_Codes',
 aggregate:='concatenate',
 expression:=ZIPCODE,
 concatenator:=', ',
 filter:=touches($geometry, geometry(@parent))
 )

You will now have a new field that has the neighbors zip codes for every feature in the layer!

There are many type of aggregate that you can use. If you want to count numbering zip codes, you can use the count aggregate instead of concatenate. The following expression would calculate the number of neighboring polygons.

aggregate(
 layer:= 'Zip_Codes',
 aggregate:='count',
 expression:=$id,
 filter:=touches($geometry, geometry(@parent))
 )

2 thoughts on “Find Neighbor Polygons using Summary Aggregate Function in QGIS

  1. Hi Ujaval, thanks for sharing this post.

    I have tried your example with the world borders shapefile (https://thematicmapping.org/downloads/world_borders.php) and QGIS returns some strange results (e.g. “Cuba” touches “USA”?!! and other countries that share a common border but they don’t appear in the results).

    Any suggestions to overcome this problem? By the way, I am using QGIS 3.4.7. The code I used can be seen below:

    aggregate(
    layer:= ‘TM_WORLD_BORDERS-0.3′,
    aggregate:=’concatenate’,
    expression:=NAME,
    concatenator:=’, ‘,
    filter:=touches($geometry, geometry(@parent))
    )

    ps1. When I use the count function, it returns zero for all the countries.
    ps2. When I use the Zip Codes shapefile, the same issue appears (e.g. in the zip code 98406, where should be 6 neighbors, but only 3 appear).

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.