TransWikia.com

Applying categorized symbol to each feature using PyQGIS

Geographic Information Systems Asked by Keyur Parmar on May 8, 2021

I want to apply unique symbol to each feature. I have used following code for doing that

from qgis.core import *
from PyQt4.QtGui import *
# supply path to where is your qgis installed
QgsApplication.setPrefixPath("/path/to/qgis/installation", True)
# load providers
QgsApplication.initQgis()

# Get the active layer (must be a vector layer)
layer = qgis.utils.iface.activeLayer();
iter = layer.getFeatures();
for feature in iter:
    geom = feature.geometry()
    print "Feature ID %d: " % feature.id()
    qgis.utils.iface.mapCanvas().setSelectionColor( QColor("yellow") );
    layer.setSelectedFeatures([feature.id()])
    qgis.utils.iface.mapCanvas().zoomToSelected( layer )
    qgis.utils.iface.mapCanvas().refresh()
    selected_features = layer.selectedFeatures()
    for i in selected_features:
       attr =i.attributes()
    chaltano= str(attr[layer.fieldNameIndex('test')])
    renderer = QgsCategorizedSymbolRendererV2("test")
    layer.setRendererV2(renderer)
    symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
    symbol.setColor(QColor("red"))
    cat = QgsRendererCategoryV2(feature.id(), symbol,str(feature.id()))
    renderer.addCategory(cat)

Symbol is applying to only last feature.
Here, "test" is attribute.

2 Answers

To draw a layer with a categorized renderer you first should create appropriate categories. A category needs value, symbol, and label. If you know the values at design time you may define these 3 parameters for each category. For an example see QGIS Python Programming Cookbook.

After defining categories you create a QgsCategorizedSymbolRendererV2() with these categories, and assign this renderer to the layer.

My code below creates a category for each unique value in a given field, with a random color. I override the default symbol to allow for some flexibility in styling.

from random import randrange

# Get the active layer (must be a vector layer)
layer = qgis.utils.iface.activeLayer()

# get unique values 
fni = layer.fieldNameIndex('test')
unique_values = layer.dataProvider().uniqueValues(fni)

# define categories
categories = []
for unique_value in unique_values:
    # initialize the default symbol for this geometry type
    symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())

    # configure a symbol layer
    layer_style = {}
    layer_style['color'] = '%d, %d, %d' % (randrange(0,256), randrange(0,256), randrange(0,256))
    layer_style['outline'] = '#000000'
    symbol_layer = QgsSimpleFillSymbolLayerV2.create(layer_style)

    # replace default symbol layer with the configured one
    if symbol_layer is not None:
        symbol.changeSymbolLayer(0, symbol_layer)

    # create renderer object
    category = QgsRendererCategoryV2(unique_value, symbol, str(unique_value))
    # entry for the list of category items
    categories.append(category)

# create renderer object
renderer = QgsCategorizedSymbolRendererV2('test', categories)

# assign the created renderer to the layer
if renderer is not None:
    layer.setRendererV2(renderer)

layer.triggerRepaint()

Correct answer by Detlev on May 8, 2021

For those who'd like to try the code above for the PyQGIS3 version, here is my adaptation (it works for the 'active layer' if run from the console ...).

# provide file name index and field's unique values
from random import randrange

layer = iface.activeLayer()
fni = layer.fields().indexFromName('nom')
unique_values = layer.uniqueValues(fni)

# fill categories
categories = []
for unique_value in unique_values:
    # initialize the default symbol for this geometry type
    symbol = QgsSymbol.defaultSymbol(layer.geometryType())

    # configure a symbol layer
    layer_style = {}
    layer_style['color'] = '%d, %d, %d' % (randrange(0, 256), randrange(0, 256), randrange(0, 256))
    layer_style['outline'] = '#000000'
    symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style)

    # replace default symbol layer with the configured one
    if symbol_layer is not None:
        symbol.changeSymbolLayer(0, symbol_layer)

    # create renderer object
    category = QgsRendererCategory(unique_value, symbol, str(unique_value))
    # entry for the list of category items
    categories.append(category)

# create renderer object
renderer = QgsCategorizedSymbolRenderer('nom', categories)

# assign the created renderer to the layer
if renderer is not None:
    layer.setRenderer(renderer)

layer.triggerRepaint()

Answered by A. Jean on May 8, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP