5

I'm new to QGIS, making the switch from ArcMap. I have 5 shapefiles of polygons representing 5 years of insect defoliation. I need to overlay the 5 years and create a new composite shapefile that is a union of all 5.

There are some areas where the polygons overlap from year to year and I want the polygons of the new composite shapefile to have an attribute field "Number_of_Yrs" which represent the total number of years of defoliation. The values of this field should be 1 to 5 years.

3
  • Maybe easier to realise using raster layers? Rasterize your polygons and use raster calculator.
    – Babel
    Commented Apr 2, 2021 at 22:53
  • Could you add an image showing what exactly you mean? Commented Apr 2, 2021 at 23:07
  • In ArcGIS, you'd Union the polys and encode based on the number of non-universe polygon ids (I'd use a DA Update Cursor, but the field calculator would do it)
    – Vince
    Commented Apr 3, 2021 at 3:03

1 Answer 1

2
  1. Convert the polygons to lines - Menu Vector / Geometry tools / Polygons to lines - use batch mode to convert all 5 polygons at once.

  2. Merge the line layers created in step 1 to one line layer using Menu Processing / Toolbox / Merge vector layers

  3. Create a new polygon layer that covers the maximum extent of all your original polygons. Use Menu Processing / Toolbox / Extract layer extent on the lines layer created in step 2.

  4. Now split the polygon created in step 3 with the lines from step 2 using Menu Processing / Toolbox / Split with lines

  5. You will get a new layer where each the original polygons are split up to several polygons, one for each category: no overlap with other polygons, overlapping with one, with two polygons etc. Create a new attribute with field calculator that counts the number of orginal polygons that overlap using the following expression (explanation below).

Remark: In line 3, in paranthesis insert the names of the layers that contain your original polygons. In my case, they are named layer1,layer2 etc. - don't forget the single quotes ' around the layer names.

array_sum( 
    array_foreach (
    array ('layer1','layer2','layer3','layer4','layer5'),
        case
        when  
            within( 
                point_on_surface( $geometry),  
                aggregate( 
                    @element, 
                    'collect', 
                    $geometry
                )
            ) 
        then 1
        else 0
        end
    )
)

Explanation: the expression creates a point inside the splitted polygons (point_on_surface( $geometry)) from step 4 and then for each of your original layers loops through (using array_foreach) an expression that looks if (case when) this point is within (line 6) layer1, layer2 etc.: the aggregate() function on line 8 to 12 that takes the layer-name for each loop from @element: this refers to the arguments of the array() in line 3. Each time the point is within the polygon, the output value is set to 1, otherwiese to 0 (line 14-15). The output is an array like e.g. [ 0, 1, 0, 1, 1 ]. So now just get the sum of the elements contained in the array with array_sum( ) and you get: 3 (in this example.

Screenshot: the result for 5 polygons (outlined in different colors). The label indicates for each splitted part how many polygons overlap there: enter image description here

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.