~ubuntu-branches/ubuntu/breezy/qgis/breezy

« back to all changes in this revision

Viewing changes to src/qgsrasterlayer.h

  • Committer: Bazaar Package Importer
  • Author(s): Steve Halasz
  • Date: 2004-12-21 09:46:27 UTC
  • Revision ID: james.westby@ubuntu.com-20041221094627-r9lb6mlz2o3yp8gn
Tags: upstream-0.6.0
ImportĀ upstreamĀ versionĀ 0.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                        qgsrasterlayer.h  -  description
 
3
                              -------------------
 
4
        begin                : Fri Jun 28 2002
 
5
        copyright            : (C) 2004 by T.Sutton, Gary E.Sherman, Steve Halasz
 
6
        email                : tim@linfiniti.com
 
7
***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
11
 *   This program is free software; you can redistribute it and/or modify  *
 
12
 *   it under the terms of the GNU General Public License as published by  *
 
13
 *   the Free Software Foundation; either version 2 of the License, or     *
 
14
 *   (at your option) any later version.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
/* $Id: qgsrasterlayer.h,v 1.51 2004/11/15 21:52:57 mhugent Exp $ */
 
18
 
 
19
/** \file qgsrasterlayer.h
 
20
 *  \brief This class provides qgis with the ability to render raster datasets
 
21
 *  onto the mapcanvas..
 
22
 *  
 
23
 *  The qgsrasterlayer class makes use of gdal for data io, and thus supports
 
24
 *  any gdal supported format. The constructor attemtps to infer what type of
 
25
 *  file (RASTER_LAYER_TYPE) is being opened - not in terms of the file format (tif, ascii grid etc.)
 
26
 *  but rather in terms of whether the image is a GRAYSCALE, PALETTED or MULTIBAND,
 
27
 *
 
28
 *  Within the three allowable raster layer types, there are 8 permutations of 
 
29
 *  how a layer can actually be rendered. These are defined in the DRAWING_STYLE enum
 
30
 *  and consist of:
 
31
 *
 
32
 *  SINGLE_BAND_GRAY -> a GRAYSCALE layer drawn as a range of gray colors (0-255)
 
33
 *  SINGLE_BAND_PSEUDO_COLOR -> a GRAYSCALE layer drawn using a pseudocolor algorithm
 
34
 *  PALETTED_SINGLE_BAND_GRAY -> a PALLETED layer drawn in gray scale (using only one of the color components)
 
35
 *  PALETTED_SINGLE_BAND_PSEUDO_COLOR -> a PALLETED layer having only one of its color components rendered as psuedo color
 
36
 *  PALETTED_MULTI_BAND_COLOR -> a PALLETED image where the bands contains 24bit color info and 8 bits is pulled out per color
 
37
 *  MULTI_BAND_SINGLE_BAND_GRAY -> a layer containing 2 or more bands, but using only one band to produce a grayscale image
 
38
 *  MULTI_BAND_SINGLE_BAND_PSEUDO_COLOR -> a layer containing 2 or more bands, but using only one band to produce a pseudocolor image
 
39
 *  MULTI_BAND_COLOR -> a layer containing 2 or more bands, mapped to the three RGBcolors. In the case of a multiband with only two bands, one band will have to be mapped to more than one color
 
40
 *
 
41
 *  Each of the above mentioned drawing styles is implemented in its own draw* function.
 
42
 *  Some of the drawing styles listed above require statistics about the layer such 
 
43
 *  as the min / max / mean / stddev etc. Statics for a band can be gathered using the 
 
44
 *  getRasterBandStats function. Note that statistics gathering is a slow process and 
 
45
 *  evey effort should be made to call this function as few times as possible. For this
 
46
 *  reason, qgsraster has a vector class member to store stats for each band. The 
 
47
 *  constructor initialises this vector on startup, but only populates the band name and
 
48
 *  number fields.
 
49
 *  
 
50
 *  Note that where bands are of gdal 'undefined' type, their values may exceed the 
 
51
 *  renderable range of 0-255. Because of this a linear scaling histogram stretch is
 
52
 *  applied to undefined layers to normalise the data into the 0-255 range.
 
53
 *
 
54
 *  A qgsrasterlayer band can be referred to either by name or by number (base=1). It
 
55
 *  should be noted that band names as stored in datafiles may not be uniqe, and 
 
56
 *  so the rasterlayer class appends the band number in brackets behind each band name.
 
57
 *  
 
58
 *  Sample useage of the QgsRasterLayer class:
 
59
 *
 
60
 *     QString myFileNameQString = "/path/to/file";
 
61
 *     QFileInfo myFileInfo(myFileNameQString);
 
62
 *     QString myBaseNameQString = myFileInfo.baseName();
 
63
 *     QgsRasterLayer *myRasterLayer = new QgsRasterLayer(myFileNameQString, myBaseNameQString);
 
64
 *     myRasterLayer->initContextMenu(this); //prepare the right click pop up menu
 
65
 *
 
66
 *  In order to automate redrawing of a raster layer, you should like it to a map canvas like this :
 
67
 *  
 
68
 *     QObject::connect( myRasterLayer, SIGNAL(repaintRequested()), mapCanvas, SLOT(refresh()) );
 
69
 *
 
70
 *  A raster layer can also export its legend as a pixmap:
 
71
 *
 
72
 *     QPixmap myQPixmap = myRasterLayer->legendPixmap();
 
73
 *
 
74
 * Once a layer has been created you can find out what type of layer it is (GRAY_OR_UNDEFINED, PALETTE or MULTIBAND):
 
75
 *
 
76
 *    if (rasterLayer->getRasterLayerType()==QgsRasterLayer::MULTIBAND)
 
77
 *    {
 
78
 *      //do something
 
79
 *    }
 
80
 *    else if (rasterLayer->getRasterLayerType()==QgsRasterLayer::PALETTE)
 
81
 *    {
 
82
 *      //do something
 
83
 *    }
 
84
 *    else // QgsRasterLayer::GRAY_OR_UNDEFINED
 
85
 *    {
 
86
 *      //do something.
 
87
 *    }
 
88
 *
 
89
 * You can combine layer type detection with the setDrawingStyle method to override the default drawing style assigned
 
90
 * when a layer is loaded.:
 
91
 *
 
92
 *    if (rasterLayer->getRasterLayerType()==QgsRasterLayer::MULTIBAND)
 
93
 *    {
 
94
 *       myRasterLayer->setDrawingStyle(QgsRasterLayer::MULTI_BAND_SINGLE_BAND_PSEUDO_COLOR);
 
95
 *    }
 
96
 *    else if (rasterLayer->getRasterLayerType()==QgsRasterLayer::PALETTE)
 
97
 *    {
 
98
 *      myRasterLayer->setDrawingStyle(QgsRasterLayer::PALETTED_SINGLE_BAND_PSEUDO_COLOR);
 
99
 *    }
 
100
 *    else // QgsRasterLayer::GRAY_OR_UNDEFINED
 
101
 *    {
 
102
 *      myRasterLayer->setDrawingStyle(QgsRasterLayer::SINGLE_BAND_PSEUDO_COLOR);
 
103
 *    }
 
104
 * 
 
105
 *  Raster layers can also have an aribitary level of transparency defined, and have their
 
106
 *  colour palettes inverted using the setTransparency and setInvertHistogramFlag methods. 
 
107
 * 
 
108
 *  Pseudocolour images can have their output adjusted to a given number of standard
 
109
 *  deviations using the setStdDevsToPlot method.
 
110
 * 
 
111
 *  The final area of functionality you may be interested in is band mapping. Band mapping
 
112
 *  allows you to choose arbitary band -> colour mappings and is applicable only to PALETTE
 
113
 *  and MULTIBAND rasters, There are four mappings that can be made : red, green, blue and gray.
 
114
 *  Mappings are non exclusive. That is a given band can be assigned to no, some or all 
 
115
 *  colour mappings. The constructor sets sensible defaults for band mappings but these can be
 
116
 *  overridden at run time using the setRedBandName,setGreenBandName,setBlueBandName and setGrayBandName 
 
117
 *  methods.
 
118
 */
 
