2

I have a GeoJSON layer consisting of some LineStrings. Each feature has a color property:

{
    "type": "featureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": { "name": "1", "color": "#ffcc90" },
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    ...
                ]
            }
        },

        ...
        
    ]
}

I'd like to set each feature color according to the color value by the color attribute in properties.

I'm able to color the whole layer with a color of my choice, but don't know how to color individual features.

This is what I have done so far:

from qgis.core import QgsProject

# get list of layer names
layerNames = []
root = QgsProject.instance().layerTreeRoot()
for ch in root.children():
    layerNames.append(ch.name())

# populate layers to a dictionary
layers = {}
for lName in layerNames:
    mapLayer = QgsProject.instance().mapLayersByName(lName)
    if len(mapLayer) == 1:
        layers[lName] = mapLayer[0]

# loop through layers
for layerName in layers:
    layer = layers[layerName]
    
    for feature in layer.getFeatures():
        print(feature['color'])
        # here I want to set the color

1 Answer 1

3

You can can set a data-defined-property for your line stroke color without iterating over every feature. I tested this on a temporary scratch layer. It should work fine for you. Select your layer as the active layer in the Table of Contents panel and run the code below in the Python console:

lyr = iface.activeLayer()
# Retrieve the symbol from renderer
line_symbol = lyr.renderer().symbols(QgsRenderContext())[0]
# Retrieve first symbol layer
symbol = line_symbol.symbolLayer(0)
# Create a QgsProperty object
color_prop = QgsProperty()
# Set the 'color' field
color_prop.setField('color')
# Set data-defined-property for the stroke color property of the symbol layer
symbol.setDataDefinedProperty(QgsSymbolLayer.PropertyStrokeColor, color_prop)

lyr.triggerRepaint()

If you want to iterate over multiple layers, you can use this script. This will set line stroke color from "color" field for all GeoJSON line string layers in the current project:

def set_data_defined_color(layer):
    line_symbol = layer.renderer().symbols(QgsRenderContext())[0]
    symbol = line_symbol.symbolLayer(0)
    color_prop = QgsProperty()
    color_prop.setField('color')
    symbol.setDataDefinedProperty(QgsSymbolLayer.PropertyStrokeColor, color_prop)
    layer.triggerRepaint()

for lyr in QgsProject.instance().mapLayers().values():
    if isinstance(lyr.dataProvider(), QgsVectorDataProvider):
        if lyr.dataProvider().storageType() == 'GeoJSON':
            if lyr.wkbType() == QgsWkbTypes.LineString:
                set_data_defined_color(lyr)
2
  • I have multiple layers in my project so I would iterate over the layers, but your code does exactly what I need. Thank you!
    – Dusan
    Commented Jul 7, 2022 at 15:23
  • @Dusan, OK- I updated my answer to show you how to iterate over the layers in your project and execute the code on GeoJSON line string layers.
    – Ben W
    Commented Jul 9, 2022 at 4:47

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.