I'm hassling around with QGIS renderer definitions in python with QGIS 2.8 at debian wheezy. At least I want simply build step by step a categorized renderer to fill a polygon. The script crashes, when I try to access the categorized symbol renderer via print catRender.dump()
in function makeLevelFill( level, title, width, fcolor, bcolor)
for example. Whats wrong with this code?
#!/usr/bin/python
# -*- coding: utf-8 -*-
# -----------------------------------------------------
# Scripting maps as a stand alone application
# investigation study 2015 November/ 2016 July
# -----------------------------------------------------
import sys
from qgis.core import *
from qgis.gui import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtXml import *
# ---------------------------------------------------
# Start Application
# ---------------------------------------------------
QgsApplication.setPrefixPath('/usr', True)
QgsApplication.initQgis()
application = QgsApplication([], True)
# ---------------------------------------------------
# Create a sample memory layer
# ---------------------------------------------------
def createLayer():
layer = QgsVectorLayer("Point&crs=4326&ID=int&LEVEL=string(8)", "bathy", "memory")
f1 = QgsFeature(); f2 = QgsFeature(); f3 = QgsFeature()
f1.setGeometry = QgsGeometry.fromWkt("POLYGON((-1 1, 1 1, 1 -1, -1 1))")
f1.setAttributes([0,'Land'])
f2.setGeometry = QgsGeometry.fromWkt("POLYGON((-2 0, 0 0, 0 -2, -2 0))")
f2.setAttributes([1,'10-20'])
f2.setGeometry = QgsGeometry.fromWkt("POLYGON(( 0 2, 2 2, 2 0, 0 2))")
f2.setAttributes([2,'20-30'])
layer.addFeatures([f1, f2, f3]);
layer.updateExtents()
return layer
# ---------------------------------------------------
# Create a fill symbol via a layer
# ---------------------------------------------------
def makeFillSymbol(width, fcolor, bcolor):
if bcolor == -1:
bcolor = fcolor
layer = QgsSimpleFillSymbolLayerV2()
layer.setFillColor(fcolor)
layer.setColor(bcolor)
layer.setBorderWidth(width)
symbol = QgsFillSymbolV2([layer])
return symbol
# ---------------------------------------------------
# Setup categorization features
# ---------------------------------------------------
def makeLevelFill( level, title, width, fcolor, bcolor):
symbol = makeFillSymbol(width, fcolor, bcolor)
print level, ' ', symbol, ' ', title
catRender = QgsRendererCategoryV2( level, symbol, title)
print "************ CRASH HERE *****************"
print catRender.dump()
return catRender
# ---------------------------------------------------
# Build the categorization layer
# ---------------------------------------------------
def makeRenderer(field):
levelList = []
levelList.append( makeLevelFill( 'Land', 'Land', 0.2 ,QColor('#ffee94'),QColor('#ffee94')))
levelList.append( makeLevelFill( '0-10', ' 0 - 10 m', 0.2 ,QColor('#f8fcff'),-1))
levelList.append( makeLevelFill( '10-20', '10 - 20 m', 0.2 ,QColor('#d8ecff'),-1))
levelList.append( makeLevelFill( '20-30', '20 - 30 m', 0.2 ,QColor('#c8deff'),-1))
levelList.append( makeLevelFill( '30-40', '30 - 40 m', 0.2 ,QColor('#b8ceff'),-1))
levelList.append( makeLevelFill( '40-50', '40 - 50 m', 0.2 ,QColor('#a8beff'),-1))
levelList.append( makeLevelFill( '50-60', ' > 50 m', 0.2 ,QColor('#98aeff'),-1))
renderer = QgsCategorizedSymbolRendererV2( field, levelList )
return renderer
# ---------------------------------------------------
# Put the stuff in the map
# ---------------------------------------------------
layer = createLayer()
renderer = makeRenderer('LEVEL')
layer.setRendererV2(renderer)
QgsMapLayerRegistry.instance().addMapLayer(layer)
# ---------------------------------------------------
# EOF
# ---------------------------------------------------
After reading the C++ sources codes and fiddeling around with some source code tests, I find the source of the error and a workaround. But it is not a explaination for the crash. The workaround addresses the constructors QgsFillSymbolV2([layer])
vs. QgsFillSymbolV2()
. The documentation declares both as valid. But the first one crashes the app, if you try to access the aftermath constructed renderer catRender = QgsRendererCategoryV2( level, makeFillSymbol(...), title)
.
def makeFillSymbol(width, fcolor, bcolor, bstyle = Qt.SolidPattern):
if bcolor == -1:
bcolor = fcolor
symbol = QgsFillSymbolV2()
layer = symbol.symbolLayer(0)
layer.setColor(fcolor)
layer.setFillColor(fcolor)
layer.setBorderColor(bcolor)
layer.setBorderWidth(width)
layer.setBrushStyle(bstyle)
return symbol
I guess it is a real bug.