I need to color each polygon based on its area and length. I can loop through all polygons, find out their area .geometry().area() and if it is larger than 100 meters squared, than I want it to be green, otherwise red. Is it possible? I found solution for one attribute. (Setting color of feature depending on attributes with PyQGIS?)
Asked
Active
Viewed 2,259 times
2 Answers
4
There is a nice example from QGIS Python Cookbook:
from PyQt4.QtGui import QColor
# load the vector layer:
lyr = QgsVectorLayer("Users/joellawhead/qgis_data/hancock/landuse.shp","Land Use", "ogr")
# create our three land use categories using a Python dictionary with a field value as the key, color name, and label
landuse = {"0":("yellow", "Developed"),"1":("darkcyan", "Water"),"2":("green","Land")}
# build our categorized renderer items
categories = []
for terrain, (color, label) in landuse.items():
sym = QgsSymbolV2.defaultSymbol(lyr.geometryType())
sym.setColor(QColor(color))
category = QgsRendererCategoryV2(terrain, sym, label)
categories.append(category)
# name the field containing the land use value:
field = "DN"
# build the renderer:
renderer = QgsCategorizedSymbolRendererV2(field, categories)
# add the renderer to the layer:
lyr.setRendererV2(renderer)
# add the categorized layer to the map:
QgsMapLayerRegistry.instance().addMapLayer(lyr)
And there you have another example:
# define some rules: label, expression, color name, (min scale, max scale)
road_rules = (
('Major road', '"type" LIKE \'major\'', 'orange', None),
('Minor road', '"type" LIKE \'minor\'', 'black', (0.0, 2500.0,)),
('Residential road', '"type" LIKE \'residential\'', 'grey', (100.0, 1000.0,)),
)
# create a new rule-based renderer
symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
renderer = QgsRuleBasedRendererV2(symbol)
# get the "root" rule
root_rule = renderer.rootRule()
for label, expression, color_name, scale in road_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))
# set the scale limits if they have been specified
if scale is not None:
rule.setScaleMinDenom(scale[0])
rule.setScaleMaxDenom(scale[1])
# 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)
And don't loop through polygons, just create a column "area" and calculate it.
dmh126
- 6,732
- 2
- 21
- 36
1
So I solved it. I post my solution, if somebody will have similar problem. I add new attribute to my layer, I called it "COLOR".
res = provider.addAttributes([QgsField(COLOR,QVariant.String)])
then I run this:
index = layer.fieldNameIndex('COLOR')
layer.startEditing()
for feature in layer.getFeatures():
COLOR = 'BW'
if feature.geometry().area() < 10000:
if feature.geometry().length() < 50:
COLOR = 'BR'
else:
COLOR = 'LW'
elif feature.geometry().length() < 50:
COLOR = 'AW'
layer.changeAttributeValue(feature.id(),index,str(COLOR))
layer.commitChanges()
So I set that value to one of (BW,BR,LW,AW). Of course I could put .area() there and color it by it's size. My dictionary looks like this:
correct = {
'BR':('green','Both right'),
'AW':('yellow','Area wrong'),
'LW':('orange','Length wrong'),
'BW':('red','Both wrong')
}
Hope this helps somebody!
Aerov
- 333
- 1
- 2
- 9
-
1Your question is not clear ... and i don't see how this "answer" solve your problem ... your code is not matching your question ... + How do u colour polygons ? – Snaileater Sep 04 '15 at 07:21
-
geometry().area()you have to create two different renderers, and one layer can't have more than one at the same time. – dmh126 Sep 01 '15 at 08:13