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

Anita Graser anitagraser at gmx.at
Tue Mar 25 01:35:23 PDT 2008


Hi Marco,

Thank you, you saved my day.
... Those Renderers are really confusing. 



-------- Original-Nachricht --------
> Datum: Sat, 22 Mar 2008 06:58:46 +0100
> Von: "Hugentobler  Marco" <marco.hugentobler at karto.baug.ethz.ch>
> An: "Anita Graser" <anitagraser at gmx.at>, qgis-user at lists.osgeo.org
> Betreff: AW: [Qgis-user] writing a new renderer in python

> 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

-- 
Ist Ihr Browser Vista-kompatibel? Jetzt die neuesten 
Browser-Versionen downloaden: http://www.gmx.net/de/go/browser



More information about the Qgis-user mailing list