Friday, 3 November 2017

polygon - Saving centroid with attribute fields in PyQGIS?


I'm new in PyQGIS and wrote a script to read a polygon and get the centroid:


from qgis.PyQt.QtGui import *
from qgis.PyQt.QtCore import *

# insert the location of the shp
layer = iface.addVectorLayer("/media/path/Setor_Censit_Urb_Cast_2010.shp", "Setor", "ogr")
layer2 = QgsVectorLayer('Point?crs=epsg:4326', 'MyPoint' , 'memory')


pts = []

# save the centroid as vector
prov = layer2.dataProvider()
points = []
for feature in layer.getFeatures():
geometry = feature.geometry()
centroid = geometry.centroid().asPoint()
pts = [centroid]

name = feature.attribute("CD_GEOCODI") # select the attribute

# Insert the coordinates in the layer2 shapefile
for x,y in pts:
feat = QgsFeature()
point = QgsPoint(x,y)
feat.setGeometry(QgsGeometry.fromPoint(point))
points.append(feat)
prov.addFeatures(points)


# update extent of the layer
layer2.updateExtents()

# add the layer to the layers panel
QgsMapLayerRegistry.instance().addMapLayers([layer2])

But I want the attributes too. How can I do it?



Answer



It's not completely clear which datatype the attribute should have. I am assuming string here (but it could be int or double among others as well).


The code below also has been simplified and shortened:




  1. There is no need to convert from the centroid to point to x and y and back. Just use the centroid geometry directly.

  2. Do not use the dataProvider. Just use the methods on the layer.

  3. No need to loop over an array with a single entry in it (The pts array).




source_layer = iface.addVectorLayer("/media/path/Setor_Censit_Urb_Cast_2010.shp", "Setor", "ogr")

# Define additional attributes already on the layer level
centroid_layer = QgsVectorLayer('Point?crs=epsg:4326&field=cd_geocodi:string', 'MyPoint' , 'memory')


centroid_layer.startEditing()
# Loop over all features
for source_feature in source_layer.getFeatures():
geometry = source_feature.geometry()
centroid = geometry.centroid()
name = source_feature.attribute("CD_GEOCODI")
# or use source_feature['CD_GEOCODI']

# Create the new feature with the fields of the memory layer

# And set geometry and attribute before adding it to the target layer
centroid_feature = QgsFeature(source_layer.fields())
centroid_feature.setGeometry(centroid)
centroid_feature['cd_geocodi'] = name
centroid_layer.addFeature(centroid_feature)

centroid_layer.commitChanges()

# Add the layer to the registry
QgsMapLayerRegistry.instance().addMapLayer(centroid_layer)


Further note, do not use * imports. They are a bad habit and will bite you when you want to upgrade your script to QGIS 3.


from qgis.PyQt.QtGui import QSomethingYouUse
from qgis.PyQt.QtCore import QWhateverElseYouReallyNeed

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...