JP,

the computeMinimumMaximumFromLastExtent() methods _do not set_ minimum and maximum values, they return them for you to use how you want. Using your variables names from below, you would want to use:

resultsLayer.computeMinimumMaximumFromLastExtent( band, minVal, maxVal )

After this call, your local variables minVal and maxVal would have values of 0 and 1 respectively. There is another convenience function called setMinimumMaximumUsingLastExtent(). This will _set_ the internal minimum maximum values of the band(s) currently being displayed.

However, you have not indicated which version of QGIS you are using, so both of these functions that I have mentioned may no be available to you. You would need to be compiling QGIS from the svn trunk (v1.6) to have access to these two functions.

-pete

On 09/07/2010 08:33 AM, JP Glutting wrote:
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 <http://self.tr>("MinMax"), self.tr <http://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 <http://self.tr>("MinMax"), self.tr <http://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 <http://self.tr>("MinMax"), self.tr <http://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 <[email protected] <mailto:[email protected]>> 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
    <[email protected] <mailto:[email protected]>> 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:* [email protected]
            <mailto:[email protected]>
            [mailto:[email protected]
            <mailto:[email protected]>]*On Behalf Of
            *JP Glutting
            *Sent:* Saturday, 04 September 2010 17:47
            *To:* [email protected]
            <mailto:[email protected]>
            *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
            <[email protected] <mailto:[email protected]>> 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
                <[email protected] <mailto:[email protected]>>
                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):

                    00204QgsRasterLayer  <http://classQgsRasterLayer.html>(int  
dummy,
                    00205const  QString&  baseName = QString(),
                    00206const  QString&  path = QString(),
                    00207const  QString&  providerLib = QString(),
                    00208const  QStringList&  layers = QStringList(),
                    00209const  QStringList&  styles = QStringList(),
                    00210const  QString&  format = QString(),

                    00211 const QString & crs = QString() );

                    Thanks,
                    JP

                    On Fri, Sep 3, 2010 at 3:04 AM, JP Glutting
                    <[email protected]
                    <mailto:[email protected]>> 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






--
====================================
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
[email protected]
http://lists.osgeo.org/mailman/listinfo/qgis-developer

Reply via email to