To add even more performance improvements to @MrXsquared's answer by using QgsGeometryEngine
and skipping feature fetching:
point_lyr = QgsProject.instance().mapLayersByName('points')[0]
poly_lyr = QgsProject.instance().mapLayersByName('polygons')[0]
ids = []
point_lyr.removeSelection() #clear selection
# build a spatial index on the points (with flag to be able to retrieve geometries)
point_lyr_idx = QgsSpatialIndex(point_lyr.getFeatures(), flags=QgsSpatialIndex.FlagStoreFeatureGeometries)
for polygon in poly_lyr.getFeatures():
poly_geometry_engine = QgsGeometry.createGeometryEngine(polygon.geometry().constGet())
poly_geometry_engine.prepareGeometry()
for pointid in point_lyr_idx.intersects(polygon.geometry().boundingBox()):
# iterate only over points inside bbox of polygon
point_geometry = point_lyr_idx.geometry(pointid)
if poly_geometry_engine.contains(point_geometry.constGet()): # check if point is actually inside polygon
ids.append(pointid)
break # stop iteration after first match and go to next polygon
point_lyr.selectByIds(ids)
QgsGeometryEngine
can be really powerful in some cases so it is useful to know about it (in some cases I have gotten a x100 performance improvement using it).
With these improvements you can get a ~20-30% improvement compared to @MrXsquared's answer.
select by expression
with geometry intersection?select by expression
should be more efficient but you need those magical spell codes.