119
 
 
120
/*
 
121
 * 
 
122
 * PROGRAMMERS NOTES:
 
123
 * 
 
124
 * 
 
125
 Please observe the following variable naming guidelines when editing this class:
 
126
----------------
 
127
In my opinion, clarity of code is more important than brevity, so variables should be given clear, 
 
128
unambiguous names. Variables names should be written in mixed case, with a lowercase first letter. 
 
129
Each variable name should include a scope resolution indicator and a type indicator, in the form:
 
130
 
 
131
[scope]+[name]+[type]
 
132
 
 
133
Where scope resolution indicators are:
 
134
 
 
135
- global vars and class members : [none]
 
136
- variables passed as parameters to a function/method: the
 
137
- variables declared locally in a method or function: my
 
138
 
 
139
For example:
 
140
 
 
141
class FooClass {
 
142
  int fooInt;  //class var has no prefix
 
143
 
 
144
  public void FooClass::fooMethod (int theBarInt)  //function parameter prefixed by 'the'
 
145
  {
 
146
    fooInt=1;
 
147
    int myLocalInt=0; //function members prefixed by 'my'
 
148
    myLocalInt=fooInt+theBarInt;
 
149
  }
 
150
}
 
151
 
 
152
Using this scope resolution naming scheme makes the origin of each variable unambiguous and the 
 
153
code easy to read (especially by people who did not write it!).
 
154
 
 
155
The [name] part of the variable should be short and descriptive, usually a noun.
 
156
 
 
157
The [type] part of the variable should be the type class of the variable written out in full.
 
158
 
 
159
*/ 
 
160
 
 
161
 
 
162
#ifndef QGSRASTERLAYER_H
 
163
#define QGSRASTERLAYER_H
 
164
 
 
165
//
 
166
// Includes
 
167
// 
 
168
 
 
169
#include <qvaluevector.h>
 
170
#include <qvaluelist.h> 
 
171
#include <qslider.h>
 
172
#include "qgspoint.h"
 
173
#include "qgsmaplayer.h"
 
174
#include "qgscolortable.h"
 
175
#include "qgsrasterlayer.h"
 
176
 
 
177
#include <gdal_priv.h>
 
178
//
 
179
// Forward declarations
 
180
//
 
181
class QgsRect;
 
182
class QgsRasterLayerProperties;
 
183
class GDALDataset;
 
184
class GDALRasterBand;
 
185
class QImage;
 
186
 
 
187
//
 
188
// Structs
 
189
//
 
190
 
 
191
/** \brief The RasterBandStats struct is a container for statistics about a single
 
192
 * raster band.
 
193
 */
 
194
struct RasterBandStats
 
195
{
 
196
    /** \brief The name of the band that these stats belong to. */
 
197
    QString bandName;
 
198
    /** \brief The gdal band number (starts at 1)*/
 
199
    int bandNoInt; 
 
200
    /** \brief A flag to indicate whether this RasterBandStats struct 
 
201
     * is completely populated */
 
202
    bool statsGatheredFlag; 
 
203
    /** \brief The minimum cell value in the raster band. NO_DATA values
 
204
     * are ignored. This does not use the gdal GetMinimum function. */
 
205
    double minValDouble;
 
206
    /** \brief The maximum cell value in the raster band. NO_DATA values
 
207
     * are ignored. This does not use the gdal GetMaximmum function. */
 
208
    double maxValDouble;
 
209
    /** \brief The range is the distance between min & max. */
 
210
    double rangeDouble;
 
211
    /** \brief The mean cell value for the band. NO_DATA values are excluded. */
 
212
    double meanDouble;
 
213
    /** \brief The sum of the squares. Used to calculate standard deviation. */
 
214
    double sumSqrDevDouble; 
 
215
    /** \brief The standard deviation of the cell values. */
 
216
    double stdDevDouble;
 
217
    /** \brief The sum of all cells in the band. NO_DATA values are excluded. */
 
218
    double sumDouble;
 
219
    /** \brief The number of cells in the band. Equivalent to height x width. 
 
220
     * TODO: check if NO_DATA are excluded!*/
 
221
    int elementCountInt;    
 
222
    /** \brief A histogram storing the distribution of values within the raster. */
 
223
    int histogram[256];
 
224
    /** Color table */
 
225
    QgsColorTable colorTable;
 
226
};
 
