PyQGIS introduction

Let’s start with simple tasks.

First steps

Layers access

Task

  • list of layers determined from current project (even unsaved) on line 1

  • print layer name and feature count for vector layers (3)

  • for other layer types print only name (5)

1for layer in QgsProject.instance().mapLayers().values():
2    if layer.type() == QgsMapLayer.VectorLayer:
3        print (layer.name(), layer.featureCount())
4    else:
5        print (layer.name())

Script to download.

../_images/qgis_editor.png

Fig. 3 Example of running simple script from QGIS built-in editor.

Task

  • skip disabled layers on line 2

  • process only vector layers with multipolygon geometry type (5)

  • loop over features on line 9

  • get feature geometry on line 10

  • get attribute value nazev (name in Czech) if exists (12)

  • print feature info (fid, name, area in hectares - assuming map units meters), see line 16

 1for layer in QgsProject.instance().mapLayers().values():
 2    if not QgsProject.instance().layerTreeRoot().findLayer(layer.id()).itemVisibilityChecked():
 3        continue
 4
 5    if layer.type() != QgsMapLayer.VectorLayer or layer.wkbType() != QgsWkbTypes.MultiPolygon:
 6        continue
 7  
 8    print (layer.name(), layer.featureCount())
 9    for feat in layer.getFeatures():
10        geom = feat.geometry()
11        try:
12            nazev = feat['nazev']
13        except KeyError:
14            nazev = 'no name defined'
15            
16        print ('{0}: {1} {2:.1f} ha'.format(feat.id(), nazev, geom.area()/1e4))

Script to download.

Vector data, features access and editing

Sample data (ice cream shops in Czech Republic downloaded from OpenStreetMap as points only): ice_cream.csv.

Adding CSV-based layers

Task

  • load layer without geometry (as table) (see lines 2 and 5)

  • add table layer into layer tree (6)

1filename = '/home/martin/Downloads/ice_cream.csv'
2uri = 'file:///{}?delimiter=,'.format(filename)
3
4name = os.path.splitext(os.path.basename(filename))[0]
5layer = QgsVectorLayer(uri, name, 'delimitedtext')
6
7QgsProject.instance().addMapLayer(layer)

Script to download.

Task

  • geometry built from longitute and latitude

  • set spatial reference system to EPSG:4326

  • add map layer into layer tree

1filename = '/home/martin/Downloads/ice_cream.csv'
2uri = 'file:///{}?delimiter=,&xField=lon&yField=lat&crs=epsg:4326'.format(filename)
3
4name = os.path.splitext(os.path.basename(filename))[0]
5layer = QgsVectorLayer(uri, name, 'delimitedtext')
6
7QgsProject.instance().addMapLayer(layer)

Script to download.

Save layer into file-based GIS format

Task

  • reproject to S-JTSK (EPSG:5514) (target CRS set on line 4)

  • save layer into Esri Shapefile format (this task performed on lines 5-7)

 1layer = QgsProject.instance().mapLayersByName('ice_cream')[0]
 2
 3shp_file = "/tmp/ice_cream.shp"
 4crs = QgsCoordinateReferenceSystem("EPSG:5514")
 5QgsVectorFileWriter.writeAsVectorFormat(
 6    layer, shp_file,
 7    "UTF-8", driverName="ESRI Shapefile", destCRS=crs)
 8                                        
 9layer_shp = QgsVectorLayer(shp_file, "test", "ogr")
10print(layer_shp.isValid())

Script to download.

Task

Improvements

  • check if input layer found (see line 1)

  • check for writter’s errors (see cookbook example)

Editing vector features

Let’s delete all features (ice cream shows) located more than 1km from specified point.

Task

  • point of interest must be transformed into layer’s CRS (10-13)

  • area of interest is defined by rectangle on lines 15-19

  • invert selection on line 24

  • delete selected features on line 27

  • note that layer must be switched to edinging mode, it can be done eg. by triggers, see lines 26,28

 1shp_file = "/tmp/ice_cream.shp"
 2layer = QgsVectorLayer(shp_file, "test", "ogr")
 3
 4QgsProject.instance().addMapLayer(layer)
 5
 6x = 14.3881100
 7y = 50.1041200
 8geom = QgsGeometry.fromPointXY(QgsPointXY(x, y))
 9
10p_crs = QgsCoordinateReferenceSystem("EPSG:4326")
11trans = QgsCoordinateTransform(
12    p_crs, layer.crs(), QgsProject.instance())
13geom.transform(trans)
14
15p = geom.asPoint()
16offset = 1500
17p1 = QgsPointXY(p.x() - offset, p.y() - offset)
18p2 = QgsPointXY(p.x() + offset, p.y() + offset)
19aoi = QgsRectangle(p1, p2)
20
21layer.selectByRect(aoi)
22print (len(layer.selectedFeatures()))
23
24layer.invertSelection()
25
26iface.actionToggleEditing().trigger()
27iface.actionDeleteSelected().trigger()
28iface.actionToggleEditing().trigger()

Script to download.

Task

Compare with

layer.startEditing()
layer.deleteSelectedFeatures()
layer.commitChanges()