5

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?

  • i'm sorry, I had not explain correctly my doubt. I want to read an polygon shapefile, and store the centroid as point and those attribute table. Some polygons can had 3 columns or more. Type int, float, text. I want to save those attributes to know informations about this polygons, but in point shapefile. – Pedro Igor Oliveira Carvalho Oct 4 '17 at 2:13
6

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
5

It is not completely clear which attributes you want, however I will show you some ideas.

Firstly, use:

name = feature["CD_GEOCODI"] # select the attribute

instead of:

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

for getting the value from the "CD_GEOCODI" field (it will return a list which only stores the value for that field)

Then, use:

attrs = feature.attributes()

for getting all the attributes for the current feature (it will return a list that stores the values from all the fields).

Finally, use:

feat.setAttributes(attrs)

for saving the attributes you saved in the previous steps.

Please note that the attributes will be correctly stored only if you preliminarily create all the required fields and add them to layer2.


EDIT Try to use this code:

# Insert the coordinates in the layer2 shapefile

for x,y in pts:
    feat = QgsFeature()
    point = QgsPoint(x,y)
    feat.setGeometry(QgsGeometry.fromPoint(point))
    feat.setAttributes(attrs)
    prov.addFeatures([feat])

instead of what you have provided.

  • Thanks for your response. I want to save all the attributes, indeed. How to "copy" theese fields and add to layer2? – Pedro Igor Oliveira Carvalho Oct 2 '17 at 21:37
  • @PedroIgorOliveiraCarvalho please, see the edit in my answer. I think you should have all the elements for solving the issue. I repeat that you need to add a proper number of fields to layer2 for seeing the right result. – mgri Oct 2 '17 at 21:56

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.