227
 
 
228
/** \brief  A vector containing one RasterBandStats struct per raster band in this raster layer.
 
229
 * Note that while very RasterBandStats element will have the name and number of its associated
 
230
 * band populated, any additional stats are calculated on a need to know basis.*/
 
231
typedef QValueVector<RasterBandStats> RasterStatsVector;
 
232
 
 
233
/** \brief The RasterViewPort describes the area of the raster layer that will be
 
234
 * rendered during a draw operation.
 
235
 */
 
236
struct RasterViewPort
 
237
{
 
238
    /** \brief  The offset from the left hand edge of the raster for the rectangle that will be drawn to screen.
 
239
     * TODO Check this explanation is correc!*/
 
240
    int rectXOffsetInt;
 
241
    /** \brief  The offset from the bottom edge of the raster for the rectangle that will be drawn to screen.
 
242
     * TODO Check this explanation is correc!*/
 
243
    int rectYOffsetInt;
 
244
    /** \brief Lower left X dimension of clipped raster image in raster pixel space.
 
245
     *  RasterIO will do the scaling for us, so for example, if the user is zoomed in a long way, there may only 
 
246
     *  be e.g. 5x5 pixels retrieved from the raw raster data, but rasterio will seamlessly scale the up to 
 
247
     *  whatever the screen coordinates are (e.g. a 600x800 display window) */
 
248
    double clippedXMinDouble;
 
249
    /** \brief Top Right X dimension of clipped raster image in raster pixel space.
 
250
     *  RasterIO will do the scaling for us, so for example, if the user is zoomed in a long way, there may only 
 
251
     *  be e.g. 5x5 pixels retrieved from the raw raster data, but rasterio will seamlessly scale the up to 
 
252
     *  whatever the screen coordinates are (e.g. a 600x800 display window) */
 
253
    double clippedXMaxDouble;
 
254
    /** \brief Lower left Y dimension of clipped raster image in raster pixel space.
 
255
     *  RasterIO will do the scaling for us, so for example, if the user is zoomed in a long way, there may only 
 
256
     *  be e.g. 5x5 pixels retrieved from the raw raster data, but rasterio will seamlessly scale the up to 
 
257
     *  whatever the screen coordinates are (e.g. a 600x800 display window) */
 
258
    double clippedYMinDouble;
 
259
    /** \brief Top Right X dimension of clipped raster image in raster pixel space.
 
260
     *  RasterIO will do the scaling for us, so for example, if the user is zoomed in a long way, there may only 
 
261
     *  be e.g. 5x5 pixels retrieved from the raw raster data, but rasterio will seamlessly scale the up to 
 
262
     *  whatever the screen coordinates are (e.g. a 600x800 display window) */
 
263
    double clippedYMaxDouble;
 
264
    /** \brief  Distance in pixels from clippedXMinDouble to clippedXMaxDouble. */
 
265
    int clippedWidthInt;
 
266
    /** \brief Distance in pixels from clippedYMinDouble to clippedYMaxDouble  */
 
267
    int clippedHeightInt;
 
268
    /** \brief Coordinate (in geographic coordinate system) of top left corner of the part of the raster that 
 
269
     * is to be rendered.*/
 
270
    QgsPoint topLeftPoint;
 
271
    /** \brief Coordinate (in geographic coordinate system) of bottom right corner of the part of the raster that 
 
272
     * is to be rendered.*/
 
273
    QgsPoint bottomRightPoint;
 
274
    /** \brief Distance in map units from left edge to right edge for the part of the raster that 
 
275
     * is to be rendered.*/
 
276
    int drawableAreaXDimInt;
 
277
    /** \brief Distance in map units from bottom edge to top edge for the part of the raster that 
 
278
     * is to be rendered.*/
 
279
    int drawableAreaYDimInt;
 
280
};
 
281
 
 
282
/** \brief This struct is used to store pyramid info for the raster layer. */
 
283
struct RasterPyramid
 
284
{
 
285
  /** \brief The pyramid level as implemented in gdal (level 2 is half orignal raster size etc) */
 
286
  int levelInt;
 
287
  /** \brief XDimension for this pyramid layer */
 
288
  int xDimInt;
 
289
  /** \brief YDimension for this pyramid layer */
 
290
  int yDimInt;
 
291
  /** \brief Whether the pyramid layer has been built yet */
 
292
  bool existsFlag;
 
293
 
 
294
};
 
295
 
 
296
/** \brief  A list containing one RasterPyramid struct per 
 
297
 * POTENTIAL pyramid layer. How this works is we divide the height
 
298
 * and width of the raster by an incrementing number. As soon as the result
 
299
 * of the division is <=256 we stop allowing RasterPyramid stracuts
 
300
 * to be added to the list. Each time a RasterPyramid is created
 
301
 * we will check to see if a pyramid matching these dimensions already exists
 
302
 * in the raster layer, and if so mark the exists flag as true. */
 
303
  
 
304
typedef QValueList<RasterPyramid> RasterPyramidList;
 
305
 
 
306
/** \brief This typedef is used when the showProgress function is passed to gdal as a function
 
307
pointer. */
 
308
//  typedef  int (QgsRasterLayer::*showTextProgress)( double theProgressDouble,
 
309
//                                      const char *theMessageCharArray,
 
310
//                                      void *theData);
 
311
  
 
312
  
 
313
/*! \class QgsRasterLayer
 
314
 *  \brief This class provides qgis with the ability to render raster datasets
 
315
 *  onto the mapcanvas..
 
316
 */
 
317
 
 
318
class QgsRasterLayer : public QgsMapLayer
 
