In this recipe, we'll perform a spatial operation to select a subset of a point layer based on the points contained in an overlapping polygon layer. We'll use shapefiles in both cases, with one being a point layer and the other a polygon. This kind of subset is one of the most common GIS operations.
We will need two new shapefiles that have not been used in previous recipes. You can download the point layer from https://geospatialpython.googlecode.com/files/MSCities_Geo_Pts.zip.
Similarly, you can download the geometry layer from https://geospatialpython.googlecode.com/files/GIS_CensusTract.zip.
Unzip these shapefiles and place them in a directory named ms
within your qgis_data
directory, within your root or home directory.
In this recipe, we will perform several steps to select features in the point layer that fall within the polygon layer, as follows:
lyrPts = QgsVectorLayer("/qgis_data/ms/MSCities_Geo_Pts.shp", "MSCities_Geo_Pts", "ogr")
lyrPoly = QgsVectorLayer("/qgis_data/ms/GIS_CensusTract_poly.shp", "GIS_CensusTract_poly", "ogr")
QgsMapLayerRegistry.instance().addMapLayers([lyrPts,lyrPoly])
ftsPoly = lyrPoly.getFeatures()
for feat in ftsPoly:
geomPoly = feat.geometry()
featsPnt = lyrPts.getFeatures(QgsFeatureRequest().setFilterRect(geomPoly.boundingBox()))
for featPnt in featsPnt: if featPnt.geometry().within(geomPoly):
print featPnt.id() lyrPts.select(featPnt.id())
iface.setActiveLayer(lyrPoly)
iface.zoomToActiveLayer()
While QGIS has a number of tools for spatial selection, PyQGIS doesn't have a dedicated API for these types of functions. However, there are just enough methods in the API, thanks to the underlying ogr/GEOS
library, that you can easily create your own spatial filters for two layers. Step 7 isn't entirely necessary, but we gain some efficiency using the bounding box of the polygon to limit the number of point features we're examining. Calculations involving rectangles are far quicker than detailed point-in-polygon queries. So, we quickly reduce the number of points we need to iterate through for the more expensive spatial operations.