[Qgis-developer] Custom raster drawing

Peter Ersts ersts at amnh.org
Tue Jun 12 12:04:42 EDT 2007

Howdy all,
I too am all for splitting the QgsRasterLayer into modular components as 
it is rather cumbersome in its current state. I think it is clear that 
we are all in agreement that this needs to happen, but there should be a 
clear rational decision as to when/how it will happen. I would rather 
see a major change done with some thought rather than quickly and 
haphazardly to meet one persons needs and deadline **no offense Barry, I 
got involved because I too needed additional functionality in the raster 
class, but your ideas are great and I think a lot of people would be 
interested in them!

Currently we have been working under the idea of first getting what is 
there working then making it is much more of the way it should be. I am 
all for splitting the class now if that is the way everyone is leaning, 
as it may actually make progress move much faster because there will be 
far less duplication of code.

The stretching and transparency would be easily and effectively 
implemented as separate classes. Another thing that also needs to be 
done is to have the raster stats stored to a file so they are not 
calculated every time the layer is reloaded (I will add this to the wiki)

One thing that have come up recently related to the transparency is that 
there is a need for  a way to reference an external raster layer loaded 
on the map canvas from with in QgsRasterLayer and also a way to know 
if/when that layer is deleted/removed. -- This allows for the an band in 
another layer to be used as the input for the transparency. A problem 
arrises when layer Y is selected as the transparency input for layer Z, 
then the user delete/unloads layer Y. In a working version (not 
committed to svn yet - I will probably commit it later this evening) I 
added a signal that is emitted when a raster layer is deleted. Thus when 
Y is deleted, layer Z knows to clear/forget about the current 
transparency layer settings. However, this is not a perfect solution 
because Qt does not guarantee the order in which signals will be 
processed. There have been a couple of suggestions about guarded 
pointers, which may be something to investigate further when the major 
refactoring is considered - but this issue has broader implications that 
reach outside of the raster transparency branch.

Unfortunately, I will not likely be able to participate in a conference 
call/chat this Friday, but pretty much I will be good with most anything 
that is decided!


Tim Sutton wrote:
> Hi Barry
> The long term solution to this is that QgsRaster needs some mjor
> refactoring. There is ongoing work on this in the transparency branch
> but it does not yet adress your needs. My suggestion is that you join
> our effor for getting qgsraster refactored. We have a roadmap for this
> here
> http://wiki.qgis.org/qgiswiki/RasterTransparencyBranch
> which I see you have already had a look at. Other things I would like
> to do is move out all data format specific into its own subclasses and
> make qgsrasterlayer an abstract base class. Also I would like to
> suport custom color ramps and palletes  whose logic is separate to the
> core raster drawing code. This means the pseudo color, rgb etc etc
> code would come out of raster layer. Instead as each pixel is rendered
> the layer value will be looked up from the data source and passed to
> our colour mapping class which would return a qcolor which we then
> draw onto the canvas. This would provide an extremelyfelxible aproach
> and for writing custom colour maps all you need to do is implement a
> subclass of QgsColorMap (in python or c++).
> Another thing I would like to do fairly urgently is get an ossim data
> provider implemented.
> There are many other things I would like to do with raster, so I would
> like to suggest that we hold an online irc or skype meeting for all
> those interested in raster.  The goals of the meeting would be to firm
> up a road map for raster with the aim of getting it merged into the
> release after 0.9, and to divvy up the work to make this happen.
> If you are interested to participate that would be great! I'd also
> hope to see Marco and Pete Ersts there and perhaps one of the ossim
> folks?
> Tentaively Id suggest this friday as a date for the meeting.
> Regards
> Tim
> 2007/6/12, Barry Rowlingson <b.rowlingson at lancaster.ac.uk>:
>> 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.
>> Thanks,
>> Barry
>> _______________________________________________
>> Qgis-developer mailing list
>> Qgis-developer at lists.qgis.org
>> http://lists.qgis.org/cgi-bin/mailman/listinfo/qgis-developer

Peter J. Ersts, Project Specialist
American Museum of Natural History
Center for Biodiversity and Conservation
Central Park West at 79th Street
New York, New York 10024
Tel: (212)-496-3488 or (212)-769-5742
Fax: (212)-313-7295 or (212)-769-5292
Web: http://cbc.amnh.org
Web: http://geospatial.amnh.org

Open Source, Open Mind.
...evolving through community cooperation to change the world bit by bit

More information about the Qgis-developer mailing list