319
{
 
320
    Q_OBJECT
 
321
public:
 
322
    //
 
323
    // Static methods:
 
324
    //
 
325
        
 
326
    static void buildSupportedRasterFileFilter(QString & fileFilters);
 
327
    static bool isSupportedRasterDriver(QString const &driverName);
 
328
    /** This helper checks to see whether the filename appears to be a valid raster file name */
 
329
    static bool isValidRasterFileName(QString theFileNameQString);
 
330
    /** Overloaded version of the above function provided for convenience that takes a qstring pointer */
 
331
    static bool isValidRasterFileName(QString * theFileNameQString);
 
332
 
 
333
    //
 
334
    // Non Static methods:
 
335
    //
 
336
        
 
337
    /** \brief This is the constructor for the RasterLayer class.
 
338
     *
 
339
     * The main tasks carried out by the constructor are:
 
340
     *
 
341
     * -Populate the RasterStatsVector with initial values for each band.
 
342
     *
 
343
     * -Calculate the layer extents
 
344
     *
 
345
     * -Determine whether the layer is gray, paletted or multiband.
 
346
     *
 
347
     * -Assign sensible defaults for the red,green, blue and gray bands.
 
348
     *
 
349
     * -
 
350
     * */
 
351
    QgsRasterLayer(QString path = 0, QString baseName = 0);
 
352
 
 
353
    /** \brief The destuctor.  */
 
354
    ~QgsRasterLayer();
 
355
 
 
356
 
 
357
    /** \brief Draws a thumbnail of the rasterlayer into the supplied pixmap pointer */
 
358
     void drawThumbnail(QPixmap * theQPixmap);
 
359
 
 
360
    /** \brief Get an 8x8 pixmap of the colour palette. If the layer has no palette a white pixmap will be returned. */
 
361
     QPixmap getPaletteAsPixmap();
 
362
     
 
363
    /** \brief This is called when the view on the rasterlayer needs to be refreshed (redrawn).  */
 
364
    void draw(QPainter * theQPainter, QgsRect * theViewExtent, QgsCoordinateTransform * theQgsCoordinateTransform, QPaintDevice* dst);
 
365
 
 
366
    /** \brief This is an overloaded version of the above function that is called by both draw above and drawThumbnail */
 
367
    void draw (QPainter * theQPainter, RasterViewPort * myRasterViewPort);
 
368
    
 
369
    //
 
370
    // Accessors for image height and width
 
371
    //
 
372
    /** \brief Accessor that returns the width of the (unclipped) raster  */
 
373
    const int getRasterXDim() {return rasterXDimInt;};
 
374
 
 
375
    /** \brief Accessor that returns the height of the (unclipped) raster  */
 
376
    const int getRasterYDim() {return rasterYDimInt;};
 
377
 
 
378
    //
 
379
    // Accessor and mutator for no data double
 
380
    //
 
381
    /** \brief  Accessor that returns the NO_DATA entry for this raster. */
 
382
    const double getNoDataValue() {return noDataValueDouble;}
 
383
 
 
384
    /** \brief  Mutator that allows the  NO_DATA entry for this raster to be overridden. */
 
385
    void setNoDataValue(double theNoDataDouble) { noDataValueDouble=theNoDataDouble; return;};
 
386
 
 
387
    //
 
388
    // Accessor and mutator for invertHistogramFlag
 
389
    //
 
390
    /** \brief Accessor to find out whether the histogram should be inverted.   */
 
391
    bool getInvertHistogramFlag()
 
392
    {
 
393
        return invertHistogramFlag;
 
394
    }
 
395
    /** \brief Mutator to alter the state of the invert histogram flag.  */
 
396
    void setInvertHistogramFlag(bool theFlag)
 
397
    {
 
398
        invertHistogramFlag=theFlag;
 
399
    }
 
400
    //
 
401
    // Accessor and mutator for stdDevsToPlotDouble
 
402
    //
 
403
    /** \brief Accessor to find out how many standard deviations are being plotted.  */
 
404
    double getStdDevsToPlot()
 
405
    {
 
406
        return stdDevsToPlotDouble;
 
407
    };
 
408
    /** \brief Mutator to alter the number of standard deviations that should be plotted.  */
 
409
    void setStdDevsToPlot(double theDouble)
 
410
    {
 
411
        stdDevsToPlotDouble = theDouble;
 
412
    };
 
413
    /** \brief Get the number of bands in this layer  */
 
414
    const unsigned int getBandCount()
 
415
    {
 
416
        return rasterStatsVector.size();
 
417
    };
 
418
    /** \brief Get RasterBandStats for a band given its number (read only)  */
 
419
    const  RasterBandStats getRasterBandStats(int);
 
420
    /** \brief  Check whether a given band number has stats associated with it */
 
421
    const bool hasStats(int theBandNoInt);
 
422
    /** \brief Overloaded method that also returns stats for a band, but uses the band colour name
 
423
    *    Note this approach is not recommeneded because it is possible for two gdal raster
 
424
    *    bands to have the same name!
 
425
    */
 
426
    const  RasterBandStats getRasterBandStats(QString);
 
427
    /** \brief Get the number of a band given its name. Note this will be the rewritten name set 
 
428
    *   up in the constructor, and will not necessarily be the same as the name retrieved directly from gdal!
 
429
    *   If no matching band is found zero will be returned! */
 
430
    const  int getRasterBandNumber (QString theBandNameQString);
 
431
    /** \brief Get the name of a band given its number.  */
 
432
    const  QString getRasterBandName(int theBandNoInt);
 
433
    /** \brief Find out whether a given band exists.    */
 
434
    bool hasBand(QString theBandName);
 
435
    /** \brief accessor for transparency level.  */
 
436
    unsigned int getTransparency();
 
437
    /** \brief Mutator for transparency level. Should be between 0 and 255 */
 
438
    void setTransparency(int); //
 
439
    /** \brief Call any inline image manipulation filters */
 
440
    void filterLayer(QImage * theQImage);
 
441
    /** \brief Accessor for red band name (allows alternate mappings e.g. map blue as red colour). */
 
442
    QString getRedBandName()
 
443
    {
 
444
        return redBandNameQString;
 
445
    };
 
446
    /** \brief Mutator for red band name (allows alternate mappings e.g. map blue as red colour). */
 
447
    void setRedBandName(QString theBandNameQString);
 
448
    // 
 
449
    // Accessor and mutator for green band name
 
450
    // 
 
451
    /** \brief Accessor for green band name mapping.  */
 
452
    QString getGreenBandName()
 
453
    {
 
454
        return greenBandNameQString;
 
455
    };
 
456
    /** \brief Mutator for green band name mapping.  */
 
457
    void setGreenBandName(QString theBandNameQString);
 
458
    //
 
459
    // Accessor and mutator for blue band name
 
460
    // 
 
461
    /** \brief  Accessor for blue band name mapping. */
 
462
    QString getBlueBandName()
 
463
    {
 
464
        return blueBandNameQString;
 
465
    };
 
466
    /** \brief Mutator for blue band name mapping.  */
 
467
    void setBlueBandName(QString theBandNameQString);
 
468
    //
 
469
    // Accessor and mutator for gray band name
 
470
    //
 
471
    /** \brief Accessor for gray band name mapping.  */
 
472
    QString getGrayBandName()
 
473
    {
 
474
        return grayBandNameQString;
 
475
    };
 
476
    /** \brief Mutator for gray band name mapping.  */
 
477
    void setGrayBandName(QString theBandNameQString);
 
478
    // 
 
479
    // Accessor and mutator for showDebugOverlayFlag
 
480
    // 
 
481
    /** \brief Accessor for a flag that determines whether to show some debug info on the image.  */
 
482
    bool getShowDebugOverlayFlag()
 
483
    {
 
484
        return showDebugOverlayFlag;
 
485
    };
 
486
    /** \brief Mutator for a flag that determines whether to show some debug info on the image.  */
 
487
    void setShowDebugOverlayFlag(bool theFlag)
 
488
    {
 
489
        showDebugOverlayFlag=theFlag;
 
490
    };
 
491
    // 
 
492
    // Accessor and mutator for min and max red
 
493
    // 
 
494
    /** \brief Accessor for minimum clipping range for red.
 
495
     *
 
496
     * The clipping range can have different interpretations - it can either be used to perform
 
497
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
498
     * that falls outside the clipping range.*/
 
499
    double getMinRedDouble()
 
500
    {
 
501
        return minRedDouble;
 
502
    };
 
503
    /** \brief Mutator for minimum clipping range for red.
 
504
     *
 
505
     * The clipping range can have different interpretations - it can either be used to perform
 
506
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
507
     * that falls outside the clipping range.*/
 
508
    void setMinRedDouble(double theDouble)
 
509
    {
 
510
        minRedDouble=theDouble;
 
511
    };
 
512
    /** \brief Accessor for maximum clipping range for red.
 
513
     *
 
514
     * The clipping range can have different interpretations - it can either be used to perform
 
515
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
516
     * that falls outside the clipping range.*/
 
517
    double getMaxRedDouble()
 
518
    {
 
519
        return maxRedDouble;
 
520
    };
 
521
    /** \brief Mutator for maximum clipping range for red.
 
522
     *
 
523
     * The clipping range can have different interpretations - it can either be used to perform
 
524
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
525
     * that falls outside the clipping range.*/
 
526
    void setMaxRedDouble(double theDouble)
 
527
    {
 
528
        maxRedDouble=theDouble;
 
529
    };
 
530
    // 
 
531
    // Accessor and mutator for min and max green
 
532
    // 
 
533
    /** \brief Accessor for minimum clipping range for green.
 
534
     *
 
535
     * The clipping range can have different interpretations - it can either be used to perform
 
536
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
537
     * that falls outside the clipping range.*/
 
538
    double getMinGreenDouble()
 
539
    {
 
540
        return minGreenDouble;
 
541
    };
 
542
    /** \brief Mutator for minimum clipping range for green.
 
543
     *
 
544
     * The clipping range can have different interpretations - it can either be used to perform
 
545
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
546
     * that falls outside the clipping range.*/
 
547
    void setMinGreenDouble(double theDouble)
 
548
    {
 
549
        minGreenDouble=theDouble;
 
550
    };
 
551
    /** \brief Accessor for maximum clipping range for green.
 
552
     *
 
553
     * The clipping range can have different interpretations - it can either be used to perform
 
554
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
555
     * that falls outside the clipping range.*/
 
556
    double getMaxGreenDouble()
 
557
    {
 
558
        return maxGreenDouble;
 
559
    };
 
560
    /** \brief Mutator for maximum clipping range for green.
 
561
     *
 
562
     * The clipping range can have different interpretations - it can either be used to perform
 
563
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
564
     * that falls outside the clipping range.*/
 
565
    void setMaxGreenDouble(double theDouble)
 
566
    {
 
567
        maxGreenDouble=theDouble;
 
568
    };
 
569
    // 
 
570
    // Accessor and mutator for min and max blue
 
571
    // 
 
572
    /** \brief Accessor for minimum clipping range for blue.
 
573
     *
 
574
     * The clipping range can have different interpretations - it can either be used to perform
 
575
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
576
     * that falls outside the clipping range.*/
 
577
    /** \brief   */
 
578
    double getMinBlueDouble()
 
579
    {
 
580
        return minBlueDouble;
 
581
    };
 
582
    /** \brief Mutator for minimum clipping range for blue.
 
583
     *
 
584
     * The clipping range can have different interpretations - it can either be used to perform
 
585
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
586
     * that falls outside the clipping range.*/
 
587
    void setMinBlueDouble(double theDouble)
 
588
    {
 
589
        minBlueDouble=theDouble;
 
590
    };
 
591
    /** \brief Accessor for maximum clipping range for blue.
 
592
     *
 
593
     * The clipping range can have different interpretations - it can either be used to perform
 
594
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
595
     * that falls outside the clipping range.*/
 
596
    double getMaxBlueDouble()
 
597
    {
 
598
        return maxBlueDouble;
 
599
    };
 
600
    /** \brief Mutator for maximum clipping range for blue.
 
601
     *
 
602
     * The clipping range can have different interpretations - it can either be used to perform
 
603
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
604
     * that falls outside the clipping range.*/
 
605
    void setMaxBlueDouble(double theDouble)
 
606
    {
 
607
        maxBlueDouble=theDouble;
 
608
    };
 
609
    // 
 
610
    // Accessor and mutator for min and max gray
 
611
    // 
 
612
    /** \brief Accessor for minimum clipping range for gray.
 
613
     *
 
614
     * The clipping range can have different interpretations - it can either be used to perform
 
615
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
616
     * that falls outside the clipping range.*/
 
617
    double getMinGrayDouble()
 
618
    {
 
619
        return minGrayDouble;
 
620
    };
 
621
    /** \brief Mutator for minimum clipping range for gray.
 
622
     *
 
623
     * The clipping range can have different interpretations - it can either be used to perform
 
624
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
625
     * that falls outside the clipping range.*/
 
626
    void setMinGrayDouble(double theDouble)
 
627
    {
 
628
        minGrayDouble=theDouble;
 
629
    };
 
630
    /** \brief Accessor for maximum clipping range for gray.
 
631
     *
 
632
     * The clipping range can have different interpretations - it can either be used to perform
 
633
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
634
     * that falls outside the clipping range.*/
 
635
    double getMaxGrayDouble()
 
636
    {
 
637
        return maxGrayDouble;
 
638
    };
 
639
    /** \brief Mutator for maximum clipping range for gray.
 
640
     *
 
641
     * The clipping range can have different interpretations - it can either be used to perform
 
642
     * a histogram stretch between the minimum and maximum clipping values, or to exclude data
 
643
     * that falls outside the clipping range.*/
 
644
    void setMaxGrayDouble(double theDouble)
 
645
    {
 
646
        maxGrayDouble=theDouble;
 
647
    };
 
648
    //
 
649
    /** \brief This enumerator describes the types of histogram scaling algorithms that can be used.  */
 
650
    enum COLOR_SCALING_ALGORITHM
 
651
    {
 
652
        STRETCH_TO_MINMAX, //linear histogram stretch
 
653
        STRETCH_AND_CLIP_TO_MINMAX,
 
654
        CLIP_TO_MINMAX
 
655
    } colorScalingAlgorithm;
 
656
    //
 
657
    // Accessor and mutator for the color scaling algorithm
 
658
    //
 
659
    /** \brief Accessor for colour scaling algorithm. */
 
660
    COLOR_SCALING_ALGORITHM getColorScalingAlgorithm()
 
661
    {
 
662
        return colorScalingAlgorithm;
 
663
    };
 
664
    /** \brief Mutator for color scaling algorithm. */
 
665
    void setColorScalingAlgorithm(COLOR_SCALING_ALGORITHM theAlgorithm)
 
666
    {
 
667
        colorScalingAlgorithm=theAlgorithm;
 
668
    };
 
669
    
 
670
    /** \brief This enumerator describes the types of histogram colour ramping that can be used.  */
 
671
    enum COLOR_RAMPING_TYPE
 
672
    {
 
673
        BLUE_GREEN_RED, 
 
674
        FREAK_OUT //it will scare your granny!
 
675
    } colorRampingType;
 
676
    //
 
677
    // Accessor and mutator for the color ramping type
 
678
    //
 
679
    /** \brief Accessor for colour ramping type. */
 
680
    COLOR_RAMPING_TYPE getColorRampingType()
 
681
    {
 
682
        return colorRampingType;
 
683
    };
 
684
    /** \brief Mutator for color scaling algorithm. */
 
685
    void setColorRampingType(COLOR_RAMPING_TYPE theRamping)
 
686
    {
 
687
        colorRampingType=theRamping;
 
688
    };
 
689
    
 
690
    /** \brief This enumerator describes the different kinds of drawing we can do.  */
 
691
    enum DRAWING_STYLE
 
692
    {
 
693
        SINGLE_BAND_GRAY, // a "Gray" or "Undefined" layer drawn as a range of gray colors
 
694
        SINGLE_BAND_PSEUDO_COLOR,// a "Gray" or "Undefined" layer drawn using a pseudocolor algorithm
 
695
        PALETTED_COLOR, //a "Palette" image drawn using color table
 
696
        PALETTED_SINGLE_BAND_GRAY,// a "Palette" layer drawn in gray scale (using only one of the color components)
 
697
        PALETTED_SINGLE_BAND_PSEUDO_COLOR, // a "Palette" layer having only one of its color components rendered as psuedo color
 
698
        PALETTED_MULTI_BAND_COLOR, // a "Palette" image is decomposed to 3 channels (RGB) and drawn 
 
699
                                   // as multiband 
 
700
        MULTI_BAND_SINGLE_BAND_GRAY, // a layer containing 2 or more bands, but using only one band to produce a grayscale image
 
701
        MULTI_BAND_SINGLE_BAND_PSEUDO_COLOR, //a layer containing 2 or more bands, but using only one band to produce a pseudocolor image
 
702
        MULTI_BAND_COLOR //a layer containing 2 or more bands, mapped to the three RGBcolors. In the case of a multiband with only two bands, one band will have to be mapped to more than one color
 
703
    } drawingStyle;    
 
704
    //
 
705
    // Accessor and mutator for drawing style.
 
706
    //
 
707
    /** \brief Accessor for drawing style.  */
 
708
    DRAWING_STYLE getDrawingStyle() {return drawingStyle;};
 
709
    /** \brief Returns a string representation of drawing style.
 
710
     *
 
711
     * Implementaed mainly for serialisation / deserialisation of settings to xml.
 
712
     * NOTE: May be deprecated in the future!. Use alternate implementation above rather.
 
713
     * */
 
714
    QString getDrawingStyleAsQString();
 
715
    /** \brief Mutator for drawing style.  */
 
716
    void setDrawingStyle(DRAWING_STYLE theDrawingStyle) {drawingStyle=theDrawingStyle;};
 
717
    /** \brief Overloaded version of the above function for convenience when restoring from xml.
 
718
     *
 
719
     * Implementaed mainly for serialisation / deserialisation of settings to xml.
 
720
     * NOTE: May be deprecated in the future! Use alternate implementation above rather.
 
721
     * */
 
722
    void setDrawingStyle(QString theDrawingStyleQString);
 
723
 
 
724
 
 
725
 
 
726
 
 
727
    /** \brief This enumerator describes the type of raster layer.  */
 
728
    enum RASTER_LAYER_TYPE
 
729
    {
 
730
        GRAY_OR_UNDEFINED,
 
731
        PALETTE,
 
732
        MULTIBAND    
 
733
    } rasterLayerType;
 
734
    //
 
735
    //accessor and for raster layer type (READ ONLY)
 
736
    //
 
737
    /** \brief  Accessor for raster layer type (which is a read only property) */
 
738
    RASTER_LAYER_TYPE getRasterLayerType() { return rasterLayerType; };
 
739
    /** \brief Accessor for hasPyramidsFlag (READ ONLY) */
 
740
    bool getHasPyramidsFlag() {return hasPyramidsFlag;};
 
741
     
 
742
    /** \brief Get a legend image for this layer.  */
 
743
    QPixmap getLegendQPixmap();
 
744
    /** \brief  Overloaded version of above function that can print layer name onto legend. */
 
745
    QPixmap getLegendQPixmap(bool);
 
746
    /** \brief Similar to above but returns a pointer. Implemented for qgsmaplayer interface. 
 
747
     * Always overlays legend name!*/
 
748
    QPixmap * legendPixmap(); 
 
749
 
 
750
    /** tailor the right-click context menu with raster layer only stuff 
 
751
 
 
752
      @note called by QgsMapLayer::initContextMenu();
 
753
     */
 
754
    void initContextMenu_(QgisApp *);
 
755
 
 
756
    /** \brief Accessor for the superclass's popmenu var - implements the pure virtual funtion. */
 
757
    QPopupMenu *contextMenu();
 
758
    /** \brief Emit a signal asking for a repaint. (inherited from maplayer) */
 
759
    void triggerRepaint();
 
760
    /** \brief Obtain GDAL Metadata for this layer */
 
761
    QString getMetadata(); 
 
762
    /** \brief Accessor for ths raster layers pyramid list. A pyramid list defines the 
 
763
     * POTENTIAL pyramids that can be in a raster. To know which of the pyramid layers 
 
764
     * ACTUALLY exists you need to look at the existsFlag member in each struct stored in the 
 
765
     * list.*/
 
766
    RasterPyramidList buildRasterPyramidList();
 
767
    /** \brief Helper method to retrieve the nth pyramid layer struct from the PyramidList. 
 
768
     * If the nth layer does not exist, NULL will be returned. */
 
769
//   RasterPyramid getRasterPyramid(int thePyramidNo);
 
770
 
 
771
    /**Currently returns always false*/
 
772
    bool isEditable() const;
 
773
    
 
774
    
 
775
public slots:    
 
776
 
 
777
    /** sets whether this is in overview or not */
 
778
    void inOverview( bool );
 
779
 
 
780
    /** \brief Slot called when the popup menu transparency slider has been moved.*/
 
781
    void popupTransparencySliderMoved(int);
 
782
     
 
783
    /** \brief Create  gdal pyramid overviews  for this layer.
 
784
    * This will speed up performance at the expense of hard drive space.
 
785
    * Also, write access to the file is required. If no paramter is passed in
 
786
    * it will default to nearest neighbor resampling. */
 
787
    void buildPyramids(RasterPyramidList,QString theResamplingMethod="NEAREST");
 
788
    /** \brief Used at the moment by the above function but hopefully will later
 
789
    be useable by any operation that needs to notify the user of its progress. */
 
790
/*
 
791
    int showTextProgress( double theProgressDouble,
 
792
                          const char *theMessageCharArray,
 
793
                          void *theData);    
 
794
*/
 
795
 
 
796
    /** \brief This method is called when the properties for this layer needs to be modified. 
 
797
     * invokes an instance of the QgsRasterLayerProperties dialog box.*/
 
798
    /* virtual */ void showLayerProperties();
 
799
 
 
800
 
 
801
 protected:
 
802
 
 
803
    /** reads vector layer specific state from project file DOM node.
 
804
 
 
805
        @note
 
806
 
 
807
        Called by QgsMapLayer::readXML().
 
808
 
 
809
    */
 
810
    /* virtual */ bool readXML_( QDomNode & layer_node );
 
811
 
 
812
 
 
813
 
 
814
  /** write vector layer specific state to project file DOM node.
 
815
 
 
816
      @note
 
817
 
 
818
      Called by QgsMapLayer::writeXML().
 
819
 
 
820
  */
 
821
  /* virtual */ bool writeXML_( QDomNode & layer_node, QDomDocument & doc );
 
822
 
 
823
 
 
824
private:
 
825
 
 
826
    //
 
827
    // Private methods
 
828
    //
 
829
    /** \brief Paint debug information onto the output image.  */
 
830
    void showDebugOverlay(QPainter * theQPainter, RasterViewPort * theRasterViewPort);
 
831
 
 
832
    //
 
833
    // Grayscale Imagery
 
834
    //
 
835
 
 
836
    /** \brief Drawing routine for single band grayscale image.  */
 
837
    void drawSingleBandGray(QPainter * theQPainter, RasterViewPort * theRasterViewPort,int theBandNoInt);
 
838
 
 
839
    /** \brief Drawing routine for single band grayscale image, rendered in pseudocolor.  */
 
840
    void drawSingleBandPseudoColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort,int theBandNoInt);
 
