Simbología basada en reglas para un vectorial de línea con PyQGIS

En este post se considera la asignación de la simbología de un vectorial de línea mediante PyQGIS. Como las reglas se basan en la presencia de ciertos valores de etiquetas (labels), en un campo determinado, el código producido tiene que explorar primero que ese campo exista y que contenga las etiquetas adecuadas para que se informe al usuario de que se presentarán problemas en caso de discordancia.

Por otra parte, también tiene que producir advertencias en caso de que los vectoriales sean diferentes a polilíneas. Las comprobaciones de que existe capa activa y de que la capa es ráster se dejan al lector. El código propuesto es el siguiente:

# -*- coding: utf-8 -*-

from PyQt4.QtGui import *
from qgis.gui import QgsMessageBar

def symbolLineRule():

    # define some rules: label, expression, color name, width
    my_rules = (
        ('first', '"type" LIKE \'first\'', 'green', 1),
        ('second', '"type" LIKE \'second\'', 'red', 2),
        ('third', '"type" LIKE \'third\'', 'blue', 3),
    )

    layer = iface.activeLayer()

    # create a new rule-based renderer
    symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
    
    if symbol.type() != QgsLineSymbolV2.Line:
        iface.messageBar().pushMessage("", 
                                       u"El vectorial no es del tipo línea", 
                                       QgsMessageBar.WARNING, 5)
        return

    n_rules = len(my_rules)
    n_features = layer.pendingFeatureCount()
    
    idx_type = layer.fieldNameIndex('type')
    
    if idx_type == -1:
        iface.messageBar().pushMessage("", 
                                       u"No existe el campo type", 
                                       QgsMessageBar.WARNING, 5)

        return

    if n_rules != n_features:
        iface.messageBar().pushMessage("", 
                                       u"El número de rasgos no es igual al número de reglas", 
                                       QgsMessageBar.WARNING, 5)
        return

    iter = layer.getFeatures()
    
    attr = []
    
    for item in iter:
        attr.append(item.attributes()[idx_type])

    for i in range(n_rules):
        if attr[i] != my_rules[i][0]:
                iface.messageBar().pushMessage("Advertencia:", 
                                               u"Rasgo \"" + str(attr[i]) + "\" sin regla", 
                                               QgsMessageBar.WARNING, 5)
                return

    
    renderer = QgsRuleBasedRendererV2(symbol)

    # get the "root" rule
    root_rule = renderer.rootRule()

    for label, expression, color_name, width in my_rules:
        # create a clone (i.e. a copy) of the default rule
        rule = root_rule.children()[0].clone()
        # set the label, expression and color
        rule.setLabel(label)
        rule.setFilterExpression(expression)
        rule.symbol().setColor(QColor(color_name))
        rule.symbol().setWidth(width)
        # append the rule to the list of rules
        root_rule.appendChild(rule)

    # delete the default rule
    root_rule.removeChildAt(0)

    # apply the renderer to the layer
    layer.setRendererV2(renderer)

    layer.triggerRepaint()
    
    iface.messageBar().pushMessage("Terminado:", 
                                   u"El symbol ha sido asignado", 
                                   QgsMessageBar.INFO, 5)

Cuando se prueba la función ‘symbolLineRule()’ en la Python Console para el vectorial de la imagen siguiente:

symbol_line1

se obtiene:

symbol_line2

con la información de que el symbol basado en reglas ha sido añadido.

Cuando modifico el campo ‘type’ a ‘type2’ y ejecuto la función se produce la advertencia de la imagen siguiente en la cual no existe el campo que alberga las reglas:

symbol_line3

Cuando el vectorial sólo tiene dos rasgos:

symbol_line4

Cuando existe un rasgo sin regla (por ejemplo, me equivoqué escribiendo “firstt” en la tabla atributiva en lugar de “first”):

symbol_line5

En el caso de que el symbol se trate de aplicar a un vectorial que no sea tipo línea:

symbol_line6

Esta entrada fue publicada en PyQGIS, QGIS, SIG, Software Libre. Guarda el enlace permanente.

Una respuesta a Simbología basada en reglas para un vectorial de línea con PyQGIS

  1. JOSE GUSTAVO RANGEL QUINTERO dijo:

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s