QGIS Python – Create Square Buffers Around Points

bufferqgis

I have x, y coordinates in lat/long and I need to create 5×5 degree square cells around them, with the lat/long coordinates being the centroids.

My first option is to create a buffer around the centroids with 1 segment and a distance of 1/2(5°) * sqrt(2) (must multiply by sqrt(2) bc the tool uses centroid to the corner of the square as the buffer distance, as opposed to centroid to edge), which results in sideways squares around my points, then rotate each feature by 45 degrees. I'd prefer not to do this as the distance isn't as precise and I do not know how to rotate each individual buffer feature quickly.

My second option, which seems much simpler, is to create a buffer around the centroids with the distance I need ((1/2)*5°) and then use something like ArcMap's Feature to Envelope tool.

I see that someone has the same question here and an answer was provided, but I have no idea how to do it programmatically.

Best Answer

As you wondering in your last paragraph, to do that programmatically with PyQGIS it is not very difficult. You can try out next code. However, I used a shapefile and projected coordinates in meters (buffer has 1000 m). You only would need to do a few changes.

layer = iface.activeLayer()

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

epsg = layer.crs().postgisSrid()

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

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

prov = mem_layer.dataProvider()

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

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

After running the above code at the Python Console of QGIS, I got:

enter image description here

It works.

Editing Note:

Next code introduces at the attributes table a column for the x-coordinate, y-coordinate, and ID number for each point.

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,
                           'square_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(1000, -1).boundingBox().asWktPolygon()
    new_feat.setGeometry(QgsGeometry.fromWkt(tmp_feat))
    prov.addFeatures([new_feat])

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

After running the new code at the Python Console of QGIS, result was:

enter image description here

Related Question