4

Using the code outlined in the question: How to create square buffers around points in QGIS with Python? I created a layer of square buffers from coordinate points, however I was unable to carry over all of the point attributes to the new layer.

We have the following columns in our point attributes:

BigCellID (integer),
BigCellTyp (integer),
x,
y

The following code carried over the x and y columns perfectly:

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)

However to get it to also carry over the other two columns I made the following modification to one line:

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

instead of:

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

This modification did not affect the x and y columns being carried over, and did create new columns; but the column BigCellID was filled with sequentially increasing numbers from 0, while BigCellTyp was filled with 'Null'. These are not the original values.

I would like to know how I can modify this code to ensure the contents of my two columns BigCellID and BigCellTyp are carried over to the new buffer layer?

  • You need to modify the line where is new_feat.setAttributes command (see my answer). – xunilk Nov 15 '16 at 5:23
1

If you did this modification:

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

you need this one:

.
.
.
for i, feat in enumerate(feats):
    .
    .
    .
    new_feat.setAttributes([i, point[0], point[1], BigCellID[i], BigCellTyp[i]])
    .
    .
    .

to fill all fields with values that you are expected. Of course, before the loop, you need to have BigCellID and BigCellTyp defined as a list of values with the same dimension of features number.

Editing Note:

As you said: "We have the following columns in our point attributes:

BigCellID (integer), BigCellTyp (integer)..."

so, next code should work well:

layer = iface.activeLayer()

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

n = len(feats)

BigCellID = [ feats[i].attribute('BigCellID') for i in range(n) ]
BigCellTyp = [ feats[i].attribute('BigCellTyp') for i in range(n) ]

epsg = layer.crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer&field=x:real&field=y:real&field=BigCelID:integer&field=BigCellTyp: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], BigCellID[i], BigCellTyp[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)

I tried it out with my own point layer (where I defined 'BigCellID' and 'BigCellTyp' fields with arbitrary values) and it works fine.

enter image description here

  • OK, thank you! I can see where I went wrong, however being unfamiliar with python I am not sure how to define those those lists, or when to run that line. – Amroco Nov 16 '16 at 2:06
  • Done. Please, see my "Editing Note". – xunilk Nov 16 '16 at 9:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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