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