3

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.

  • What is the error message? – artwork21 Jul 2 '16 at 12:48
  • Memory access error or german Speicherzugriffsfehler... – huckfinn Jul 2 '16 at 15:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.