Skip to main content
5 of 5
fixing code errors
xunilk
  • 30.2k
  • 4
  • 43
  • 82

You can directly produce features of concentric buffers as polygons by using linspace method from numpy python module. As you have in your attributes table 1440 features, I know that, in your case, polygon sides number is 360 for each one of your concentric buffers. Algorithm for extracting points for each polygon features is easily inferred; as it can be observed in following PyQGIS code.

import numpy as np
 
bufferLength1 = 1000
bufferLength2 = 2000
bufferLength3 = 3000
bufferLength4 = 4000
polygonSides = 360

pt = QgsPointXY(364067.6920850627, 4426289.212155256)
 
pts1 = [ QgsPointXY(pt[0] + np.sin(angle)*bufferLength1, pt[1] + np.cos(angle)*bufferLength1)
                    for angle in np.linspace(0, 2*np.pi, polygonSides, endpoint = False) ]

pts2 = [ QgsPointXY(pt[0] + np.sin(angle)*bufferLength2, pt[1] + np.cos(angle)*bufferLength2)
                    for angle in np.linspace(0, 2*np.pi, polygonSides, endpoint = False) ]

pts3 = [ QgsPointXY(pt[0] + np.sin(angle)*bufferLength3, pt[1] + np.cos(angle)*bufferLength3)
                    for angle in np.linspace(0, 2*np.pi, polygonSides, endpoint = False) ]

pts4 = [ QgsPointXY(pt[0] + np.sin(angle)*bufferLength4, pt[1] + np.cos(angle)*bufferLength4)
                    for angle in np.linspace(0, 2*np.pi, polygonSides, endpoint = False) ]

n = len(pts1)

geom_feats = []

for i in range(n-1):
    geom_feats.append(QgsGeometry.fromPolygonXY([[pts1[i], pts1[i+1], pt]]).asWkt())
    
geom_feats.append(QgsGeometry.fromPolygonXY([[pts1[n-1], pts1[0], pt]]).asWkt())

for i in range(n-1):
    geom_feats.append(QgsGeometry.fromPolygonXY([[pts2[i], pts2[i+1], pts1[i+1], pts1[i]]]).asWkt())

geom_feats.append(QgsGeometry.fromPolygonXY([[pts2[n-1], pts2[0], pts1[0], pts1[n-1]]]).asWkt())

for i in range(n-1):
    geom_feats.append(QgsGeometry.fromPolygonXY([[pts3[i], pts3[i+1], pts2[i+1], pts2[i]]]).asWkt())

geom_feats.append(QgsGeometry.fromPolygonXY([[pts3[n-1], pts3[0], pts2[0], pts2[n-1]]]).asWkt())

for i in range(n-1):
    geom_feats.append(QgsGeometry.fromPolygonXY([[pts4[i], pts4[i+1], pts3[i+1], pts3[i]]]).asWkt())

geom_feats.append(QgsGeometry.fromPolygonXY([[pts4[n-1], pts4[0], pts3[0], pts3[n-1]]]).asWkt())

epsg = 32612
 
uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"
 
mem_layer = QgsVectorLayer(uri,
                           'concentric_buffer',
                           'memory')
 
prov = mem_layer.dataProvider()

feats = [ QgsFeature() for i in range(len(geom_feats)) ]

for i, feat in enumerate(feats):
    feat.setAttributes([i])
    feat.setGeometry(QgsGeometry.fromWkt(geom_feats[i]))

prov.addFeatures(feats)

QgsProject.instance().addMapLayer(mem_layer)

I ran above code for an arbitrary point with length buffer of 1000, 2000, 3000 and 4000 meters (EPSG: 32612 projection). The result can be observed in following image where I selected the 10 last features. You can observe that they are sequentially adjacent (I have complete control over ids). On the other hand, missed information it can be easily recovered because you can apply geometry functions (area, perimeter, etc) in each feature by using field calculator.

In your case, you can not keep the original attribute values with polygonize processing toolbox because each polygon feature was produced combining four LineStrings with four different ids. Polygonize tool can't handle this. If you want to control initial information you need a more elaborate script with PyQGIS but, with LineStrings, it is more difficult than with points (as in my script). However, these information can be obtained by using field calculator in final multipolygon.

enter image description here

xunilk
  • 30.2k
  • 4
  • 43
  • 82