841
 
 
842
 
 
843
    //
 
844
    // Paletted Layers
 
845
    //
 
846
    
 
847
    /** \brief Drawing routine for paletted image, rendered as a single band image in color.  */
 
848
    void drawPalettedSingleBandColor(QPainter * theQPainter,
 
849
                                RasterViewPort * theRasterViewPort,
 
850
                                int theBandNoInt);
 
851
    
 
852
    /** \brief Drawing routine for paletted image, rendered as a single band image in grayscale.  */
 
853
    void drawPalettedSingleBandGray(QPainter * theQPainter,
 
854
                                RasterViewPort * theRasterViewPort,
 
855
                                int theBandNoInt,
 
856
                                QString theColorQString);
 
857
 
 
858
    /** \brief Drawing routine for paletted image, rendered as a single band image in pseudocolor.  */
 
859
    void drawPalettedSingleBandPseudoColor(QPainter * theQPainter,
 
860
                                RasterViewPort * theRasterViewPort,
 
861
                                int theBandNoInt,
 
862
                                QString theColorQString);
 
863
 
 
864
    /** \brief Drawing routine for paletted multiband image.  */
 
865
    void drawPalettedMultiBandColor(QPainter * theQPainter,
 
866
                                RasterViewPort * theRasterViewPort,
 
867
                                int theBandNoInt);
 
