8

I have a point layer with an attribute table like this:

id_point class 1 A 2 B 3 A 4 C 5 B ... 

enter image description here

What I need is to count how many points of any class are in every polygon. Something like this

id_pol A B C pol1 1 2 0 pol2 1 0 1 ... 

Is there a way to count points within polygons grouping by a point attribute using Python in QGIS 3?

I think QGIS 2 had a Count Unique Features by Polygon but I can't find it in QGIS 3.

2
  • In QGIS 3, there is "Count points in polygon" tool which counts unique features with some settings. But your problem is different, and that tools doesn't help you. You should use a script. I've added a script that may help you. Commented May 20, 2020 at 23:02
  • Is there a way to make it work for lines instead of polygons ? Commented Feb 19, 2021 at 10:00

1 Answer 1

11

Use this script:

from PyQt5.QtCore import QVariant # layers polygon_lyr = QgsProject.instance().mapLayersByName("Polygons")[0] point_lyr = QgsProject.instance().mapLayersByName("Points")[0] # index number of "class" field field_index = point_lyr.fields().indexFromName('class') # unique class names unique_classes = point_lyr.uniqueValues(field_index) polygon_lyr.startEditing() # add a field for each class to polygon layer for field_name in unique_classes: if polygon_lyr.fields().indexFromName(field_name)==-1: polygon_lyr.addAttribute(QgsField(field_name, QVariant.Int)) for feat in polygon_lyr.getFeatures(): g = feat.geometry() req = QgsFeatureRequest(g.boundingBox()) # for performance classes = [p["class"] for p in point_lyr.getFeatures(req) if g.contains(p.geometry())] class_numbers_in_polygon = {cls: classes.count(cls) for cls in unique_classes} # add unique class numbers in polygon to the related field for cls in class_numbers_in_polygon: feat[cls] = class_numbers_in_polygon[cls] polygon_lyr.updateFeature(feat) polygon_lyr.commitChanges() 

enter image description here

3
  • Thanks Kadir Şahbaz, your script works fine, but when updating the fields I get an error: 'QgsVectorLayer' object has no attribute 'updatefields', although the new fields are added. I just save as another shp the original polygon layer before the first for instance as not to modify it, then I add the new shp with iface.addVectorLayer and define the layer by name. Commented May 21, 2020 at 11:16
  • Sorry, I've realized that you don't need updateFields in edit mode. I've deleted that line. (It would be updateFields, not updatefields) Commented May 21, 2020 at 11:36
  • Great, I made some changes to adapt it to my script and it worked fine. Thanks. Commented May 21, 2020 at 16:19

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.