PyQGIS: Get Feature Geometry
Geometry is what defines the shape and spatial location of a feature. Features can be points, lines, or polygons, can be anywhere on earth, and can be represented by coordinates in a number of different units (depending on the coordinate reference system, or projection). Points are represented by a single coordinate pair while lines and polygons are represented by multiple coordinate pairs.
Copying, or updating the shape or location of a feature requires you to access the feature’s geometry. This tutorial will show the basics of accessing feature geometry with PyQGIS. This example uses a line feature, but can be easily adapted for lines or polygons.
To start, define the path to the file you want to open, open that file as a QGIS vector layer, then get the features in the layer as a list of objects.
fn = "path/to/shapefile.shp" layer = QgsVectorLayer(fn, '', 'ogr') feats = layer.getFeatures()
You have to get the geometry of each feature individually, so loop through each feature in the list of features. A feature’s geometry can be accessed by calling geometry()
.
for feat in feats: geom = feat.geometry()
If you already know exactly what type your geometry is, you can get the shape’s final geometry with geom.asPolyline()
or geom.asMultiline()
. However, if you’re unsure of the layer’s geometry type, or if it is single-part or multi-part you’ll need a little more code. It’s always safest to check for the geometry type in the code to avoid any errors.
The geometry’s type can easily be accessed with geom.wkbType()
. WKB stands for ‘well-known binary’ format. Geometry type can be either single type — one shape (line, point, polygon) per geometry entry– or multi type — more than one shape per geometry. This can be assessed by passing the geometry type to isSingleType
, which returns True or False.
for feat in feats: geom = feat.geometry() geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
Now we’re going to make two checks using if
statements. First, we’ll check to be sure the geometry type is a Line Geometry. Second, we’ll check if the geometry is single-part or multi-part using the geomSingleType
variable we created above. Note that QgsWkbTypes.LineGeometry
can be substituted for points or polygons with PointGeometry
or PolygonGeometry
.
for feat in feats: geom = feat.geometry() geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType()) if geom.type() == QgsWkbTypes.LineGeometry: if geomSingleType:
Finally, if the geometry is single-type (single-part) you can access the geometry with asPolyline()
, or if it is multi-type (multi-part) with asMultiPolyline(
). The print statement prints the resulting geometry.
for feat in feats: geom = feat.geometry() geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType()) if geom.type() == QgsWkbTypes.LineGeometry: if geomSingleType: x = geom.asPolyline() print("line:", x) else: x = geom.asMultiPolyline() print("multiline:", x)
Here is the final code block we have created. Watch the video below for a step-by-step demonstration of the process.
fn = "path/to/shapefile.shp" layer = QgsVectorLayer(fn, '', 'ogr') feats = layer.getFeatures() for feat in feats: geom = feat.geometry() geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType()) if geom.type() == QgsWkbTypes.LineGeometry: if geomSingleType: x = geom.asPolyline() print("line:", x) else: x = geom.asMultiPolyline() print("multiline:", x)