868
 
 
869
    //
 
870
    // Multiband Layers
 
871
    //
 
872
    
 
873
    /** \brief Drawing routine for multiband image, rendered as a single band image in grayscale.  */
 
874
    void drawMultiBandSingleBandGray(QPainter * theQPainter,
 
875
                                RasterViewPort * theRasterViewPort, 
 
876
                                int theBandNoInt);
 
877
 
 
878
    /** \brief Drawing routine for multiband image, rendered as a single band image in pseudocolor.  */
 
879
    void drawMultiBandSingleBandPseudoColor(QPainter * theQPainter, 
 
880
                                RasterViewPort * theRasterViewPort, 
 
881
                                int theBandNoInt);
 
882
 
 
883
    /** \brief Drawing routine for multiband image  */
 
884
    void drawMultiBandColor(QPainter * theQPainter, RasterViewPort * theRasterViewPort);
 
885
 
 
886
    /** \brief Read color table from GDAL raster band */
 
887
    void readColorTable ( GDALRasterBand *gdalBand, QgsColorTable *theColorTable );
 
888
 
 
889
    /** \brief Allocate memory and load data to that allocated memory, data type is the same
 
890
     *         as raster band. The memory must be released later!
 
891
     *  \return pointer to the memory
 
892
     */
 
893
    void *readData ( GDALRasterBand *gdalBand, RasterViewPort *viewPort );
 
