2

Description of my problem (somewhat simplified)

I have two datasets:

  • One polygon layer "villages" which represents the boundary of villages

  • One point layer "buildings" which represent buildings. This layer has the attributes "year of construction" and "type".

I would like to count the number of buildings (points) inside each village (polygone) which are of a given type and age, namely:

  • Number of individual houses with year of construction < 2000

  • Number of individual houses with year of construction > 2000

  • Number of appartment buildings with year of construction < 2000

  • Number of appartment buildings with year of construction > 2000

The following figure shows an example, with the blue polygon representing the village and each point a building, with styling applied to distinguish the 4 categories of buildings mentionned above (purple: buildings <2000; green: buildings >2000; triangles: individual houses; squares: appartment buildings):

I know how to count points within a polygon using "Analysis Tools" in the "Processing framework" plugin, but I do not how to count only the points which respect a given rule.

Any suggestions?

3
  • 1
    How about join attributes by location so the buildings also "know" which village they're in, then do the filtering?
    – Erik
    Commented Oct 10, 2019 at 13:17
  • Thanks for the advice, I hadn't thought of it. I will try and let you know! Commented Oct 10, 2019 at 13:18
  • I tried, but got this error: QgsFeature.setGeometry(QgsGeometry): argument 1 has unexpected type 'NoneType' See log for more details Commented Oct 10, 2019 at 13:28

2 Answers 2

3

Use "Select by Location" under Vector > Research Tools. Use that to select all of the points which are in the polygon.

Then open the attribute table of the points, click "Select features using an expression", use something like the following:

"type" = 'individual' AND "year of construction" < 2000

Then click the small drop down arrow next to Select Features and click "Filter Current Selection", this will use that expression to only select from what you have already selected using the polygon.

Repeat this for each combination of variables.

2
  • Thank you for your answer. Your solution works. However, the problem with this approach is that all points which are within polygons are selected as I have several polygons to represent different villages. I would need to create a unique polygon for each village, do the calculations, and then delete the polygon before moving on to the next village. Given the number of villages which I have to process, this would be very time consuming and I was hoping there would be some automatic way to process all villages at once. Commented Oct 10, 2019 at 13:49
  • 1
    @johnwolf1987, if you have a 'name' field for each village in your dataset then you could intersect your buildings dataset with the villages dataset, so that each building is attributed with the corresponding village. Your summary statistics could then be generated from the building dataset attributes.
    – ABragg
    Commented Oct 10, 2019 at 14:41
2

Use a virtual layer:

Layer -> Create Layer -> New Virtual Layer

enter image description here

and enter a query like this:

SELECT v.VillageName,
v.geometry,
SUM(CASE WHEN h.Hyear>2000 THEN 1 ELSE 0 END) "H_New",
SUM(CASE WHEN h.Hyear<=2000 THEN 1 ELSE 0 END) "H_Old",
SUM(CASE WHEN h.Fyear>2000 THEN 1 ELSE 0 END) "F_New",
SUM(CASE WHEN h.Fyear<=2000 THEN 1 ELSE 0 END) "F_Old"
FROM "Random points" h ,"Village"  v
WHERE ST_Contains(v.geometry, h.geometry)
GROUP by v.VillageName

enter image description here

Output

enter image description here

where labels were formatted as follows:

concat( 
"VillageName" , 
'\n  * H_New: ',"H_New" ,
'\n  * H_Old: ', "H_Old" ,
'\n  * F_New: ', "F_New" ,
'\n  * F_Old: ', "F_Old" 
)

Table:

enter image description here

1
  • Your method works, and it was very helpful, thank you! However, strangely I did a cross-check of the results (on several values) using the other method posted by TeddyTedTed, and the value was somewhat different (e.g. 105 vs. 153). It seems that the method using the virtual layer always has around 50% more points. Commented Oct 17, 2019 at 12:22

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.