[Qgis-developer] Custom raster drawing

Barry Rowlingson b.rowlingson at lancaster.ac.uk
Tue Jun 12 07:52:16 EDT 2007

I want to display some rasters with a very specific colour scheme:

  values from 0 to 0.9: gray (or maybe green. Something neutral)
  from 0.90 to 0.95 : gray to yellow
  from 0.95 to 0.99 : yellow to orange
  from 0.99 to 1.00 : orange to red

  its a sort of 'alert' system, the values are probabilities.

The current raster colouring system won't do it, so I've looked at how I 
can extend it to do so. I've tried a couple of things:

  I wrote a new Python class that extends QgsRasterLayer, and wrote an 
overridden 'draw' method.

  QgsRasterLayer has two draw methods - one with five arguments 
(although in the docs this is called the '4 argument' method) and one 
with three. The five-arg method does some calculation and then calls the 
three-arg method. The drawThumbnail method also calls the three-arg 
method directly. The three-arg method is then a big switch statement on 
the drawing style.

  What I wanted to do was to override the 3-arg method with my new 
drawing code - it just has to paint on a QImage and return. But my 
Python class method got called with 5-args. When I just called the 
parent 5-arg method from my Python method it never called it again with 
3-args. You can only have one method per name in a Python class, so 
maybe there's some trick with SIP to get this to work. I couldn't. The 
simple solution here would be to rename the 3-arg draw method in the C++ 
code, then I could override that and have it called. Let's call this 
solution #1.

  Solution #2 is to have a new drawing style, lets call it 
CUSTOM_DRAWING_STYLE - then the big switch would have another case which 
would then call drawCustomStyle - which would have a null definition for 
a QgsRasterLayer by default, but which could be overridden by other 
classes. I'd override one of the current drawing routines, probably 
drawSingleBandPseudoColor, but they are private and so can't be accessed 
from Python wrappers.

  Solution #3 is to rewrite the raster drawing code to use renderers. I 
think this is outside my timeframe though - I'd like to get this done in 
a matter of weeks.

  On top of all this there are still problems since to draw a raster on 
screen I think you need access to adfGeoTransform, which is declared 
private and there's no accessor method.

  I know I've probably gone on about raster drawing before, but this is 
the last thing on my Todo list for my project. I'm willing to spend time 
on Qgis for this. Solutions #1 and #2 are pretty quick hacks that 
shouldn't take long, #3 would require working with the rest of the team 
to get it right. The problem with the private adfGeoTransform (and 
possible other private members needed from Python) could be solved with 
writing some accessor methods and associated SIP code.



More information about the Qgis-developer mailing list