5

I have two sets of polygons. One contains villages, the other farming areas.

There can be several farming areas in one village. Crucially, there can be cross-village farming areas.

My approach to get the area of all farming areas per village was this:

  1. save both shapefiles in EPSG:3857 projection (pseudo-Mercator)
  2. fix geometries
  3. clip (farming areas to my villages)
  4. intersection (to cut the farming areas by the village borders)
  5. calculate the area in square meters via the attribute table ($area)
  6. join attributes by location (summary) - the sum of the field square meters

Now, this is overall rather cumbersome. Is there an easier way to get to the result?

The problem: the resulting sum of areas is wrong. In (6) I tried different types of intersection (intersect, overlap, contain), but none resulted in the equivalent to what I can add up manually?

Maybe somebody sees an obvious mistake here? Otherwise, I can try to upload data for testing.


Edit:

To further specify: The main issue for this case was that the villages are directly adjacent and farms can cross borders.

enter image description here

10
  • I did it to accelerate later processes. Farming areas cover a much wider area than my actual area of interest, as determined by the village layer.
    – kemajuan
    Commented Sep 4 at 12:23
  • You want a table with one row per village and a column with the sum of total farming area in that village?
    – Bera
    Commented Sep 4 at 13:12
  • That is correct.
    – kemajuan
    Commented Sep 4 at 13:13
  • Skipping the clipping step does not alter the results. They are still wrong.
    – kemajuan
    Commented Sep 4 at 13:16
  • I think an expression to perform the calculation like this should work, I have tested it and it seems fine. area( intersection($geometry, aggregate( layer:='yourfarminglayer' ,aggregate:='collect' ,expression:=$geometry) ) )
    – Sethinacan
    Commented Sep 4 at 13:30

2 Answers 2

5

If you have many features QGIS processing tools will be fast.

enter image description here

  1. My farms can overlap so I start with Dissolve (advanced option: keep disjoint features separate)
  2. Intersect farms with villages
  3. Field calculate an area field (decimal type) with the expression $area to calculate each intersection polygons area.
  4. Statistics by categories: enter image description here

enter image description here

2
  • 1
    Essentially, surprisingly and annoyingly, the command "join attributes by location (summary)" fails to deliver the right results in this use case. Your solution, @Bera, with "statistics by categories" works - thanks!
    – kemajuan
    Commented Sep 5 at 8:40
  • Nice. I suspect the join is creating duplicate rows
    – Bera
    Commented Sep 5 at 9:05
4

You can perform this calculation in an expression rather than using the sequence you have described.

Using your villages layer this expression will calculate the area of intersection you can use this in the attributes table or as a label if that helps for testing.

Note you need to change your layer name 'yourfarminlayer'

area(
    intersection($geometry,
        aggregate( 
            layer:='yourfarminlayer'
            ,aggregate:='collect'
            ,expression:=$geometry)
    )
)

The two interesting functions are:

intersection Returns a geometry that represents the shared portion of two geometries. you use this to do the intersecting

aggregate Returns an aggregate value calculated using features from another layer. this collects the geometry from your farming layer

You can also use this expression (omitting the area function) to draw the intersection areas using a geometry generator in your villages layer.

4
  • When I start the calculation in the field calculator qgis turns into 'not responding' 'mode'. For half an hour this has not changed now. The reason might be that farming has about 370,000 features, 130,000 of which are within the 2,148 villages. The approach is not working out for me thus far.
    – kemajuan
    Commented Sep 4 at 14:30
  • I would test with a subset of your data
    – Sethinacan
    Commented Sep 4 at 14:43
  • It works for a subset but remains unfeasible for my use case.
    – kemajuan
    Commented Sep 5 at 8:30
  • @kemajuan that's a shame, i'll leave the answer as it may be good for others with a similar issue but less demanding data
    – Sethinacan
    Commented Sep 5 at 9: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.