AW: [Qgis-user] writing a new renderer in python

Hugentobler Marco marco.hugentobler at karto.baug.ethz.ch
Fri Mar 21 22:58:46 PDT 2008


Hi Anita,

To make QGIS fetch the attributes, you need to implement QgsRenderer::classificationAttributes()
in your renderer subclass. It returns a QgsAttributeList (that is a typedef for QList<int>) and tells QGIS, what attributes the renderer class needs. Only the specified attributes are fetched from the datasource (for performance reasons).
Also, there is the method QgsRenderer::needsAttributes() that should return true (is only used in the legend of QGIS, the method seems highly redundant with classificationAttributes() and is a candidate for removal).

Hope it helps,
Marco


-----Ursprüngliche Nachricht-----
Von: qgis-user-bounces at lists.osgeo.org im Auftrag von Anita Graser
Gesendet: Fr 21.03.2008 13:12
An: qgis-user at lists.osgeo.org
Betreff: [Qgis-user] writing a new renderer in python
 
For my project I want to visualise speed on streets with a continuous color renderer. I'd like it to show slow in red then change to yellow then to green. Unfortunately QgsContinuousColorRenderer only allows to use two colors. So I'm trying to write a new renderer inheriting QgsContinuousColor Renderer.

Is it possible to write a new renderer in python?

I found some problems which I don't understand:

1.
I tried to rewirte the renderFeature function:
-------------------------------------------------------------
def renderFeature(self, painter, feature, image, scalefactor, selected, widthScale=1):
     attrs = feature.attributeMap()
     fvalue = float(attrs[self.classificationField])
-------------------------------------------------------------
However, attributeMap() seems to always return a dictionary of length 1 allthough there should be 12 attributes. So I can't get a value for fvalue.

2.
If I catch the exception caused by problem 1 and set a default value the function will continue to it's end. But then, I get a typeError:
TypeError: invalid result type from My3ColorRenderer.renderFeature()
I'm confused because I thought that this function returns void ...

Anyone got an idea what I'm doing wrong?

Thank you!

My Code:

-----------------------------------------------------------------

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *

class My3ColorRenderer(QgsContinuousColorRenderer):
    def __init__(self,vectorType):
        self.vectorType=vectorType
        QgsContinuousColorRenderer.__init__(self,vectorType)
    
    def setMiddleSymbol(self,symbol):
        self.mMiddleSymbol=symbol
    def middleSymbol(self):
        return self.mMiddleSymbol
        
    def name(self):
        return "FleetVis3ColorRenderer"
    
    def symbols(self):
        list=[]
        list.append(self.mMinimumSymbol)
        list.append(self.mMiddleSymbol)
        list.append(self.mMaximumSymbol)
        return list
    
    def setClassificationField(self,id):
        self.classificationField=id
    
    def renderFeature(self, painter, feature, image, scalefactor, selected, widthScale=1):
        #first find out the value for the classification attribute
        # ??? i dont know why it doesnt work ...
        attrs = feature.attributeMap()
        try:
            fvalue = float(attrs[self.classificationField])
        except:
            fvalue=50.0

        minvalue = float(self.minimumSymbol().lowerValue())
        maxvalue = float(self.maximumSymbol().lowerValue())
        middlevalue = minvalue + maxvalue
        middlevalue=middlevalue/2
        
        mincolor=QColor()
        maxcolor=QColor()
        
        if self.vectorType == QGis.Line or self.vectorType == QGis.Point:
            mincolor = self.minimumSymbol().pen().color()
            middlecolor=self.middleSymbol().pen().color()
            maxcolor = self.maximumSymbol().pen().color()
        else:#if polygon
            painter.setPen(self.minimumSymbol().pen())
            mincolor = self.minimumSymbol().fillColor()
            middlecolor=self.middleSymbol().fillColor()
            maxcolor = self.maximumSymbol().fillColor()

        if (maxvalue - minvalue)!=0:
            if(fvalue<middlevalue):
                red = int (middlecolor.red() * (fvalue - minvalue) / (middlevalue - minvalue) + mincolor.red() * (middlevalue - fvalue) / (middlevalue - minvalue))
                green = int (middlecolor.green() * (fvalue - minvalue) / (middlevalue - minvalue) + mincolor.green() * (middlevalue - fvalue) / (middlevalue - minvalue))
                blue =  int (middlecolor.blue() * (fvalue - minvalue) / (middlevalue - minvalue) + mincolor.blue() * (middlevalue - fvalue) / (middlevalue - minvalue))
            elif(fvalue==middlevalue):
                red=int(middlecolor.red())
                green=int(middlecolor.green())
                blue=int(middlecolor.blue())
            else:
                red = int (maxcolor.red() * (fvalue - middlevalue) / (maxvalue - middlevalue) + middlecolor.red() * (maxvalue - fvalue) / (maxvalue - middlevalue))
                green = int (maxcolor.green() * (fvalue - middlevalue) / (maxvalue - middlevalue) + middlecolor.green() * (maxvalue - fvalue) / (maxvalue - middlevalue))
                blue =  int (maxcolor.blue() * (fvalue - middlevalue) / (maxvalue - middlevalue) + middlecolor.blue() * (maxvalue - fvalue) / (maxvalue - middlevalue))
        else:
            red = int (mincolor.red())
            green = int (mincolor.green())
            blue = int (mincolor.blue())

        if self.vectorType == QGis.Point:
            pen = self.minimumSymbol().pen()
            pen.setColor ( QColor(red, green, blue) )
            pen.setWidthF ( widthScale * pen.width() )
            
            brush = self.minimumSymbol().brush()
            
            brush.setColor ( QColor(red, green, blue) )

            brush.setStyle ( Qt.SolidPattern )

            img = QgsMarkerCatalogue.instance().imageMarker ( self.minimumSymbol().pointSymbolName(), self.minimumSymbol().pointSize(),pen, brush)

            if scalefactor:
                 scalefactor = 1

        elif self.vectorType == QGis.Line:
            painter.setPen( QPen(QColor(red, green, blue),int(widthScale*self.minimumSymbol().pen().width()) ))
        
        else:
            painter.setBrush(QColor(red, green, blue))
            painter.setPen(Qt.NoPen)
            
-- 
Ist Ihr Browser Vista-kompatibel? Jetzt die neuesten 
Browser-Versionen downloaden: http://www.gmx.net/de/go/browser
_______________________________________________
Qgis-user mailing list
Qgis-user at lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/qgis-user




More information about the Qgis-user mailing list