0

I have a script that creates a square buffer of 1 degree around a point in QGIS, through the python console but I am unable to find a way to create circular buffers instead. Also, would it be possible to add to the script to add multiple buffers around the same point of different distances, as I currently have 1 degree but would like 5 degrees, 10 degrees... etc. The script I have currently written:

layer = iface.activeLayer()

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

epsg = layer.crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer&field=x:real&field=y:real&field=point_id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'circular_buffer',
                           'memory')

prov = mem_layer.dataProvider()

for i, feat in enumerate(feats):
    point = feat.geometry().asPoint()
    new_feat = QgsFeature()
    new_feat.setAttributes([i, point[0], point[1], feat.id()])
    tmp_feat = feat.geometry().buffer(1, -1).boundingBox().asWktPolygon()
    new_feat.setGeometry(QgsGeometry.fromWkt(tmp_feat))
    prov.addFeatures([new_feat])

QgsProject.instance().addMapLayer(mem_layer)
5
  • 1
    Have you tried to use: tmp_feat = feat.geometry().buffer(1, -1).asWktPolygon() instead. without the boundingbox function it should return a circular buffer
    – eurojam
    Commented Nov 18, 2020 at 16:35
  • 1
    A one degree buffer is an odd requirement, since degrees are angular measurements which measure wildly differing distances depending on latitude. A sixty nautical mile buffer would be slightly oblate over the Equator, and more and more egg-shaped as you increased latitude, so if you're doing a buffer in decimal degrees and see a circle, it's pretty much always wrong.
    – Vince
    Commented Nov 18, 2020 at 18:56
  • @eurojam Unfortunately after removing the bounding box function, it comes up with an error - AttributeError: 'QgsGeometry' object has no attribute 'asWktPolygon'. Any ideas?
    – LiamHems
    Commented Nov 19, 2020 at 11:20
  • @Vince I have tried to get a different CRS so that it would be in metres or another measurement other than degrees but every time I change the projection, I either can not see the geojson file or other files within my project
    – LiamHems
    Commented Nov 19, 2020 at 11:21
  • 1
    GeoJSON is restricted to WGS84 (4326), so that's nearly a different issue (GeoJSON isn't mentioned anywhere in the question). Note that projection "change" usually applies to clobbering the existing CRS, when "reprojection" is usually the goal.
    – Vince
    Commented Nov 19, 2020 at 12:25

1 Answer 1

1

You can try the following, which will work anyway. Since the tmp_feat is from type geometry you can pass it directly to new_feat.setGeometry(tmp_feat)

layer = iface.activeLayer()
feats = [ feat for feat in layer.getFeatures() ]
epsg = layer.crs().postgisSrid()
uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer&field=x:real&    field=y:real&field=point_id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                       'circular_buffer',
                       'memory')
prov = mem_layer.dataProvider()

for i, feat in enumerate(feats):
    point = feat.geometry().asPoint()
    new_feat = QgsFeature()
    new_feat.setAttributes([i, point[0], point[1], feat.id()])
    tmp_feat = feat.geometry().buffer(1, -1)
    new_feat.setGeometry(tmp_feat)
    prov.addFeatures([new_feat])

QgsProject.instance().addMapLayer(mem_layer)
3
  • Thank you very much, it works now!
    – LiamHems
    Commented Nov 19, 2020 at 11:41
  • Do you know how I would be able to change the buffer opacity to 50% and to also change the color of the buffer to red too? Thanks
    – LiamHems
    Commented Nov 19, 2020 at 13:34
  • 1
    it is something like: sym =mem_layer.renderer().symbol() sym.setColor(QColor("red")) sym.setOpacity(50)
    – eurojam
    Commented Nov 19, 2020 at 17:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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