[Qgis-developer] Re: Raster layer display control from Plugin

JP Glutting jpglutting at gmail.com
Tue Sep 7 08:33:24 EDT 2010


Hi Peter,

Thanks for the response. Sorry if I wasn't clear - there was no real
question at this point, I was just following up on my previous question with
the resolution of the problem, mostly for the users list, and I copied the
message to the developers list as well, just for completeness.

However, the information about when and how Mins and Maxes can be calculated
is interesting. I am not sure that computeMinimumMaximumFromLastExtent is
what I want - I was using code form a plugin that was adjusting the color
scheme for the visible extent, not the whole layer (which is what I want to
do). Where does it store the result? This code:

        QgsMapLayerRegistry.instance().addMapLayer(resultsLayer)
        resultsLayer.triggerRepaint()
        band = resultsLayer.bandNumber(resultsLayer.grayBandName()) #Should
be 1
        minVal = resultsLayer.minimumValue(band)
        maxVal = resultsLayer.maximumValue(band)
        QtGui.QMessageBox.information(self, self.tr("MinMax"), self.tr("Min:
%s Max %s:" %(minVal, maxVal)))
        resultsLayer.computeMinimumMaximumFromLastExtent(band)
        minVal = resultsLayer.minimumValue(band)
        maxVal = resultsLayer.maximumValue(band)
        QtGui.QMessageBox.information(self, self.tr("MinMax"), self.tr("Min:
%s Max %s:" %(minVal, maxVal)))

Produces the same values (0.0 and 255.0) for a raster with values of 0 and 1
before and after calling computeMinimumMaximumFromLastExtent.

Calling this next:

 resultsLayer.setContrastEnhancementAlgorithm(QgsContrastEnhancement.StretchToMinimumMaximum)
        minVal = resultsLayer.minimumValue(band)
        maxVal = resultsLayer.maximumValue(band)
        QtGui.QMessageBox.information(self, self.tr("MinMax"), self.tr("Min:
%s Max %s:" %(minVal, maxVal)))

stretches the grayscale colormap to 0 and 1, with the layer properties (from
the GUI) Min and Max set to 0 and 1, so I assume that it is computing the
real values itself, I can't quite follow the internals. Without this call,
the properties window in the GUI shows 0 and 255 for min and max, even after
calling computeMinimumMaximumFromLastExtent (I can't seem to find a way to
figure out if this call does anything at all - I can't find any values or
results that indicate any effect, although I am probably looking in the
wrong place).

Of course, the MessageBox continues to report 0 and 255, so I not sure where
the correct information is stored.

The tip on using the PseudoColorShader was exactly what I needed, thank you.
I knew it was just something simple I was going at wrong.

Anyway, my plug-in works very nicely now, and I will add it to the QGIS
repository here in a few weeks when I hand in my assignment.

Cheers,
JP

On Tue, Sep 7, 2010 at 3:12 AM, Peter Ersts <ersts at amnh.org> wrote:

>  Howdy JP,
>
> Not quite sure what the question is at this stage. However, here are some
> general comments.
>
> When the raster is first loaded, the min max values for each band are
> provided by GDAL but are estimates. You will not get the exact min max
> values until the band statistics are generated, which depending on the size
> of the image can take be slow. The raster has to be rendered at least once
> for computeMinimumMaximumFromLastExtent() to provide meaningful values.
>
> Re:
>
> "On the other hand,
> resultsLayer.setColorShadingAlgorithm("PseudoColorShader")
> Doesn't seem to do anything at all. Strange."
>
> Pseudo color shading does not just use the minimum and maximum values, it
> requires you to define the number of standard deviations to apply. Also the
> pseudo color shader has to be used with the correct drawing style, i.e.,
> QgsRasterLayer.SingleBandPseudoColor
>
>
> -pete
>
>
> On 09/05/2010 10:52 AM, JP Glutting wrote:
>
> Ok, I figured this out. It was as simple as:
>
>  *
> resultsLayer.setContrastEnhancementAlgorithm(QgsContrastEnhancement.StretchToMinimumMaximum)
> *
>
>  That computes the min and max, and stretches the grayscale (to black and
> white for boolean rasters).
>
>  In the mean time I was futzing around with:
>
>         * band = resultsLayer.bandNumber(resultsLayer.grayBandName()) *
>   *        minVal = resultsLayer.minimumValue(band)*
> *        maxVal = resultsLayer.maximumValue(band)*
>
>  and
>
>        *  resultsLayer.setMinimumValue(band, minVal,
> generateLookupTableFlag)*
> *        resultsLayer.setMaximumValue(band, maxVal,
> generateLookupTableFlag)*
>
>  but it turns out that  *resultsLayer.**setMaximumValue(band) *returns the
> theoretical maximum (255) rather than the real maximum (1), which is not
> what I wanted. You can get the correct value with
>
>  *        maxVal = resultsLayer.bandStatistics(band).maximumValue*
>
>  However, it says that calling bandStatistics is very CPU intensive, since
> it also calculates a lot of other stuff. As it turns out, the
> StretchToMinimumMaximum algorithm seems to calculate the minmax anyway, so
> none of that is needed.
>
>  My big mistake, as I was rushing through this, was to confuse extent and
> values, as I was trying to copy from a tutorial and wasn't paying close
> attention. Once I figured that out, it was easy.
>
>  On the other hand,
>
>  *resultsLayer.setColorShadingAlgorithm("PseudoColorShader")*
>
>  Doesn't seem to do anything at all. Strange.
>
>  Cheers,
> JP
>
>  On Sat, Sep 4, 2010 at 6:35 PM, Benoit de Cabissole <benoit at exigesa.com>wrote:
>
>>   Hi JP,
>>
>> I would suggest asking your question on the Qgis-developer list instead of
>> this one.
>>
>> Below is what I've done to display a custom colormap on a raster. Could it
>> be adapted to your problem?
>>
>>      # Display the raster with the selected colour table:
>>      #
>>      # - tell the layer to use a QgsColorRampShader function
>>      theLayer.setColorShadingAlgorithm( QgsRasterLayer.ColorRampShader )
>>      # - get a pointer to the raster shader function (QgsColorRampShader)
>>      myColorRampShader = theLayer.rasterShader().rasterShaderFunction()
>>      # - set parameters for the QgsColorRampShader function
>>      myColorRampShader.setColorRampType( QgsColorRampShader.DISCRETE )
>>      myColorRampShader.setColorRampItemList( theTBL )
>>      theLayer.setDrawingStyle( QgsRasterLayer.SingleBandPseudoColor )
>>      # - refresh map & legend
>>      if hasattr(theLayer, "setCacheImage"):
>>          theLayer.setCacheImage( None )
>>      theLayer.triggerRepaint()
>>      self.iface.legendInterface().refreshLayerSymbology( theLayer )
>>      # - tell QGIS that it needs to ask user to save changes
>>      self.iface.mapCanvas().setDirty( True )
>>  Cheers,
>> Benoit
>>
>>
>> -----Original Message-----
>> *From:* qgis-user-bounces at lists.osgeo.org [mailto:
>> qgis-user-bounces at lists.osgeo.org]*On Behalf Of *JP Glutting
>> *Sent:* Saturday, 04 September 2010 17:47
>> *To:* Qgis-user at lists.osgeo.org
>> *Subject:* [Qgis-user] Re: Raster layer display control from Plugin
>>
>>  No takers? No hints? I have been looking all over the place, and I am
>> stuck. If it is something absurdly simple, just point me in the right
>> direction.
>>
>>  Any ideas?
>>
>>  Thanks,
>> JP
>>
>> On Fri, Sep 3, 2010 at 7:50 AM, JP Glutting <jpglutting at gmail.com> wrote:
>>
>>> Although here (http://blog.qgis.org/node/94) it seems to indicate that
>>> SingleBandPseudoColor is a constant:
>>>
>>>  mypLayer->setColorRampingType(QgsRasterLayer::BLUE_GREEN_RED);
>>>   mypLayer->setDrawingStyle(QgsRasterLayer::SINGLE_BAND_PSEUDO_COLOR);
>>>   std::deque myLayerSet;
>>>
>>>  which is what I was thinking in the first place, and here (
>>> http://doc.qgis.org/stable/classQgsRasterLayer.html#36796f1a303dac9848ba3dce3e5527dc7b7c9814c053986846b579119d2e5be9 )
>>> DrawingStyle is described as an enumerator, which seems coherent. I am not
>>> sure how to do this from Python.
>>>
>>>  Cheers,
>>> JP
>>>
>>> On Fri, Sep 3, 2010 at 7:43 AM, JP Glutting <jpglutting at gmail.com>wrote:
>>>
>>>> Actually, I am not even sure that first part is the way to do it. I
>>>> tried this:
>>>>
>>>>
>>>>  resultsLayer.setDrawingStyle(QtCore.QString('SingleBandPseudoColor'))
>>>>          resultsLayer.setCacheImage(None)
>>>>         resultsLayer.triggerRepaint()
>>>>
>>>>  (passing the 'SingleBandPseudoColor' style as a string) and it makes
>>>> the raster invisible. It still shows up black in the Layers Panel, but it
>>>> doesn't show in the main window until you change the properties manually
>>>> (and it is Grayscale when you do). It feels like I am pretty close, but I am
>>>> not sure how to interpret this code from the QGIS documentation:
>>>>
>>>>  myRasterLayer->setDrawingStyle<http://classQgsRasterLayer.html#3a923f732bedd87d0b920c5552215434>
>>>> (QgsRasterLayer::SingleBandPseudoColor<http://classQgsRasterLayer.html#36796f1a303dac9848ba3dce3e5527dc7b7c9814c053986846b579119d2e5be9>
>>>> );
>>>>
>>>>  (I never learned more than the basics of C++, and that was a long time
>>>> ago). The source code seems to indicate that the format needs to be passed
>>>> as a string (of course, when the layer is generated):
>>>>
>>>>  00204     QgsRasterLayer <http://classQgsRasterLayer.html>( int dummy,00205                     const QString & baseName = QString(),00206                     const QString & path = QString(),00207                     const QString & providerLib = QString(),00208                     const QStringList & layers = QStringList(),00209                     const QStringList & styles = QStringList(),00210                     const QString & format = QString(),
>>>>
>>>>  00211 const QString & crs = QString() );
>>>>
>>>>  Thanks,
>>>> JP
>>>>
>>>> On Fri, Sep 3, 2010 at 3:04 AM, JP Glutting <jpglutting at gmail.com>wrote:
>>>>
>>>>> Hello,
>>>>>
>>>>>  I am working on a plugin (I mentioned it on the list earlier, but it
>>>>> isn't relevant to the question I have now). I have the results written to a
>>>>> raster file, and I need to display it. I am using this code:
>>>>>
>>>>>          resultsLayer =
>>>>> qgis.core.QgsRasterLayer(self.query.results_file,
>>>>> QtCore.QFileInfo(self.query.results_file).baseName())
>>>>>
>>>>>  qgis.core.QgsMapLayerRegistry.instance().addMapLayer(resultsLayer)
>>>>>
>>>>>
>>>>>  which works fine for opening the file, but I would like to fine-tune
>>>>> the display so the user doesn't have to reset the properties (in my test
>>>>> exaple the values are 0 and 1 and the display is essentially all black). I
>>>>> would like to either display the results in pseudocolor directly, or in
>>>>> grayscale with the scale stretched to the min and max extent of the raster.
>>>>>
>>>>>  I tried the psuedocolor with this code:
>>>>>
>>>>>
>>>>>  resultsLayer.setDrawingStyle(qgis.core.QgsRasterLayer.SingleBandPseudoColor)
>>>>>         resultsLayer.setCacheImage(None)
>>>>>         resultsLayer.triggerRepaint()
>>>>>
>>>>>  which doesn't seem to do anything at all, and I am just guessing,
>>>>> really.
>>>>>
>>>>>  I found a nice tutorial about how to calculate the min and max extent
>>>>> of a raster and adjust the display here:
>>>>>
>>>>>  http://linfiniti.com/2010/08/a-simple-qgis-python-tutorial/
>>>>>
>>>>>  and I tried the following code:
>>>>>
>>>>>          band = resultsLayer.bandNumber(resultsLayer.grayBandName())
>>>>>         extentMin = 0.0
>>>>>         extentMax = 0.0
>>>>>         generateLookupTableFlag = False
>>>>>         extentMin, extentMax =
>>>>> resultsLayer.computeMinimumMaximumFromLastExtent(band)
>>>>>         resultsLayer.setMinimumValue(band, extentMin,
>>>>> generateLookupTableFlag)
>>>>>         resultsLayer.setMaximumValue(band, extentMax,
>>>>> generateLookupTableFlag)
>>>>>         resultsLayer.setStandardDeviations(0.0)
>>>>>         resultsLayer.setUserDefinedGrayMinimumMaximum( True )
>>>>>         resultsLayer.setCacheImage(None)
>>>>>         resultsLayer.triggerRepaint()
>>>>>
>>>>>  but that fails with the following error:
>>>>>
>>>>>  Traceback (most recent call last):
>>>>>   File "/Users//.qgis/python/plugins/mcelite/MCELiteDialog.py", line
>>>>> 361, in accept
>>>>>     extentMin, extentMax =
>>>>> resultsLayer.computeMinimumMaximumFromLastExtent(band)
>>>>> TypeError: 'float' object is not iterable
>>>>>
>>>>>
>>>>>  and I don't understand what the float object is, exactly.
>>>>>
>>>>>
>>>>>  Any help or suggestions much appreciated.
>>>>>
>>>>>
>>>>>  Cheers,
>>>>>
>>>>> JP
>>>>>
>>>>
>>>>
>>>
>>
>>  _______________________________________________
>> Qgis-user mailing list
>>
>> Qgis-user at lists.osgeo.org
>>  http://lists.osgeo.org/mailman/listinfo/qgis-user
>>
>>
>
>
> _______________________________________________
> Qgis-developer mailing listQgis-developer at lists.osgeo.orghttp://lists.osgeo.org/mailman/listinfo/qgis-developer
>
>
>
> --
> ====================================
> Peter J. Ersts, Software Developer
> American Museum of Natural History
> Center for Biodiversity and Conservation
> Central Park West at 79th Street
> New York, New York 10024
> Web: http://biodiversityinformatics.amnh.org
> Web: http://cbc.amnh.org
>
> Open Source,
> ...evolving through community cooperation to change the world bit by bit
>
> Quantum GIS Raster Development Team.
>
>
> _______________________________________________
> Qgis-developer mailing list
> Qgis-developer at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/qgis-developer
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/qgis-developer/attachments/20100907/d36b9dae/attachment-0001.html


More information about the Qgis-developer mailing list