894
 
 
895
    /** \brief Read a raster value on given position from memory block created by readData() 
 
896
     *  \param index index in memory block
 
897
     */
 
898
    inline double readValue ( void *data, GDALDataType type, int index );
 
899
 
 
900
    /** \brief Color table 
 
901
     *  \param band number
 
902
     *  \return pointer to color table
 
903
     */
 
904
    QgsColorTable *colorTable ( int theBandNoInt );
 
905
 
 
906
    /**
 
907
       Load the given raster file
 
908
 
 
909
       @returns true if successfully read file
 
910
 
 
911
       @note
 
912
       
 
913
       Called from ctor if a raster image given there
 
914
     */
 
915
    bool readFile( QString const & fileName );
 
916
 
 
917
    //
 
918
    // Private member vars
 
919
    //
 
920
    /** \brief  Raster width. */
 
921
    int rasterXDimInt;
 
922
    /** \brief  Raster Height. */
 
923
    int rasterYDimInt;
 
924
    /** \brief Cell value representing no data. e.g. -9999  */
 
925
    double noDataValueDouble;
 
926
    /** \brief Flag to indicate whether debug infor overlay should be rendered onto the raster.  */
 
927
    bool showDebugOverlayFlag;
 
928
    /** \brief Pointer to the gdaldataset.  */
 
929
    GDALDataset * gdalDataset;
 
930
    /** \brief Values for mapping pixel to world coordinates.  */
 
931
    double adfGeoTransform[6];
 
932
    /** \brief Flag indicating whether the histogram should be inverted or not.  */
 
933
    bool invertHistogramFlag;
 
934
    /** \brief Number of stddev to plot (0) to ignore. Not applicable to all layer types.  */
 
935
    double stdDevsToPlotDouble;
 
936
    /** \brief A collection of stats - one for each band in the layer.
 
937
     * The typedef for this is defined above before class declaration
 
938
     */
 
939
    RasterStatsVector rasterStatsVector;
 
940
    /** \brief Transparency level for this layer should be 0-255.  */
 
941
    unsigned int transparencyLevelInt;
 
942
    /** \brief The band to be associated with the color red - usually 1.  */
 
943
    QString redBandNameQString;
 
944
    /** \brief The band to be associated with the color green - usually 2.  */
 
945
    QString greenBandNameQString;
 
946
    /** \brief The band to be associated with the color blue - usually 3.  */
 
947
    QString blueBandNameQString;
 
948
    /** \brief The band to be associated with the grayscale only ouput - usually 1.  */
 
949
    QString grayBandNameQString;
 
950
    /** \brief Minimum red value - used in scaling procedure.  */
 
951
    double minRedDouble;
 
952
    /** \brief Maximum red value - used in scaling procedure.  */
 
953
    double maxRedDouble;
 
954
    /** \brief Minimum green value - used in scaling procedure.  */
 
955
    double minGreenDouble;
 
956
    /** \brief Maximum green value - used in scaling procedure.  */
 
957
    double maxGreenDouble;
 
958
    /** \brief Minimum blue value - used in scaling procedure.  */
 
959
    double minBlueDouble;
 
960
    /** \brief Maximum blue value - used in scaling procedure.  */
 
961
    double maxBlueDouble;
 
962
    /** \brief Minimum gray value - used in scaling procedure.  */
 
963
    double minGrayDouble;
 
964
    /** \brief Maximum gray value - used in scaling procedure.  */
 
965
    double maxGrayDouble;
 
966
    /** \brief Whether this raster has overviews / pyramids or not */
 
967
    bool hasPyramidsFlag;
 
968
    /** \brief These are two little icons used to indicate whether a 
 
969
     * layer has pyramds bult or not. */
 
970
    QPixmap mPyramidPixmap, mNoPyramidPixmap;
 
971
    /** \brief This list holds a series of RasterPyramid structs
 
972
     * which store infomation for each potential pyramid level for this raster.*/
 
973
    RasterPyramidList mPyramidList;
 
974
    //Transparency slider for popup menu
 
975
    QSlider * mTransparencySlider; 
 
976
    //we need to do the tr() stuff outside of the main drawing loops becauses tr() is a 
 
977
    //time consuming operation nd we dont want to do it in the loop!
 
978
    QString redTranslatedQString;
 
979
    QString greenTranslatedQString;
 
980
    QString blueTranslatedQString;
 
981
 
 
982
    /* raster properties dialog 
 
983
 
 
984
       @todo XXX should consider generalizing this
 
985
    */
 
986
    QgsRasterLayerProperties * mLayerProperties;
 
987
    
 
988
};
 
989
 
 
990
#endif