In this task we will use python scripting to buffer the features of a vector layer (using a buffer distance stored in a field) and save it as a memory layer. The Processing algorithm Variable distance buffer does the same thing, but we want to do it using Python.
We can use the following code (if you don’t know how to create a new script from Processing, please see here):
##Input_Layer=vector ##Distance_Field=field Input_Layer ##Segments=number 10 ##Buffer_only_selected_features=Boolean False from qgis.core import * from qgis.PyQt.QtCore import QVariant layer = processing.getObject(Input_Layer) crs = layer.crs().toWkt() # Create the output layer outLayer = QgsVectorLayer('Polygon?crs='+ crs, 'outLayer' , 'memory') prov = outLayer.dataProvider() fields = layer.pendingFields() # Fields from the input layer fields.append(QgsField('drawn_area', QVariant.Double, '', 10, 3)) prov.addAttributes(fields) # Add input layer fields to the outLayer outLayer.updateFields() # Check for selected features if layer.selectedFeatures() and Buffer_only_selected_features is True: features = layer.selectedFeatures() else: features = layer.getFeatures() # Generate buffers for feat in features: inAttr = feat.attributes() # Input attributes inGeom = feat.geometry() # Input geometry bf_inGeom = inGeom.buffer(feat[Distance_Field], Segments) poly=bf_inGeom.asPolygon() drawn_area = bf_inGeom.area() inAttr.append(drawn_area) outGeom = QgsFeature() outGeom.setGeometry(QgsGeometry.fromPolygon(poly)) # Output geometry outGeom.setAttributes(inAttr) # Output attributes prov.addFeatures([outGeom]) # Add the layer to the Layers panel QgsMapLayerRegistry.instance().addMapLayer(outLayer)
You can save the buffered vector layer by right clicking on its name in the Layers Panel and then by clicking “Save as…”.
We need to make some remarks:
- In addition to the creation of the geometries, the script will create a new field (called “drawn_area”) which stores the numerical value of the drawn area: its value depends on how many segments you set in the input window (the larger the number of segments, the better the result);
- you may decide to buffer only selected features;
- this script will work for any geometry type (point, line, polygon).
As an example, we test the script on a set of sample vector points (15 points):
which have the value of the buffer distance stored in the attribute called “radius”:
If we set the number of segments equal to 20:
this will be the result of the buffer:
and this will be the corresponding attribute table: