2

I'd like to ask on how can I categorize by attribute using my shapefile via python / custom plugin.

I have a Municipality and field name of "Land_Classification" with values "Residential, Commercial and Industrial". I would like to create a plugin that if i click it the layer will automatically categorize the shapefile by Land Classification and will be have colors by Residential, Commercial and Industrial.

1

1 Answer 1

3

Personally, I would avoid creating a function in your plugin which allows the user to click a layer and apply a certain style (unless you add some sort of checkbox to enable/disable this function).

What I would do is:

  1. Create a combo box and populate this with the names of the loaded layers
  2. Create a function which defines the parameters of the categorised style
  3. Create a push button which applies the above function to the selected layer in the combo box

So you could use something like the following in your main.py file. Add the imports at the top of the script:

from qgis.core import QgsMapLayerRegistry, QgsSymbolV2, QgsRendererCategoryV2, QgsCategorizedSymbolRendererV2
from PyQt4.QtGui import QColor

Then in the main run() function, you can use:

def run(self):
    # Define a list for layer names
    layer_list = []
    # Get all layer names loaded in QGIS and store them in the list   
    for layer in QgsMapLayerRegistry.instance().mapLayers().values():
        layerName = layer.name()
        layer_list.append(layerName)
    # Clear layer combo box to make sure if plugin is loaded again, the list is not duplicated
    self.dlg.comboBox_layer.clear()
    # Add layers from list to combobox
    self.dlg.comboBox_layer.addItems(layer_list)

    def apply_style():
        # Get currently selected layer in combo box
        current_layer = self.dlg.comboBox_layer.currentText()
        layer = QgsMapLayerRegistry.instance().mapLayersByName(str(current_layer))[0]

        # Define style parameters: value, colour, legend
        land_class = {
        'Residential': ('#f00', 'Residential'),
        'Commercial': ('#0f0', 'Commercial'),
        'Industrial': ('#fff', 'Industrial'),
        }

        # Define a list for categories
        categories = []
        # Define symbology depending on layer type, set the relevant style parameters
        for classes, (color, label) in land_class.items():
            symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
            symbol.setColor(QColor(color))
            category = QgsRendererCategoryV2(classes, symbol, label)
            categories.append(category)

        # Column/field name to be used to read values from
        column = 'Land_Class'
        # Apply the style rendering
        renderer = QgsCategorizedSymbolRendererV2(column, categories)
        layer.setRendererV2(renderer)
        # Refresh the layer
        layer.triggerRepaint()

    # Set up push button to connect to above function
    run_button = self.dlg.style_button
    run_button.clicked.connect(apply_style)
27
  • 1
    Wow! Thanks sir Joseph. Sorry for my late reply I was out of town for projects. I will try what you suggested and will give you feedback. Commented Oct 13, 2016 at 10:31
  • @ConradoDomingo - Most welcome! I implemented something very similar recently so thought to post it as it might be helpful =)
    – Joseph
    Commented Oct 13, 2016 at 10:35
  • In step 2 im getting a little confused.. how can I create a function thats not in a plugin? Commented Oct 13, 2016 at 11:22
  • @ConradoDomingo - Apologies, probably not very clear. The function is in the code (def apply_style(): which you add to the plugin.
    – Joseph
    Commented Oct 13, 2016 at 11:25
  • yes I added it already. :) but apparently when i click style_button nothing happens.. I think im missing something.. Commented Oct 13, 2016 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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