-1

I am developing a plugin in QGIS and I was given a task to develop a plugin without using the inbuilt functions of QGIS. Now, For most of the case I have avoided using built-in modules like sum line length tools to calculate line and using the intersection.length() instead, but now I am stuck on buffer. Let's say I have a line file and I want to make a buffer around it, so I wanted to know, is there any way to make buffer in QGIS without using the buffer processing tool and completely coding it.

A buffer like the image below

I don't want to use processing.run("native:buffer", {dict of parameters}) but I want to know is there a method to code it and not use this function.

enter image description here

4
  • 2
    why? is this a homework problem?
    – Ian Turton
    Commented Jun 4, 2021 at 16:04
  • More like research study problem. Under a professor. Commented Jun 4, 2021 at 16:09
  • 4
    then the best way to learn is to try to solve it yourself instead of asking here. Feel free to come back when you have tried a solution and got stuck. Don't forget you can study the source code of QGis and other open source programs
    – Ian Turton
    Commented Jun 4, 2021 at 16:14
  • 2
    While learning how the algorithms of GIS work is important, this "reinvent every wheel" approach seems... counterproductive (since you're also likely reinventing every defect as well).
    – Vince
    Commented Jun 4, 2021 at 17:19

1 Answer 1

4

Try the following (after you selected a layer)

Be aware that we use as an input a layer using EPSG:4326 (hence, the buffer 0.2 degrees = around 20km depending where you are on the globe). The buffer function uses units from the geometry SRS. You may need to reproject (good thing to learn for your "homework")

layer = iface.activeLayer()
# layer = QgsVectorLayer("path/to/layer", "polygon", "ogr")

feats = [QgsFeature(feat) for feat in layer.getFeatures()]

new_feats = []
for feat in feats:
    geom = feat.geometry()
    feat.setGeometry(geom.buffer(0.2, 8))
    new_feats.append(feat)

mem_layer = QgsVectorLayer("Polygon?crs=epsg:4326", "duplicated_layer", "memory")

mem_layer_data = mem_layer.dataProvider()
attr = layer.dataProvider().fields().toList()
mem_layer_data.addAttributes(attr)
mem_layer.updateFields()
mem_layer_data.addFeatures(new_feats)

QgsProject.instance().addMapLayer(mem_layer)

PS: Code mainly borrowed from Duplicating layer in memory using pyqgis? and adapted

Edit:

For dissolve support, you can take a look at C++ code to see how it works in original processing C++ code you try to avoid ;) https://github.com/qgis/QGIS/blob/master/src/analysis/processing/qgsalgorithmbuffer.cpp.

Be aware that reimplementing all the buffer functionalities in Python is a bit of a waste in fact. The processing buffer was in the "old days" in Python and to speed up has been ported in C++. So, you lose all the benefits with your approach. FYI,you can look at old code buffer.py (for QGIS 2.18)

2
  • I also wanted to implement the dissolve result feature in buffer, the way it asks on the buffer dialog box, in this code the buffer might overlap. Commented Jun 4, 2021 at 22:45
  • Edited for the "dissolve" part
    – ThomasG77
    Commented Jun 4, 2021 at 23:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.