QGIS API Documentation  2.2.0-Valmiera
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsrasterlayer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterlayer.cpp - description
3  -------------------
4 begin : Sat Jun 22 2002
5 copyright : (C) 2003 by Tim Sutton, Steve Halasz and Gary E.Sherman
6 email : tim at 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 #include "qgsapplication.h"
18 #include "qgscolorrampshader.h"
20 #include "qgscoordinatetransform.h"
21 #include "qgsdatasourceuri.h"
22 #include "qgslogger.h"
23 #include "qgsmaplayerregistry.h"
24 #include "qgsmaptopixel.h"
25 #include "qgsmessagelog.h"
29 #include "qgsproviderregistry.h"
30 #include "qgspseudocolorshader.h"
31 #include "qgsrasterdrawer.h"
32 #include "qgsrasteriterator.h"
33 #include "qgsrasterlayer.h"
34 #include "qgsrasterprojector.h"
35 #include "qgsrasterrange.h"
37 #include "qgsrectangle.h"
38 #include "qgsrendercontext.h"
42 
43 #include <cmath>
44 #include <cstdio>
45 #include <limits>
46 #include <typeinfo>
47 
48 #include <QApplication>
49 #include <QCursor>
50 #include <QDomElement>
51 #include <QDomNode>
52 #include <QFile>
53 #include <QFileInfo>
54 #include <QFont>
55 #include <QFontMetrics>
56 #include <QFrame>
57 #include <QImage>
58 #include <QLabel>
59 #include <QLibrary>
60 #include <QList>
61 #include <QMatrix>
62 #include <QMessageBox>
63 #include <QPainter>
64 #include <QPixmap>
65 #include <QRegExp>
66 #include <QSettings>
67 #include <QSlider>
68 #include <QTime>
69 
70 // typedefs for provider plugin functions of interest
71 typedef bool isvalidrasterfilename_t( QString const & theFileNameQString, QString & retErrMsg );
72 
73 #define ERR(message) QGS_ERROR_MESSAGE(message,"Raster layer")
74 
75 const double QgsRasterLayer::CUMULATIVE_CUT_LOWER = 0.02;
76 const double QgsRasterLayer::CUMULATIVE_CUT_UPPER = 0.98;
77 const double QgsRasterLayer::SAMPLE_SIZE = 250000;
78 
80  : QgsMapLayer( RasterLayer )
81  , QSTRING_NOT_SET( "Not Set" )
82  , TRSTRING_NOT_SET( tr( "Not Set" ) )
83  , mDataProvider( 0 )
84 {
85  init();
86  mValid = false;
87 }
88 
90  QString const & path,
91  QString const & baseName,
92  bool loadDefaultStyleFlag )
93  : QgsMapLayer( RasterLayer, baseName, path )
94  , QSTRING_NOT_SET( "Not Set" )
95  , TRSTRING_NOT_SET( tr( "Not Set" ) )
96  , mDataProvider( 0 )
97 {
98  QgsDebugMsg( "Entered" );
99 
100  // TODO, call constructor with provider key
101  init();
102  setDataProvider( "gdal" );
103  if ( !mValid ) return;
104 
105  bool defaultLoadedFlag = false;
106  if ( mValid && loadDefaultStyleFlag )
107  {
108  loadDefaultStyle( defaultLoadedFlag );
109  }
110  if ( !defaultLoadedFlag )
111  {
113  }
114  return;
115 } // QgsRasterLayer ctor
116 
121 QgsRasterLayer::QgsRasterLayer( const QString & uri,
122  const QString & baseName,
123  const QString & providerKey,
124  bool loadDefaultStyleFlag )
125  : QgsMapLayer( RasterLayer, baseName, uri )
126  // Constant that signals property not used.
127  , QSTRING_NOT_SET( "Not Set" )
128  , TRSTRING_NOT_SET( tr( "Not Set" ) )
129  , mDataProvider( 0 )
130  , mProviderKey( providerKey )
131 {
132  QgsDebugMsg( "Entered" );
133  init();
134  setDataProvider( providerKey );
135  if ( !mValid ) return;
136 
137  // load default style
138  bool defaultLoadedFlag = false;
139  if ( mValid && loadDefaultStyleFlag )
140  {
141  loadDefaultStyle( defaultLoadedFlag );
142  }
143  if ( !defaultLoadedFlag )
144  {
146  }
147 
148  // TODO: Connect signals from the dataprovider to the qgisapp
149 
150  emit statusChanged( tr( "QgsRasterLayer created" ) );
151 } // QgsRasterLayer ctor
152 
154 {
155  mValid = false;
156  // Note: provider and other interfaces are owned and deleted by pipe
157 }
158 
160 //
161 // Static Methods and members
162 //
164 
168 bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString, QString & retErrMsg )
169 {
170  isvalidrasterfilename_t *pValid = ( isvalidrasterfilename_t * ) cast_to_fptr( QgsProviderRegistry::instance()->function( "gdal", "isValidRasterFileName" ) );
171  if ( ! pValid )
172  {
173  QgsDebugMsg( "Could not resolve isValidRasterFileName in gdal provider library" );
174  return false;
175  }
176 
177  bool myIsValid = pValid( theFileNameQString, retErrMsg );
178  return myIsValid;
179 }
180 
181 bool QgsRasterLayer::isValidRasterFileName( QString const & theFileNameQString )
182 {
183  QString retErrMsg;
184  return isValidRasterFileName( theFileNameQString, retErrMsg );
185 }
186 
187 QDateTime QgsRasterLayer::lastModified( QString const & name )
188 {
189  QgsDebugMsg( "name=" + name );
190  QDateTime t;
191 
192  QFileInfo fi( name );
193 
194  // Is it file?
195  if ( !fi.exists() )
196  return t;
197 
198  t = fi.lastModified();
199 
200  QgsDebugMsg( "last modified = " + t.toString() );
201 
202  return t;
203 }
204 
205 // typedef for the QgsDataProvider class factory
206 typedef QgsDataProvider * classFactoryFunction_t( const QString * );
207 
209 //
210 // Non Static Public methods
211 //
213 
215 {
216  if ( !mDataProvider ) return 0;
217  return mDataProvider->bandCount();
218 }
219 
220 const QString QgsRasterLayer::bandName( int theBandNo )
221 {
222  return dataProvider()->generateBandName( theBandNo );
223 }
224 
226 {
227  setRenderer( QgsRasterRendererRegistry::instance()->defaultRendererForDrawingStyle( theDrawingStyle, mDataProvider ) );
228 }
229 
234 {
235  return mDataProvider;
236 }
237 
242 {
243  return mDataProvider;
244 }
245 
247 {
248  if ( mDataProvider )
249  {
251  }
252 }
253 
254 bool QgsRasterLayer::draw( QgsRenderContext& rendererContext )
255 {
256  QgsDebugMsg( "entered. (renderContext)" );
257 
258  QgsDebugMsg( "checking timestamp." );
259 
260  // Check timestamp
261  if ( !update() )
262  {
263  return false;
264  }
265 
266  const QgsMapToPixel& theQgsMapToPixel = rendererContext.mapToPixel();
267 
268  QgsRectangle myProjectedViewExtent;
269  QgsRectangle myProjectedLayerExtent;
270 
271  if ( rendererContext.coordinateTransform() )
272  {
273  QgsDebugMsg( "coordinateTransform set -> project extents." );
274  try
275  {
276  myProjectedViewExtent = rendererContext.coordinateTransform()->transformBoundingBox( rendererContext.extent() );
277  }
278  catch ( QgsCsException &cs )
279  {
280  QgsMessageLog::logMessage( tr( "Could not reproject view extent: %1" ).arg( cs.what() ), tr( "Raster" ) );
281  myProjectedViewExtent.setMinimal();
282  }
283 
284  try
285  {
286  myProjectedLayerExtent = rendererContext.coordinateTransform()->transformBoundingBox( extent() );
287  }
288  catch ( QgsCsException &cs )
289  {
290  QgsMessageLog::logMessage( tr( "Could not reproject layer extent: %1" ).arg( cs.what() ), tr( "Raster" ) );
291  myProjectedViewExtent.setMinimal();
292  }
293  }
294  else
295  {
296  QgsDebugMsg( "coordinateTransform not set" );
297  myProjectedViewExtent = rendererContext.extent();
298  myProjectedLayerExtent = extent();
299  }
300 
301  QPainter* theQPainter = rendererContext.painter();
302 
303  if ( !theQPainter )
304  {
305  return false;
306  }
307 
308  // clip raster extent to view extent
309  QgsRectangle myRasterExtent = myProjectedViewExtent.intersect( &myProjectedLayerExtent );
310  if ( myRasterExtent.isEmpty() )
311  {
312  QgsDebugMsg( "draw request outside view extent." );
313  // nothing to do
314  return true;
315  }
316 
317  QgsDebugMsg( "theViewExtent is " + rendererContext.extent().toString() );
318  QgsDebugMsg( "myProjectedViewExtent is " + myProjectedViewExtent.toString() );
319  QgsDebugMsg( "myProjectedLayerExtent is " + myProjectedLayerExtent.toString() );
320  QgsDebugMsg( "myRasterExtent is " + myRasterExtent.toString() );
321 
322  //
323  // The first thing we do is set up the QgsRasterViewPort. This struct stores all the settings
324  // relating to the size (in pixels and coordinate system units) of the raster part that is
325  // in view in the map window. It also stores the origin.
326  //
327  //this is not a class level member because every time the user pans or zooms
328  //the contents of the rasterViewPort will change
329  QgsRasterViewPort *myRasterViewPort = new QgsRasterViewPort();
330 
331  myRasterViewPort->mDrawnExtent = myRasterExtent;
332  if ( rendererContext.coordinateTransform() )
333  {
334  myRasterViewPort->mSrcCRS = crs();
335  myRasterViewPort->mDestCRS = rendererContext.coordinateTransform()->destCRS();
336  myRasterViewPort->mSrcDatumTransform = rendererContext.coordinateTransform()->sourceDatumTransform();
337  myRasterViewPort->mDestDatumTransform = rendererContext.coordinateTransform()->destinationDatumTransform();
338  }
339  else
340  {
341  myRasterViewPort->mSrcCRS = QgsCoordinateReferenceSystem(); // will be invalid
342  myRasterViewPort->mDestCRS = QgsCoordinateReferenceSystem(); // will be invalid
343  myRasterViewPort->mSrcDatumTransform = -1;
344  myRasterViewPort->mDestDatumTransform = -1;
345  }
346 
347  // get dimensions of clipped raster image in device coordinate space (this is the size of the viewport)
348  myRasterViewPort->mTopLeftPoint = theQgsMapToPixel.transform( myRasterExtent.xMinimum(), myRasterExtent.yMaximum() );
349  myRasterViewPort->mBottomRightPoint = theQgsMapToPixel.transform( myRasterExtent.xMaximum(), myRasterExtent.yMinimum() );
350 
351  // align to output device grid, i.e. floor/ceil to integers
352  // TODO: this should only be done if paint device is raster - screen, image
353  // for other devices (pdf) it can have floating point origin
354  // we could use floating point for raster devices as well, but respecting the
355  // output device grid should make it more effective as the resampling is done in
356  // the provider anyway
357  myRasterViewPort->mTopLeftPoint.setX( floor( myRasterViewPort->mTopLeftPoint.x() ) );
358  myRasterViewPort->mTopLeftPoint.setY( floor( myRasterViewPort->mTopLeftPoint.y() ) );
359  myRasterViewPort->mBottomRightPoint.setX( ceil( myRasterViewPort->mBottomRightPoint.x() ) );
360  myRasterViewPort->mBottomRightPoint.setY( ceil( myRasterViewPort->mBottomRightPoint.y() ) );
361  // recalc myRasterExtent to aligned values
362  myRasterExtent.set(
363  theQgsMapToPixel.toMapCoordinatesF( myRasterViewPort->mTopLeftPoint.x(),
364  myRasterViewPort->mBottomRightPoint.y() ),
365  theQgsMapToPixel.toMapCoordinatesF( myRasterViewPort->mBottomRightPoint.x(),
366  myRasterViewPort->mTopLeftPoint.y() )
367  );
368 
369  //raster viewport top left / bottom right are already rounded to int
370  myRasterViewPort->mWidth = static_cast<int>( myRasterViewPort->mBottomRightPoint.x() - myRasterViewPort->mTopLeftPoint.x() );
371  myRasterViewPort->mHeight = static_cast<int>( myRasterViewPort->mBottomRightPoint.y() - myRasterViewPort->mTopLeftPoint.y() );
372 
373 
374  //the drawable area can start to get very very large when you get down displaying 2x2 or smaller, this is becasue
375  //theQgsMapToPixel.mapUnitsPerPixel() is less then 1,
376  //so we will just get the pixel data and then render these special cases differently in paintImageToCanvas()
377 
378  QgsDebugMsgLevel( QString( "mapUnitsPerPixel = %1" ).arg( theQgsMapToPixel.mapUnitsPerPixel() ), 3 );
379  QgsDebugMsgLevel( QString( "mWidth = %1" ).arg( width() ), 3 );
380  QgsDebugMsgLevel( QString( "mHeight = %1" ).arg( height() ), 3 );
381  QgsDebugMsgLevel( QString( "myRasterExtent.xMinimum() = %1" ).arg( myRasterExtent.xMinimum() ), 3 );
382  QgsDebugMsgLevel( QString( "myRasterExtent.xMaximum() = %1" ).arg( myRasterExtent.xMaximum() ), 3 );
383  QgsDebugMsgLevel( QString( "myRasterExtent.yMinimum() = %1" ).arg( myRasterExtent.yMinimum() ), 3 );
384  QgsDebugMsgLevel( QString( "myRasterExtent.yMaximum() = %1" ).arg( myRasterExtent.yMaximum() ), 3 );
385 
386  QgsDebugMsgLevel( QString( "mTopLeftPoint.x() = %1" ).arg( myRasterViewPort->mTopLeftPoint.x() ), 3 );
387  QgsDebugMsgLevel( QString( "mBottomRightPoint.x() = %1" ).arg( myRasterViewPort->mBottomRightPoint.x() ), 3 );
388  QgsDebugMsgLevel( QString( "mTopLeftPoint.y() = %1" ).arg( myRasterViewPort->mTopLeftPoint.y() ), 3 );
389  QgsDebugMsgLevel( QString( "mBottomRightPoint.y() = %1" ).arg( myRasterViewPort->mBottomRightPoint.y() ), 3 );
390 
391  QgsDebugMsgLevel( QString( "mWidth = %1" ).arg( myRasterViewPort->mWidth ), 3 );
392  QgsDebugMsgLevel( QString( "mHeight = %1" ).arg( myRasterViewPort->mHeight ), 3 );
393 
394  // /\/\/\ - added to handle zoomed-in rasters
395 
396  mLastViewPort = *myRasterViewPort;
397 
398  // TODO: is it necessary? Probably WMS only?
399  mDataProvider->setDpi( rendererContext.rasterScaleFactor() * 25.4 * rendererContext.scaleFactor() );
400 
401  draw( theQPainter, myRasterViewPort, &theQgsMapToPixel );
402 
403  delete myRasterViewPort;
404  QgsDebugMsg( "exiting." );
405 
406  return true;
407 
408 }
409 
410 void QgsRasterLayer::draw( QPainter * theQPainter,
411  QgsRasterViewPort * theRasterViewPort,
412  const QgsMapToPixel* theQgsMapToPixel )
413 {
414  QgsDebugMsg( " 3 arguments" );
415  QTime time;
416  time.start();
417  //
418  //
419  // The goal here is to make as many decisions as possible early on (outside of the rendering loop)
420  // so that we can maximise performance of the rendering process. So now we check which drawing
421  // procedure to use :
422  //
423 
424  QgsRasterProjector *projector = mPipe.projector();
425 
426  // TODO add a method to interface to get provider and get provider
427  // params in QgsRasterProjector
428  if ( projector )
429  {
430  projector->setCRS( theRasterViewPort->mSrcCRS, theRasterViewPort->mDestCRS, theRasterViewPort->mSrcDatumTransform, theRasterViewPort->mDestDatumTransform );
431  }
432 
433  // Drawer to pipe?
434  QgsRasterIterator iterator( mPipe.last() );
435  QgsRasterDrawer drawer( &iterator );
436  drawer.draw( theQPainter, theRasterViewPort, theQgsMapToPixel );
437 
438  QgsDebugMsg( QString( "total raster draw time (ms): %1" ).arg( time.elapsed(), 5 ) );
439 } //end of draw method
440 
442 {
443  return mError;
444 }
445 
447 {
448  return mErrorCaption;
449 }
450 
451 QList< QPair< QString, QColor > > QgsRasterLayer::legendSymbologyItems() const
452 {
453  QList< QPair< QString, QColor > > symbolList;
455  if ( renderer )
456  {
457  renderer->legendSymbologyItems( symbolList );
458  }
459  return symbolList;
460 }
461 
463 {
464  QString myMetadata ;
465  myMetadata += "<p class=\"glossy\">" + tr( "Driver" ) + "</p>\n";
466  myMetadata += "<p>";
467  myMetadata += mDataProvider->description();
468  myMetadata += "</p>\n";
469 
470  // Insert provider-specific (e.g. WMS-specific) metadata
471  // crashing
472  myMetadata += mDataProvider->metadata();
473 
474  myMetadata += "<p class=\"glossy\">";
475  myMetadata += tr( "No Data Value" );
476  myMetadata += "</p>\n";
477  myMetadata += "<p>";
478  // TODO: all bands
479  if ( mDataProvider->srcHasNoDataValue( 1 ) )
480  {
481  myMetadata += QString::number( mDataProvider->srcNoDataValue( 1 ) );
482  }
483  else
484  {
485  myMetadata += "*" + tr( "NoDataValue not set" ) + "*";
486  }
487  myMetadata += "</p>\n";
488 
489  myMetadata += "</p>\n";
490  myMetadata += "<p class=\"glossy\">";
491  myMetadata += tr( "Data Type" );
492  myMetadata += "</p>\n";
493  myMetadata += "<p>";
494  //just use the first band
495  switch ( mDataProvider->srcDataType( 1 ) )
496  {
497  case QGis::Byte:
498  myMetadata += tr( "Byte - Eight bit unsigned integer" );
499  break;
500  case QGis::UInt16:
501  myMetadata += tr( "UInt16 - Sixteen bit unsigned integer " );
502  break;
503  case QGis::Int16:
504  myMetadata += tr( "Int16 - Sixteen bit signed integer " );
505  break;
506  case QGis::UInt32:
507  myMetadata += tr( "UInt32 - Thirty two bit unsigned integer " );
508  break;
509  case QGis::Int32:
510  myMetadata += tr( "Int32 - Thirty two bit signed integer " );
511  break;
512  case QGis::Float32:
513  myMetadata += tr( "Float32 - Thirty two bit floating point " );
514  break;
515  case QGis::Float64:
516  myMetadata += tr( "Float64 - Sixty four bit floating point " );
517  break;
518  case QGis::CInt16:
519  myMetadata += tr( "CInt16 - Complex Int16 " );
520  break;
521  case QGis::CInt32:
522  myMetadata += tr( "CInt32 - Complex Int32 " );
523  break;
524  case QGis::CFloat32:
525  myMetadata += tr( "CFloat32 - Complex Float32 " );
526  break;
527  case QGis::CFloat64:
528  myMetadata += tr( "CFloat64 - Complex Float64 " );
529  break;
530  default:
531  myMetadata += tr( "Could not determine raster data type." );
532  }
533  myMetadata += "</p>\n";
534 
535  myMetadata += "<p class=\"glossy\">";
536  myMetadata += tr( "Pyramid overviews" );
537  myMetadata += "</p>\n";
538  myMetadata += "<p>";
539 
540  myMetadata += "<p class=\"glossy\">";
541  myMetadata += tr( "Layer Spatial Reference System" );
542  myMetadata += "</p>\n";
543  myMetadata += "<p>";
544  myMetadata += crs().toProj4();
545  myMetadata += "</p>\n";
546 
547  myMetadata += "<p class=\"glossy\">";
548  myMetadata += tr( "Layer Extent (layer original source projection)" );
549  myMetadata += "</p>\n";
550  myMetadata += "<p>";
551  myMetadata += mDataProvider->extent().toString();
552  myMetadata += "</p>\n";
553 
554  // output coordinate system
555  // TODO: this is not related to layer, to be removed? [MD]
556 #if 0
557  myMetadata += "<tr><td class=\"glossy\">";
558  myMetadata += tr( "Project Spatial Reference System" );
559  myMetadata += "</p>\n";
560  myMetadata += "<p>";
561  myMetadata += mCoordinateTransform->destCRS().toProj4();
562  myMetadata += "</p>\n";
563 #endif
564 
565  //
566  // Add the stats for each band to the output table
567  //
568  int myBandCountInt = bandCount();
569  for ( int myIteratorInt = 1; myIteratorInt <= myBandCountInt; ++myIteratorInt )
570  {
571  QgsDebugMsg( "Raster properties : checking if band " + QString::number( myIteratorInt ) + " has stats? " );
572  //band name
573  myMetadata += "<p class=\"glossy\">\n";
574  myMetadata += tr( "Band" );
575  myMetadata += "</p>\n";
576  myMetadata += "<p>";
577  myMetadata += bandName( myIteratorInt );
578  myMetadata += "</p>\n";
579  //band number
580  myMetadata += "<p>";
581  myMetadata += tr( "Band No" );
582  myMetadata += "</p>\n";
583  myMetadata += "<p>\n";
584  myMetadata += QString::number( myIteratorInt );
585  myMetadata += "</p>\n";
586 
587  //check if full stats for this layer have already been collected
588  if ( !dataProvider()->hasStatistics( myIteratorInt ) ) //not collected
589  {
590  QgsDebugMsg( ".....no" );
591 
592  myMetadata += "<p>";
593  myMetadata += tr( "No Stats" );
594  myMetadata += "</p>\n";
595  myMetadata += "<p>\n";
596  myMetadata += tr( "No stats collected yet" );
597  myMetadata += "</p>\n";
598  }
599  else // collected - show full detail
600  {
601  QgsDebugMsg( ".....yes" );
602 
603  QgsRasterBandStats myRasterBandStats = dataProvider()->bandStatistics( myIteratorInt );
604  //Min Val
605  myMetadata += "<p>";
606  myMetadata += tr( "Min Val" );
607  myMetadata += "</p>\n";
608  myMetadata += "<p>\n";
609  myMetadata += QString::number( myRasterBandStats.minimumValue, 'f', 10 );
610  myMetadata += "</p>\n";
611 
612  // Max Val
613  myMetadata += "<p>";
614  myMetadata += tr( "Max Val" );
615  myMetadata += "</p>\n";
616  myMetadata += "<p>\n";
617  myMetadata += QString::number( myRasterBandStats.maximumValue, 'f', 10 );
618  myMetadata += "</p>\n";
619 
620  // Range
621  myMetadata += "<p>";
622  myMetadata += tr( "Range" );
623  myMetadata += "</p>\n";
624  myMetadata += "<p>\n";
625  myMetadata += QString::number( myRasterBandStats.range, 'f', 10 );
626  myMetadata += "</p>\n";
627 
628  // Mean
629  myMetadata += "<p>";
630  myMetadata += tr( "Mean" );
631  myMetadata += "</p>\n";
632  myMetadata += "<p>\n";
633  myMetadata += QString::number( myRasterBandStats.mean, 'f', 10 );
634  myMetadata += "</p>\n";
635 
636  //sum of squares
637  myMetadata += "<p>";
638  myMetadata += tr( "Sum of squares" );
639  myMetadata += "</p>\n";
640  myMetadata += "<p>\n";
641  myMetadata += QString::number( myRasterBandStats.sumOfSquares, 'f', 10 );
642  myMetadata += "</p>\n";
643 
644  //standard deviation
645  myMetadata += "<p>";
646  myMetadata += tr( "Standard Deviation" );
647  myMetadata += "</p>\n";
648  myMetadata += "<p>\n";
649  myMetadata += QString::number( myRasterBandStats.stdDev, 'f', 10 );
650  myMetadata += "</p>\n";
651 
652  //sum of all cells
653  myMetadata += "<p>";
654  myMetadata += tr( "Sum of all cells" );
655  myMetadata += "</p>\n";
656  myMetadata += "<p>\n";
657  myMetadata += QString::number( myRasterBandStats.sum, 'f', 10 );
658  myMetadata += "</p>\n";
659 
660  //number of cells
661  myMetadata += "<p>";
662  myMetadata += tr( "Cell Count" );
663  myMetadata += "</p>\n";
664  myMetadata += "<p>\n";
665  myMetadata += QString::number( myRasterBandStats.elementCount );
666  myMetadata += "</p>\n";
667  }
668  }
669 
670  QgsDebugMsg( myMetadata );
671  return myMetadata;
672 }
673 
678 QPixmap QgsRasterLayer::paletteAsPixmap( int theBandNumber )
679 {
680  //TODO: This function should take dimensions
681  QgsDebugMsg( "entered." );
682 
683  // Only do this for the GDAL provider?
684  // Maybe WMS can do this differently using QImage::numColors and QImage::color()
685  if ( mDataProvider->colorInterpretation( theBandNumber ) == QgsRaster::PaletteIndex )
686  {
687  QgsDebugMsg( "....found paletted image" );
688  QgsColorRampShader myShader;
689  QList<QgsColorRampShader::ColorRampItem> myColorRampItemList = mDataProvider->colorTable( theBandNumber );
690  if ( myColorRampItemList.size() > 0 )
691  {
692  QgsDebugMsg( "....got color ramp item list" );
693  myShader.setColorRampItemList( myColorRampItemList );
695  // Draw image
696  int mySize = 100;
697  QPixmap myPalettePixmap( mySize, mySize );
698  QPainter myQPainter( &myPalettePixmap );
699 
700  QImage myQImage = QImage( mySize, mySize, QImage::Format_RGB32 );
701  myQImage.fill( 0 );
702  myPalettePixmap.fill();
703 
704  double myStep = (( double )myColorRampItemList.size() - 1 ) / ( double )( mySize * mySize );
705  double myValue = 0.0;
706  for ( int myRow = 0; myRow < mySize; myRow++ )
707  {
708  QRgb* myLineBuffer = ( QRgb* )myQImage.scanLine( myRow );
709  for ( int myCol = 0; myCol < mySize; myCol++ )
710  {
711  myValue = myStep * ( double )( myCol + myRow * mySize );
712  int c1, c2, c3, c4;
713  myShader.shade( myValue, &c1, &c2, &c3, &c4 );
714  myLineBuffer[ myCol ] = qRgba( c1, c2, c3, c4 );
715  }
716  }
717 
718  myQPainter.drawImage( 0, 0, myQImage );
719  return myPalettePixmap;
720  }
721  QPixmap myNullPixmap;
722  return myNullPixmap;
723  }
724  else
725  {
726  //invalid layer was requested
727  QPixmap myNullPixmap;
728  return myNullPixmap;
729  }
730 }
731 
733 {
734  return mProviderKey;
735 }
736 
741 {
742 // We return one raster pixel per map unit pixel
743 // One raster pixel can have several raster units...
744 
745 // We can only use one of the mGeoTransform[], so go with the
746 // horisontal one.
747 
749  {
750  return mDataProvider->extent().width() / mDataProvider->xSize();
751  }
752  return 1;
753 }
754 
756 {
758  {
759  return mDataProvider->extent().height() / mDataProvider->ySize();
760  }
761  return 1;
762 }
763 
765 {
767 
769 
770  //Initialize the last view port structure, should really be a class
771  mLastViewPort.mWidth = 0;
773 }
774 
775 void QgsRasterLayer::setDataProvider( QString const & provider )
776 {
777  QgsDebugMsg( "Entered" );
778  mValid = false; // assume the layer is invalid until we determine otherwise
779 
780  mPipe.remove( mDataProvider ); // deletes if exists
781  mDataProvider = 0;
782 
783  // XXX should I check for and possibly delete any pre-existing providers?
784  // XXX How often will that scenario occur?
785 
786  mProviderKey = provider;
787  // set the layer name (uppercase first character)
788  if ( ! mLayerName.isEmpty() ) // XXX shouldn't this happen in parent?
789  {
791  }
792 
793  //mBandCount = 0;
794 
796  if ( !mDataProvider )
797  {
798  //QgsMessageLog::logMessage( tr( "Cannot instantiate the data provider" ), tr( "Raster" ) );
799  appendError( ERR( tr( "Cannot instantiate the '%1' data provider" ).arg( mProviderKey ) ) );
800  return;
801  }
802  QgsDebugMsg( "Data provider created" );
803 
804  // Set data provider into pipe even if not valid so that it is deleted with pipe (with layer)
806  if ( !mDataProvider->isValid() )
807  {
809  appendError( ERR( tr( "Provider is not valid (provider: %1, URI: %2" ).arg( mProviderKey ).arg( mDataSource ) ) );
810  return;
811  }
812 
813  if ( provider == "gdal" )
814  {
815  // make sure that the /vsigzip or /vsizip is added to uri, if applicable
817  }
818 
819  // get the extent
821 
822  // show the extent
823  QString s = mbr.toString();
824  QgsDebugMsg( "Extent of layer: " + s );
825  // store the extent
826  setExtent( mbr );
827 
828  // upper case the first letter of the layer name
829  QgsDebugMsg( "mLayerName: " + name() );
830 
831  // set up the raster drawing style
832  // Do not set any 'sensible' style here, the style is set later
833 
834  // Setup source CRS
836 
837  QString mySourceWkt = crs().toWkt();
838 
839  QgsDebugMsg( "using wkt:\n" + mySourceWkt );
840 
841  //defaults - Needs to be set after the Contrast list has been build
842  //Try to read the default contrast enhancement from the config file
843 
844  QSettings myQSettings;
845 
846  //decide what type of layer this is...
847  //TODO Change this to look at the color interp and palette interp to decide which type of layer it is
848  QgsDebugMsg( "bandCount = " + QString::number( mDataProvider->bandCount() ) );
849  QgsDebugMsg( "dataType = " + QString::number( mDataProvider->dataType( 1 ) ) );
850  if (( mDataProvider->bandCount() > 1 ) )
851  {
853  }
854  else if ( mDataProvider->dataType( 1 ) == QGis::ARGB32
856  {
858  }
860  {
862  }
864  {
866  }
867  else
868  {
870  }
871 
872  QgsDebugMsg( "mRasterType = " + QString::number( mRasterType ) );
873  if ( mRasterType == ColorLayer )
874  {
875  QgsDebugMsg( "Setting drawing style to SingleBandColorDataStyle " + QString::number( QgsRaster::SingleBandColorDataStyle ) );
877  }
879  {
881  }
883  {
885  // Load color table
886  QList<QgsColorRampShader::ColorRampItem> colorTable = mDataProvider->colorTable( 1 );
888  if ( r )
889  {
890  // TODO: this should go somewhere else
891  QgsRasterShader* shader = new QgsRasterShader();
892  QgsColorRampShader* colorRampShader = new QgsColorRampShader();
894  colorRampShader->setColorRampItemList( colorTable );
895  shader->setRasterShaderFunction( colorRampShader );
896  r->setShader( shader );
897  }
898  }
899  else if ( mRasterType == Multiband )
900  {
902  }
903  else //GrayOrUndefined
904  {
906  }
907 
908  // Auto set alpha band
909  for ( int bandNo = 1; bandNo <= mDataProvider->bandCount(); bandNo++ )
910  {
912  {
913  if ( mPipe.renderer() )
914  {
915  mPipe.renderer()->setAlphaBand( bandNo );
916  }
917  break;
918  }
919  }
920 
921  // brightness filter
923  mPipe.set( brightnessFilter );
924 
925  // hue/saturation filter
927  mPipe.set( hueSaturationFilter );
928 
929  //resampler (must be after renderer)
931  mPipe.set( resampleFilter );
932 
933  // projector (may be anywhere in pipe)
934  QgsRasterProjector * projector = new QgsRasterProjector;
935  mPipe.set( projector );
936 
937  // Set default identify format - use the richest format available
938  int capabilities = mDataProvider->capabilities();
940  if ( capabilities & QgsRasterInterface::IdentifyHtml )
941  {
942  // HTML is usually richest
943  identifyFormat = QgsRaster::IdentifyFormatHtml;
944  }
945  else if ( capabilities & QgsRasterInterface::IdentifyFeature )
946  {
947  identifyFormat = QgsRaster::IdentifyFormatFeature;
948  }
949  else if ( capabilities & QgsRasterInterface::IdentifyText )
950  {
951  identifyFormat = QgsRaster::IdentifyFormatText;
952  }
953  else if ( capabilities & QgsRasterInterface::IdentifyValue )
954  {
955  identifyFormat = QgsRaster::IdentifyFormatValue;
956  }
957  setCustomProperty( "identify/format", QgsRasterDataProvider::identifyFormatName( identifyFormat ) );
958 
959  // Store timestamp
960  // TODO move to provider
962 
963  // Connect provider signals
964  connect(
965  mDataProvider, SIGNAL( progress( int, double, QString ) ),
966  this, SLOT( onProgress( int, double, QString ) )
967  );
968 
969  // Do a passthrough for the status bar text
970  connect(
971  mDataProvider, SIGNAL( statusChanged( QString ) ),
972  this, SIGNAL( statusChanged( QString ) )
973  );
974 
975  //mark the layer as valid
976  mValid = true;
977 
978  QgsDebugMsg( "exiting." );
979 } // QgsRasterLayer::setDataProvider
980 
982 {
983  mValid = false;
985  mDataProvider = 0;
986 }
987 
988 void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, QgsRaster::ContrastEnhancementLimits theLimits, QgsRectangle theExtent, int theSampleSize, bool theGenerateLookupTableFlag )
989 {
990  QgsDebugMsg( QString( "theAlgorithm = %1 theLimits = %2 theExtent.isEmpty() = %3" ).arg( theAlgorithm ).arg( theLimits ).arg( theExtent.isEmpty() ) );
991  if ( !mPipe.renderer() || !mDataProvider )
992  {
993  return;
994  }
995 
996  QList<int> myBands;
997  QList<QgsContrastEnhancement*> myEnhancements;
998  QgsSingleBandGrayRenderer* myGrayRenderer = 0;
999  QgsMultiBandColorRenderer* myMultiBandRenderer = 0;
1000  QString rendererType = mPipe.renderer()->type();
1001  if ( rendererType == "singlebandgray" )
1002  {
1003  myGrayRenderer = dynamic_cast<QgsSingleBandGrayRenderer*>( mPipe.renderer() );
1004  if ( !myGrayRenderer ) return;
1005  myBands << myGrayRenderer->grayBand();
1006  }
1007  else if ( rendererType == "multibandcolor" )
1008  {
1009  myMultiBandRenderer = dynamic_cast<QgsMultiBandColorRenderer*>( mPipe.renderer() );
1010  if ( !myMultiBandRenderer ) return;
1011  myBands << myMultiBandRenderer->redBand() << myMultiBandRenderer->greenBand() << myMultiBandRenderer->blueBand();
1012  }
1013 
1014  foreach ( int myBand, myBands )
1015  {
1016  if ( myBand != -1 )
1017  {
1018  QGis::DataType myType = ( QGis::DataType )mDataProvider->dataType( myBand );
1019  QgsContrastEnhancement* myEnhancement = new QgsContrastEnhancement(( QGis::DataType )myType );
1020  myEnhancement->setContrastEnhancementAlgorithm( theAlgorithm, theGenerateLookupTableFlag );
1021 
1022  double myMin = std::numeric_limits<double>::quiet_NaN();
1023  double myMax = std::numeric_limits<double>::quiet_NaN();
1024 
1025  if ( theLimits == QgsRaster::ContrastEnhancementMinMax )
1026  {
1027  QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, theExtent, theSampleSize );
1028  myMin = myRasterBandStats.minimumValue;
1029  myMax = myRasterBandStats.maximumValue;
1030  }
1031  else if ( theLimits == QgsRaster::ContrastEnhancementStdDev )
1032  {
1033  double myStdDev = 1; // make optional?
1034  QgsRasterBandStats myRasterBandStats = mDataProvider->bandStatistics( myBand, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, theExtent, theSampleSize );
1035  myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
1036  myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );
1037  }
1038  else if ( theLimits == QgsRaster::ContrastEnhancementCumulativeCut )
1039  {
1040  QSettings mySettings;
1041  double myLower = mySettings.value( "/Raster/cumulativeCutLower", QString::number( CUMULATIVE_CUT_LOWER ) ).toDouble();
1042  double myUpper = mySettings.value( "/Raster/cumulativeCutUpper", QString::number( CUMULATIVE_CUT_UPPER ) ).toDouble();
1043  QgsDebugMsg( QString( "myLower = %1 myUpper = %2" ).arg( myLower ).arg( myUpper ) );
1044  mDataProvider->cumulativeCut( myBand, myLower, myUpper, myMin, myMax, theExtent, theSampleSize );
1045  }
1046 
1047  QgsDebugMsg( QString( "myBand = %1 myMin = %2 myMax = %3" ).arg( myBand ).arg( myMin ).arg( myMax ) );
1048  myEnhancement->setMinimumValue( myMin );
1049  myEnhancement->setMaximumValue( myMax );
1050  myEnhancements.append( myEnhancement );
1051  }
1052  else
1053  {
1054  myEnhancements.append( 0 );
1055  }
1056  }
1057 
1058  if ( rendererType == "singlebandgray" )
1059  {
1060  if ( myEnhancements.value( 0 ) ) myGrayRenderer->setContrastEnhancement( myEnhancements.value( 0 ) );
1061  }
1062  else if ( rendererType == "multibandcolor" )
1063  {
1064  if ( myEnhancements.value( 0 ) ) myMultiBandRenderer->setRedContrastEnhancement( myEnhancements.value( 0 ) );
1065  if ( myEnhancements.value( 1 ) ) myMultiBandRenderer->setGreenContrastEnhancement( myEnhancements.value( 1 ) );
1066  if ( myEnhancements.value( 2 ) ) myMultiBandRenderer->setBlueContrastEnhancement( myEnhancements.value( 2 ) );
1067  }
1068 }
1069 
1071 {
1072  QgsDebugMsg( "Entered" );
1073 
1074  QSettings mySettings;
1075 
1076  QString myKey;
1077  QString myDefault;
1078 
1079  // TODO: we should not test renderer class here, move it somehow to renderers
1080  if ( dynamic_cast<QgsSingleBandGrayRenderer*>( renderer() ) )
1081  {
1082  myKey = "singleBand";
1083  myDefault = "StretchToMinimumMaximum";
1084  }
1085  else if ( dynamic_cast<QgsMultiBandColorRenderer*>( renderer() ) )
1086  {
1087  if ( QgsRasterBlock::typeSize( dataProvider()->srcDataType( 1 ) ) == 1 )
1088  {
1089  myKey = "multiBandSingleByte";
1090  myDefault = "NoEnhancement";
1091  }
1092  else
1093  {
1094  myKey = "multiBandMultiByte";
1095  myDefault = "StretchToMinimumMaximum";
1096  }
1097  }
1098 
1099  if ( myKey.isEmpty() )
1100  {
1101  QgsDebugMsg( "No default contrast enhancement for this drawing style" );
1102  }
1103  QgsDebugMsg( "myKey = " + myKey );
1104 
1105  QString myAlgorithmString = mySettings.value( "/Raster/defaultContrastEnhancementAlgorithm/" + myKey, myDefault ).toString();
1106  QgsDebugMsg( "myAlgorithmString = " + myAlgorithmString );
1107 
1109 
1110  if ( myAlgorithm == QgsContrastEnhancement::NoEnhancement )
1111  {
1112  return;
1113  }
1114 
1115  QString myLimitsString = mySettings.value( "/Raster/defaultContrastEnhancementLimits", "CumulativeCut" ).toString();
1117 
1118  setContrastEnhancement( myAlgorithm, myLimits );
1119 }
1120 
1126 void QgsRasterLayer::setDrawingStyle( QString const & theDrawingStyleQString )
1127 {
1128  QgsDebugMsg( "DrawingStyle = " + theDrawingStyleQString );
1129  QgsRaster::DrawingStyle drawingStyle;
1130  if ( theDrawingStyleQString == "SingleBandGray" )//no need to tr() this its not shown in ui
1131  {
1132  drawingStyle = QgsRaster::SingleBandGray;
1133  }
1134  else if ( theDrawingStyleQString == "SingleBandPseudoColor" )//no need to tr() this its not shown in ui
1135  {
1136  drawingStyle = QgsRaster::SingleBandPseudoColor;
1137  }
1138  else if ( theDrawingStyleQString == "PalettedColor" )//no need to tr() this its not shown in ui
1139  {
1140  drawingStyle = QgsRaster::PalettedColor;
1141  }
1142  else if ( theDrawingStyleQString == "PalettedSingleBandGray" )//no need to tr() this its not shown in ui
1143  {
1144  drawingStyle = QgsRaster::PalettedSingleBandGray;
1145  }
1146  else if ( theDrawingStyleQString == "PalettedSingleBandPseudoColor" )//no need to tr() this its not shown in ui
1147  {
1149  }
1150  else if ( theDrawingStyleQString == "PalettedMultiBandColor" )//no need to tr() this its not shown in ui
1151  {
1152  drawingStyle = QgsRaster::PalettedMultiBandColor;
1153  }
1154  else if ( theDrawingStyleQString == "MultiBandSingleBandGray" )//no need to tr() this its not shown in ui
1155  {
1156  drawingStyle = QgsRaster::MultiBandSingleBandGray;
1157  }
1158  else if ( theDrawingStyleQString == "MultiBandSingleBandPseudoColor" )//no need to tr() this its not shown in ui
1159  {
1161  }
1162  else if ( theDrawingStyleQString == "MultiBandColor" )//no need to tr() this its not shown in ui
1163  {
1164  drawingStyle = QgsRaster::MultiBandColor;
1165  }
1166  else if ( theDrawingStyleQString == "SingleBandColorDataStyle" )//no need to tr() this its not shown in ui
1167  {
1168  QgsDebugMsg( "Setting drawingStyle to SingleBandColorDataStyle " + QString::number( QgsRaster::SingleBandColorDataStyle ) );
1169  drawingStyle = QgsRaster::SingleBandColorDataStyle;
1170  QgsDebugMsg( "Setted drawingStyle to " + QString::number( drawingStyle ) );
1171  }
1172  else
1173  {
1174  drawingStyle = QgsRaster::UndefinedDrawingStyle;
1175  }
1176  setRendererForDrawingStyle( drawingStyle );
1177 }
1178 
1179 void QgsRasterLayer::setLayerOrder( QStringList const & layers )
1180 {
1181  QgsDebugMsg( "entered." );
1182 
1183  if ( mDataProvider )
1184  {
1185  QgsDebugMsg( "About to mDataProvider->setLayerOrder(layers)." );
1186  mDataProvider->setLayerOrder( layers );
1187  }
1188 
1189 }
1190 
1191 void QgsRasterLayer::setSubLayerVisibility( QString name, bool vis )
1192 {
1193 
1194  if ( mDataProvider )
1195  {
1196  QgsDebugMsg( "About to mDataProvider->setSubLayerVisibility(name, vis)." );
1197  mDataProvider->setSubLayerVisibility( name, vis );
1198  }
1199 
1200 }
1201 
1203 {
1204  QgsDebugMsg( "Entered" );
1205  if ( !theRenderer ) { return; }
1206  mPipe.set( theRenderer );
1207  emit rendererChanged();
1208 }
1209 
1210 void QgsRasterLayer::showProgress( int theValue )
1211 {
1212  emit progressUpdate( theValue );
1213 }
1214 
1215 
1216 void QgsRasterLayer::showStatusMessage( QString const & theMessage )
1217 {
1218  // QgsDebugMsg(QString("entered with '%1'.").arg(theMessage));
1219 
1220  // Pass-through
1221  // TODO: See if we can connect signal-to-signal. This is a kludge according to the Qt doc.
1222  emit statusChanged( theMessage );
1223 }
1224 
1225 QStringList QgsRasterLayer::subLayers() const
1226 {
1227  return mDataProvider->subLayers();
1228 }
1229 
1230 QPixmap QgsRasterLayer::previewAsPixmap( QSize size, QColor bgColor )
1231 {
1232  QPixmap myQPixmap( size );
1233 
1234  myQPixmap.fill( bgColor ); //defaults to white, set to transparent for rendering on a map
1235 
1236  QgsRasterViewPort *myRasterViewPort = new QgsRasterViewPort();
1237 
1238  double myMapUnitsPerPixel;
1239  double myX = 0.0;
1240  double myY = 0.0;
1241  QgsRectangle myExtent = mDataProvider->extent();
1242  if ( myExtent.width() / myExtent.height() >= myQPixmap.width() / myQPixmap.height() )
1243  {
1244  myMapUnitsPerPixel = myExtent.width() / myQPixmap.width();
1245  myY = ( myQPixmap.height() - myExtent.height() / myMapUnitsPerPixel ) / 2;
1246  }
1247  else
1248  {
1249  myMapUnitsPerPixel = myExtent.height() / myQPixmap.height();
1250  myX = ( myQPixmap.width() - myExtent.width() / myMapUnitsPerPixel ) / 2;
1251  }
1252 
1253  double myPixelWidth = myExtent.width() / myMapUnitsPerPixel;
1254  double myPixelHeight = myExtent.height() / myMapUnitsPerPixel;
1255 
1256  myRasterViewPort->mTopLeftPoint = QgsPoint( myX, myY );
1257  myRasterViewPort->mBottomRightPoint = QgsPoint( myPixelWidth, myPixelHeight );
1258  myRasterViewPort->mWidth = myQPixmap.width();
1259  myRasterViewPort->mHeight = myQPixmap.height();
1260 
1261  myRasterViewPort->mDrawnExtent = myExtent;
1262  myRasterViewPort->mSrcCRS = QgsCoordinateReferenceSystem(); // will be invalid
1263  myRasterViewPort->mDestCRS = QgsCoordinateReferenceSystem(); // will be invalid
1264  myRasterViewPort->mSrcDatumTransform = -1;
1265  myRasterViewPort->mDestDatumTransform = -1;
1266 
1267  QgsMapToPixel *myMapToPixel = new QgsMapToPixel( myMapUnitsPerPixel );
1268 
1269  QPainter * myQPainter = new QPainter( &myQPixmap );
1270  draw( myQPainter, myRasterViewPort, myMapToPixel );
1271  delete myRasterViewPort;
1272  delete myMapToPixel;
1273  myQPainter->end();
1274  delete myQPainter;
1275 
1276  return myQPixmap;
1277 }
1278 
1280 {
1281  emit repaintRequested();
1282 }
1283 
1284 void QgsRasterLayer::updateProgress( int theProgress, int theMax )
1285 {
1286  //simply propogate it on!
1287  emit drawingProgress( theProgress, theMax );
1288 }
1289 
1290 void QgsRasterLayer::onProgress( int theType, double theProgress, QString theMessage )
1291 {
1292  Q_UNUSED( theType );
1293  Q_UNUSED( theMessage );
1294  QgsDebugMsg( QString( "theProgress = %1" ).arg( theProgress ) );
1295  emit progressUpdate(( int )theProgress );
1296 }
1297 
1299 //
1300 // Protected methods
1301 //
1303 /*
1304  * @param QDomNode node that will contain the symbology definition for this layer.
1305  * @param errorMessage reference to string that will be updated with any error messages
1306  * @return true in case of success.
1307  */
1308 bool QgsRasterLayer::readSymbology( const QDomNode& layer_node, QString& errorMessage )
1309 {
1310  Q_UNUSED( errorMessage );
1311  QDomElement rasterRendererElem;
1312 
1313  // pipe element was introduced in the end of 1.9 development when there were
1314  // already many project files in use so we support 1.9 backward compatibility
1315  // even it was never officialy released -> use pipe element if present, otherwise
1316  // use layer node
1317  QDomNode pipeNode = layer_node.firstChildElement( "pipe" );
1318  if ( pipeNode.isNull() ) // old project
1319  {
1320  pipeNode = layer_node;
1321  }
1322 
1323  //rasterlayerproperties element there -> old format (1.8 and early 1.9)
1324  if ( !layer_node.firstChildElement( "rasterproperties" ).isNull() )
1325  {
1326  //copy node because layer_node is const
1327  QDomNode layerNodeCopy = layer_node.cloneNode();
1328  QDomDocument doc = layerNodeCopy.ownerDocument();
1329  QDomElement rasterPropertiesElem = layerNodeCopy.firstChildElement( "rasterproperties" );
1330  QgsProjectFileTransform::convertRasterProperties( doc, layerNodeCopy, rasterPropertiesElem,
1331  this );
1332  rasterRendererElem = layerNodeCopy.firstChildElement( "rasterrenderer" );
1333  QgsDebugMsg( doc.toString() );
1334  }
1335  else
1336  {
1337  rasterRendererElem = pipeNode.firstChildElement( "rasterrenderer" );
1338  }
1339 
1340  if ( !rasterRendererElem.isNull() )
1341  {
1342  QString rendererType = rasterRendererElem.attribute( "type" );
1343  QgsRasterRendererRegistryEntry rendererEntry;
1344  if ( QgsRasterRendererRegistry::instance()->rendererData( rendererType, rendererEntry ) )
1345  {
1346  QgsRasterRenderer *renderer = rendererEntry.rendererCreateFunction( rasterRendererElem, dataProvider() );
1347  mPipe.set( renderer );
1348  }
1349  }
1350 
1351  //brightness
1353  mPipe.set( brightnessFilter );
1354 
1355  //brightness coefficient
1356  QDomElement brightnessElem = pipeNode.firstChildElement( "brightnesscontrast" );
1357  if ( !brightnessElem.isNull() )
1358  {
1359  brightnessFilter->readXML( brightnessElem );
1360  }
1361 
1362  //hue/saturation
1364  mPipe.set( hueSaturationFilter );
1365 
1366  //saturation coefficient
1367  QDomElement hueSaturationElem = pipeNode.firstChildElement( "huesaturation" );
1368  if ( !hueSaturationElem.isNull() )
1369  {
1370  hueSaturationFilter->readXML( hueSaturationElem );
1371  }
1372 
1373  //resampler
1375  mPipe.set( resampleFilter );
1376 
1377  //max oversampling
1378  QDomElement resampleElem = pipeNode.firstChildElement( "rasterresampler" );
1379  if ( !resampleElem.isNull() )
1380  {
1381  resampleFilter->readXML( resampleElem );
1382  }
1383 
1384  // get and set the blend mode if it exists
1385  QDomNode blendModeNode = layer_node.namedItem( "blendMode" );
1386  if ( !blendModeNode.isNull() )
1387  {
1388  QDomElement e = blendModeNode.toElement();
1390  }
1391 
1392  return true;
1393 } //readSymbology
1394 
1401 bool QgsRasterLayer::readXml( const QDomNode& layer_node )
1402 {
1403  QgsDebugMsg( "Entered" );
1405 
1406  //process provider key
1407  QDomNode pkeyNode = layer_node.namedItem( "provider" );
1408 
1409  if ( pkeyNode.isNull() )
1410  {
1411  mProviderKey = "gdal";
1412  }
1413  else
1414  {
1415  QDomElement pkeyElt = pkeyNode.toElement();
1416  mProviderKey = pkeyElt.text();
1417  if ( mProviderKey.isEmpty() )
1418  {
1419  mProviderKey = "gdal";
1420  }
1421  }
1422 
1423  // Open the raster source based on provider and datasource
1424 
1425  // Go down the raster-data-provider paradigm
1426 
1427  // Collect provider-specific information
1428 
1429  QDomNode rpNode = layer_node.namedItem( "rasterproperties" );
1430 
1431  if ( mProviderKey == "wms" )
1432  {
1433  // >>> BACKWARD COMPATIBILITY < 1.9
1434  // The old WMS URI format does not contain all the informations, we add them here.
1435  if ( !mDataSource.contains( "crs=" ) && !mDataSource.contains( "format=" ) )
1436  {
1437  QgsDebugMsg( "Old WMS URI format detected -> adding params" );
1438  QgsDataSourceURI uri;
1439  uri.setEncodedUri( mDataSource );
1440  QDomElement layerElement = rpNode.firstChildElement( "wmsSublayer" );
1441  while ( !layerElement.isNull() )
1442  {
1443  // TODO: sublayer visibility - post-0.8 release timeframe
1444 
1445  // collect name for the sublayer
1446  uri.setParam( "layers", layerElement.namedItem( "name" ).toElement().text() );
1447 
1448  // collect style for the sublayer
1449  uri.setParam( "styles", layerElement.namedItem( "style" ).toElement().text() );
1450 
1451  layerElement = layerElement.nextSiblingElement( "wmsSublayer" );
1452  }
1453 
1454  // Collect format
1455  QDomNode formatNode = rpNode.namedItem( "wmsFormat" );
1456  uri.setParam( "format", rpNode.namedItem( "wmsFormat" ).toElement().text() );
1457 
1458  // WMS CRS URL param should not be mixed with that assigned to the layer.
1459  // In the old WMS URI version there was no CRS and layer crs().authid() was used.
1460  uri.setParam( "crs", crs().authid() );
1461  mDataSource = uri.encodedUri();
1462  }
1463  // <<< BACKWARD COMPATIBILITY < 1.9
1464  }
1465 
1467  if ( !mValid ) return false;
1468 
1469  QString theError;
1470  bool res = readSymbology( layer_node, theError );
1471 
1472  // old wms settings we need to correct
1473  if ( res && mProviderKey == "wms" && ( !renderer() || renderer()->type() != "singlebandcolordata" ) )
1474  {
1476  }
1477 
1478  // Check timestamp
1479  // This was probably introduced to reload completely raster if data changed and
1480  // reset completly symbology to reflect new data type etc. It creates however
1481  // problems, because user defined symbology is complete lost if data file time
1482  // changed (the content may be the same). See also 6900.
1483 #if 0
1484  QDomNode stampNode = layer_node.namedItem( "timestamp" );
1485  if ( !stampNode.isNull() )
1486  {
1487  QDateTime stamp = QDateTime::fromString( stampNode.toElement().text(), Qt::ISODate );
1488  // TODO: very bad, we have to load twice!!! Make QgsDataProvider::timestamp() static?
1489  if ( stamp < mDataProvider->dataTimestamp() )
1490  {
1491  QgsDebugMsg( "data changed, reload provider" );
1493  init();
1495  if ( !mValid ) return false;
1496  }
1497  }
1498 #endif
1499 
1500  // Load user no data value
1501  QDomElement noDataElement = layer_node.firstChildElement( "noData" );
1502 
1503  QDomNodeList noDataBandList = noDataElement.elementsByTagName( "noDataList" );
1504 
1505  for ( int i = 0; i < noDataBandList.size(); ++i )
1506  {
1507  QDomElement bandElement = noDataBandList.at( i ).toElement();
1508  bool ok;
1509  int bandNo = bandElement.attribute( "bandNo" ).toInt( &ok );
1510  QgsDebugMsg( QString( "bandNo = %1" ).arg( bandNo ) );
1511  if ( ok && ( bandNo > 0 ) && ( bandNo <= mDataProvider->bandCount() ) )
1512  {
1513  mDataProvider->setUseSrcNoDataValue( bandNo, bandElement.attribute( "useSrcNoData" ).toInt() );
1514  QgsRasterRangeList myNoDataRangeList;
1515 
1516  QDomNodeList rangeList = bandElement.elementsByTagName( "noDataRange" );
1517 
1518  for ( int j = 0; j < rangeList.size(); ++j )
1519  {
1520  QDomElement rangeElement = rangeList.at( j ).toElement();
1521  QgsRasterRange myNoDataRange( rangeElement.attribute( "min" ).toDouble(),
1522  rangeElement.attribute( "max" ).toDouble() );
1523  QgsDebugMsg( QString( "min = %1 %2" ).arg( rangeElement.attribute( "min" ) ).arg( myNoDataRange.min() ) );
1524  myNoDataRangeList << myNoDataRange;
1525  }
1526  mDataProvider->setUserNoDataValue( bandNo, myNoDataRangeList );
1527  }
1528  }
1529 
1530  return res;
1531 } // QgsRasterLayer::readXml( QDomNode & layer_node )
1532 
1533 /*
1534  * @param QDomNode the node that will have the style element added to it.
1535  * @param QDomDocument the document that will have the QDomNode added.
1536  * @param errorMessage reference to string that will be updated with any error messages
1537  * @return true in case of success.
1538  */
1539 bool QgsRasterLayer::writeSymbology( QDomNode & layer_node, QDomDocument & document, QString& errorMessage ) const
1540 {
1541  Q_UNUSED( errorMessage );
1542  QDomElement layerElem = layer_node.toElement();
1543 
1544  // Store pipe members (except provider) into pipe element, in future, it will be
1545  // possible to add custom filters into the pipe
1546  QDomElement pipeElement = document.createElement( "pipe" );
1547 
1548  for ( int i = 1; i < mPipe.size(); i++ )
1549  {
1550  QgsRasterInterface * interface = mPipe.at( i );
1551  if ( !interface ) continue;
1552  interface->writeXML( document, pipeElement );
1553  }
1554 
1555  layer_node.appendChild( pipeElement );
1556 
1557  // add blend mode node
1558  QDomElement blendModeElement = document.createElement( "blendMode" );
1559  QDomText blendModeText = document.createTextNode( QString::number( QgsMapRenderer::getBlendModeEnum( blendMode() ) ) );
1560  blendModeElement.appendChild( blendModeText );
1561  layer_node.appendChild( blendModeElement );
1562 
1563  return true;
1564 } // bool QgsRasterLayer::writeSymbology
1565 
1566 /*
1567  * virtual
1568  * @note Called by QgsMapLayer::writeXML().
1569  */
1570 bool QgsRasterLayer::writeXml( QDomNode & layer_node,
1571  QDomDocument & document )
1572 {
1573  // first get the layer element so that we can append the type attribute
1574 
1575  QDomElement mapLayerNode = layer_node.toElement();
1576 
1577  if ( mapLayerNode.isNull() || "maplayer" != mapLayerNode.nodeName() )
1578  {
1579  QgsMessageLog::logMessage( tr( "<maplayer> not found." ), tr( "Raster" ) );
1580  return false;
1581  }
1582 
1583  mapLayerNode.setAttribute( "type", "raster" );
1584 
1585  // add provider node
1586 
1587  QDomElement provider = document.createElement( "provider" );
1588  QDomText providerText = document.createTextNode( mProviderKey );
1589  provider.appendChild( providerText );
1590  layer_node.appendChild( provider );
1591 
1592  // User no data
1593  QDomElement noData = document.createElement( "noData" );
1594 
1595  for ( int bandNo = 1; bandNo <= mDataProvider->bandCount(); bandNo++ )
1596  {
1597  if ( mDataProvider->userNoDataValues( bandNo ).isEmpty() ) continue;
1598 
1599  QDomElement noDataRangeList = document.createElement( "noDataList" );
1600  noDataRangeList.setAttribute( "bandNo", bandNo );
1601  noDataRangeList.setAttribute( "useSrcNoData", mDataProvider->useSrcNoDataValue( bandNo ) );
1602 
1603  foreach ( QgsRasterRange range, mDataProvider->userNoDataValues( bandNo ) )
1604  {
1605  QDomElement noDataRange = document.createElement( "noDataRange" );
1606 
1607  noDataRange.setAttribute( "min", range.min() );
1608  noDataRange.setAttribute( "max", range.max() );
1609  noDataRangeList.appendChild( noDataRange );
1610  }
1611 
1612  noData.appendChild( noDataRangeList );
1613 
1614  }
1615  if ( noData.hasChildNodes() )
1616  {
1617  layer_node.appendChild( noData );
1618  }
1619 
1620  //write out the symbology
1621  QString errorMsg;
1622  return writeSymbology( layer_node, document, errorMsg );
1623 }
1624 
1626 {
1627  if ( !mDataProvider ) return 0;
1628  return mDataProvider->xSize();
1629 }
1630 
1632 {
1633  if ( !mDataProvider ) return 0;
1634  return mDataProvider->ySize();
1635 }
1636 
1638 //
1639 // Private methods
1640 //
1643 {
1644  QgsDebugMsg( "entered." );
1645  // Check if data changed
1647  {
1648  QgsDebugMsg( "reload data" );
1650  init();
1652  emit dataChanged();
1653  }
1654  return mValid;
1655 }
QgsDataProvider * classFactoryFunction_t(const QString *)
static void convertRasterProperties(QDomDocument &doc, QDomNode &parentNode, QDomElement &rasterPropertiesElem, QgsRasterLayer *rlayer)
virtual int bandCount() const =0
Get number of bands.
virtual void setSubLayerVisibility(const QString &name, bool vis)
Set the visibility of the given sublayer name.
void setRenderer(QgsRasterRenderer *theRenderer)
Set raster renderer.
#define ERR(message)
void setContrastEnhancementAlgorithm(ContrastEnhancementAlgorithm, bool generateTable=true)
Set the contrast enhancement algorithm.
virtual QStringList subLayers() const
Returns the sublayers of this layer - useful for providers that manage their own layers, such as WMS.
IdentifyFormat
Definition: qgsraster.h:54
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:45
Interface for all raster shaders.
bool isEmpty() const
test if rectangle is empty
double rasterUnitsPerPixelY()
QgsMapLayer::LayerType type() const
Get the type of the layer.
Definition: qgsmaplayer.cpp:88
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
double sum
The sum of all cells in the band.
void setCRS(const QgsCoordinateReferenceSystem &theSrcCRS, const QgsCoordinateReferenceSystem &theDestCRS, int srcDatumTransform=-1, int destDatumTransform=-1)
set source and destination CRS
Iterator for sequentially processing raster cells.
void rendererChanged()
Signal emitted when the symbology changes, through call to setRenderer()
DrawingStyle
This enumerator describes the different kinds of drawing we can do.
Definition: qgsraster.h:95
A ramp shader will color a raster pixel based on a list of values ranges in a ramp.
static QgsProviderRegistry * instance(QString pluginPath=QString::null)
means of accessing canonical single instance
QString lastErrorTitle()
[ data provider interface ] If an operation returns 0 (e.g.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:189
void setEncodedUri(const QByteArray &uri)
set complete encoded uri (generic mode)
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
virtual QgsCoordinateReferenceSystem crs()=0
static ContrastEnhancementLimits contrastEnhancementLimitsFromString(QString theLimits)
Definition: qgsraster.cpp:39
void setDefaultContrastEnhancement()
Set default contrast enhancement.
void triggerRepaint()
Emit a signal asking for a repaint.
virtual void setUseSrcNoDataValue(int bandNo, bool use)
Set source nodata value usage.
virtual double srcNoDataValue(int bandNo) const
Value representing no data value.
QgsPoint transform(const QgsPoint &p) const
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
virtual void setLayerOrder(const QStringList &layers)
Reorders the previously selected sublayers of this layer from bottom to top.
void drawingProgress(int theProgress, int theTotalSteps)
Emit a signal to notify of a progress event.
double maximumValue
The maximum cell value in the raster band.
int mWidth
Width, number of columns to be rendered.
QgsRasterInterface * last() const
Definition: qgsrasterpipe.h:86
virtual QgsRasterRangeList userNoDataValues(int bandNo) const
Get list of user no data value ranges.
static QDateTime lastModified(const QString &name)
Return time stamp for given file name.
Raster values range container.
const QgsRectangle & extent() const
static bool isValidRasterFileName(const QString &theFileNameQString, QString &retError)
This helper checks to see whether the file name appears to be a valid raster file name...
Resample filter pipe for rasters.
Abstract base class for spatial data provider implementations.
void setColorRampItemList(const QList< QgsColorRampShader::ColorRampItem > &theList)
Set custom colormap.
void readXML(const QDomElement &filterElem)
Sets base class members from xml.
bool draw(QgsRenderContext &rendererContext)
This is called when the view on the raster layer needs to be redrawn.
static const double SAMPLE_SIZE
Default sample size (number of pixels) for estimated statistics/histogram calculation.
double scaleFactor() const
void updateProgress(int, int)
Propagate progress updates from GDAL up to the parent app.
const QgsCoordinateTransform * coordinateTransform() const
void readXML(const QDomElement &filterElem)
Sets base class members from xml.
QString mError
[ data provider interface ]The error message associated with the last error
void setBlendMode(const QPainter::CompositionMode &blendMode)
Write blend mode for layer.
QString mLayerName
Name of the layer - used for display.
Definition: qgsmaplayer.h:483
void setShader(QgsRasterShader *shader)
Takes ownership of the shader.
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer...
double rasterUnitsPerPixelX()
Returns the number of raster units per each raster pixel.
virtual int ySize() const
void setGreenContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
static QString identifyFormatName(QgsRaster::IdentifyFormat format)
virtual QDateTime dataTimestamp() const
Current time stamp of data source.
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
int size() const
Definition: qgsrasterpipe.h:84
QgsCoordinateReferenceSystem mDestCRS
Target coordinate system.
void setDrawingStyle(const QString &theDrawingStyleQString)
Overloaded version of the above function for convenience when restoring from xml. ...
void setRendererForDrawingStyle(const QgsRaster::DrawingStyle &theDrawingStyle)
Sets corresponding renderer for style.
void set(const QgsPoint &p1, const QgsPoint &p2)
Set the rectangle from two QgsPoints.
void init()
Initialize default values.
virtual bool useSrcNoDataValue(int bandNo) const
Get source nodata value usage.
const QString & name() const
Get the display name of the layer.
void onProgress(int, double, QString)
receive progress signal from provider
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:33
virtual QgsRasterBandStats bandStatistics(int theBandNo, int theStats=QgsRasterBandStats::All, const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0)
Get band statistics.
The drawing pipe for raster layers.
bool readXml(const QDomNode &layer_node)
Reads layer specific state from project file Dom node.
double stdDev
The standard deviation of the cell values.
virtual QStringList subLayers() const
Returns the sublayers of this layer - Useful for providers that manage their own layers, such as WMS.
The RasterBandStats struct is a container for statistics about a single raster band.
static QgsRasterRendererRegistry * instance()
void setError(const QgsError &theError)
Set error message.
Definition: qgsmaplayer.h:471
double mean
The mean cell value for the band.
int height() const
Accessor that returns the height of the (unclipped) raster.
QPainter::CompositionMode blendMode() const
Read blend mode for layer.
void readXML(const QDomElement &filterElem)
Sets base class members from xml.
void setRedContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:194
QgsRasterRenderer * renderer() const
virtual void setUserNoDataValue(int bandNo, QgsRasterRangeList noData)
int bandCount() const
Get the number of bands in this layer.
QgsDataProvider * provider(const QString &providerKey, const QString &dataSource)
Create an instance of the provider.
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:179
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:37
void setParam(const QString &key, const QString &value)
Set generic param (generic mode)
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
QgsRasterViewPort mLastViewPort
virtual QGis::DataType srcDataType(int bandNo) const =0
Returns source data type for the band specified by number, source data type may be shorter than dataT...
virtual QgsRectangle extent()=0
Get the extent of the data source.
void statusChanged(QString theStatus)
Emit a signal with status (e.g.
virtual void setExtent(const QgsRectangle &rect)
Set the extent.
bool readSymbology(const QDomNode &node, QString &errorMessage)
Read the symbology for the current layer from the Dom node supplied.
static const double CUMULATIVE_CUT_UPPER
Default cumulative cut upper limit.
~QgsRasterLayer()
The destructor.
ContrastEnhancementLimits
Contrast enhancement limits.
Definition: qgsraster.h:86
qgssize elementCount
The number of not no data cells in the band.
void setMinimumValue(double, bool generateTable=true)
Return the minimum value for the contrast enhancement range.
Raster renderer pipe for single band pseudocolor.
void dataChanged()
This is emitted whenever data or metadata (e.g.
virtual QGis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
const QString bandName(int theBandNoInt)
Get the name of a band given its number.
double rasterScaleFactor() const
bool isvalidrasterfilename_t(QString const &theFileNameQString, QString &retErrMsg)
double min() const
Raster renderer pipe for single band gray.
virtual QString generateBandName(int theBandNumber) const
helper function to create zero padded band names
QgsRasterResampleFilter * resampleFilter() const
Set raster resample filter.
double mapUnitsPerPixel() const
Return current map units per pixel.
static int typeSize(int dataType)
virtual void setLayerOrder(const QStringList &layers)
Reorder the list of layer names to be rendered by this provider (in order from bottom to top) ...
QgsRasterProjector * projector() const
QString lastError()
[ data provider interface ] If an operation returns 0 (e.g.
void setAlphaBand(int band)
bool mValid
Indicates if the layer is valid and can be drawn.
Definition: qgsmaplayer.h:477
void setContrastEnhancement(QgsContrastEnhancement::ContrastEnhancementAlgorithm theAlgorithm, QgsRaster::ContrastEnhancementLimits theLimits=QgsRaster::ContrastEnhancementMinMax, QgsRectangle theExtent=QgsRectangle(), int theSampleSize=SAMPLE_SIZE, bool theGenerateLookupTableFlag=true)
Set contrast enhancement algorithm.
void setDataProvider(const QString &provider)
[ data provider interface ] Set the data provider
QgsRasterDataProvider * mDataProvider
Pointer to data provider.
void setRasterShaderFunction(QgsRasterShaderFunction *)
A public method that allows the user to set their own shader function.
Base class for processing filters like renderers, reprojector, resampler etc.
A class to represent a point geometry.
Definition: qgspoint.h:63
void setColorRampType(QgsColorRampShader::ColorRamp_TYPE theColorRampType)
Set the color ramp type.
QPixmap previewAsPixmap(QSize size, QColor bgColor=Qt::white)
Draws a preview of the rasterlayer into a pixmap.
Class for storing the component parts of a PostgreSQL/RDBMS datasource URI.
QPixmap paletteAsPixmap(int theBandNumber=1)
Get an 100x100 pixmap of the color palette.
bool shade(double, int *, int *, int *, int *)
Generates and new RGB value based on one input value.
void setX(double x)
Definition: qgspoint.h:87
static ContrastEnhancementAlgorithm contrastEnhancementAlgorithmFromString(const QString &contrastEnhancementString)
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
virtual int colorInterpretation(int theBandNo) const
Returns data type for the band specified by number.
QgsCoordinateReferenceSystem mSrcCRS
Source coordinate system.
QgsPoint toMapCoordinatesF(double x, double y) const
void progressUpdate(int theValue)
Signal for notifying listeners of long running processes.
static QPainter::CompositionMode getCompositionMode(const QgsMapRenderer::BlendMode &blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode Added in 1.9.
void showProgress(int theValue)
[ data provider interface ] A wrapper function to emit a progress update signal
Registry for raster renderer entries.
bool writeSymbology(QDomNode &, QDomDocument &doc, QString &errorMessage) const
Write the symbology for the layer into the docment provided.
LayerType mRasterType
QgsPoint mBottomRightPoint
Coordinate (in output device coordinate system) of bottom right corner of the part of the raster that...
void setContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
QString metadata()
Obtain GDAL Metadata for this layer.
ContrastEnhancementAlgorithm
This enumerator describes the types of contrast enhancement algorithms that can be used...
QString what() const
Definition: qgsexception.h:35
QString mProviderKey
[ data provider interface ] Data provider key
Contains information about the context of a rendering operation.
virtual void legendSymbologyItems(QList< QPair< QString, QColor > > &symbolItems) const
Get symbology items if provided by renderer.
QgsRectangle transformBoundingBox(const QgsRectangle theRect, TransformDirection direction=ForwardTransform) const
QPainter * painter()
QDateTime mLastModified
[ data provider interface ] Timestamp, the last modified time of the data source when the layer was c...
bool remove(int idx)
Remove and delete interface at given index if possible.
QList< QgsRasterRange > QgsRasterRangeList
virtual int xSize() const
Get raster size.
QString mDataSource
data source description string, varies by layer type
Definition: qgsmaplayer.h:480
virtual QString loadDefaultStyle(bool &theResultFlag)
Retrieve the default style for this layer if one exists (either as a .qml file on disk or as a record...
virtual QDateTime timestamp() const
Time stamp of data source in the moment when data/metadata were loaded by provider.
virtual QString type() const
virtual QString metadata()=0
Get metadata in a format suitable for feeding directly into a subset of the GUI raster properties "Me...
virtual void reloadData()
Reloads the data from the source.
QgsRectangle intersect(const QgsRectangle *rect) const
return the intersection with the given rectangle
virtual bool isValid()=0
Returns true if this is a valid layer.
void repaintRequested()
This signal should be connected with the slot QgsMapCanvas::refresh()
int mHeight
Distance in map units from bottom edge to top edge for the part of the raster that is to be rendered...
bool update()
Update the layer if it is outdated.
Brightness/contrast filter pipe for rasters.
Class for storing a coordinate reference system (CRS)
Color and saturation filter pipe for rasters.
static const double CUMULATIVE_CUT_LOWER
Default cumulative cut lower limit.
DataType
Raster data types.
Definition: qgis.h:204
virtual QString description() const =0
return description
double range
The range is the distance between min & max.
void setBlueContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
void closeDataProvider()
Close data provider and clear related members.
QgsHueSaturationFilter * hueSaturationFilter() const
double minimumValue
The minimum cell value in the raster band.
const QgsMapToPixel & mapToPixel() const
Renderer for multiband images with the color components.
void setLayerName(const QString &name)
Set the display name of the layer.
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
void * function(const QString &providerKey, const QString &functionName)
Get pointer to provider function.
void appendError(const QgsErrorMessage &theMessage)
Add error message.
Definition: qgsmaplayer.h:469
Manipulates raster pixel values so that they enhanceContrast or clip into a specified numerical range...
double max() const
QByteArray encodedUri() const
return complete encoded uri (generic mode)
void(*)() cast_to_fptr(void *p)
Definition: qgis.h:282
QgsRasterDataProvider * dataProvider()
Returns the data provider.
static QgsMapRenderer::BlendMode getBlendModeEnum(const QPainter::CompositionMode &blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode Added in 1.9.
virtual void setSubLayerVisibility(QString name, bool vis)
Set the visibility of the given sublayer name.
Custom exception class for Coordinate Reference System related exceptions.
QString providerType() const
[ data provider interface ] Which provider is being used for this Raster Layer?
QgsPoint mTopLeftPoint
Coordinate (in output device coordinate system) of top left corner of the part of the raster that is ...
virtual bool srcHasNoDataValue(int bandNo) const
This class provides details of the viewable area that a raster will be rendered into.
QString mErrorCaption
[ data provider interface ] The error caption associated with the last error
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:199
virtual void cumulativeCut(int theBandNo, double theLowerCount, double theUpperCount, double &theLowerValue, double &theUpperValue, const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0)
Find values for cumulative pixel count cut.
virtual QList< QgsColorRampShader::ColorRampItem > colorTable(int bandNo) const
const QgsCoordinateReferenceSystem & destCRS() const
virtual QgsRectangle extent()
Return the extent of the layer.
double size
Definition: qgssvgcache.cpp:77
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
QgsRasterRenderer * renderer() const
QgsRasterPipe mPipe
bool set(QgsRasterInterface *theInterface)
Insert a new known interface in default place or replace interface of the same role if it already exi...
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:184
virtual QgsError error() const
Get current status error.
QList< QPair< QString, QColor > > legendSymbologyItems() const
Returns a list with classification items (Text and color)
Raster renderer pipe that applies colors to a raster.
QgsRasterRendererCreateFunc rendererCreateFunction
void setDpi(int dpi)
Sets the output device resolution.
virtual QString dataSourceUri() const
Get the data source specification.
void setMaximumValue(double, bool generateTable=true)
Set the maximum value for the contrast enhancement range.
void showStatusMessage(const QString &theMessage)
bool writeXml(QDomNode &layer_node, QDomDocument &doc)
Write layer specific state to project file Dom node.
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:204
QgsBrightnessContrastFilter * brightnessFilter() const
QgsRectangle mDrawnExtent
Intersection of current map extent and layer extent.
QString toProj4() const
Get the Proj Proj4 string representation of this srs.
virtual void reload()
Synchronises with changes in the datasource.
Base class for raster data providers.
int width() const
Accessor that returns the width of the (unclipped) raster.
double sumOfSquares
The sum of the squares.
#define tr(sourceText)
QgsRasterLayer()
Constructor.