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)
```