[Qgis-developer] Re: Raster layer display control from Plugin
Peter Ersts
ersts at amnh.org
Tue Sep 7 09:42:13 EDT 2010
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 <ersts at amnh.org
> <mailto: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 <mailto: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>
>> [mailto: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
>> <mailto: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 <mailto: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 <mailto: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):
>>
>> 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
>> <jpglutting at gmail.com
>> <mailto: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
>>
>>
>>
>>
>>
--
====================================
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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/qgis-developer/attachments/20100907/acd4225e/attachment-0001.html
More information about the Qgis-developer
mailing list