Skip to content

Commit 1c94672

Browse files
committedAug 4, 2011
Regenerated docs post raster-stats merge
1 parent 58c737d commit 1c94672

17 files changed

+580
-311
lines changed
 

‎CODING

Lines changed: 166 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,14 @@ Developers guide for QGIS
5858
3.4. The ADD_QGIS_TEST macro explained
5959
3.5. Building your unit test
6060
3.6. Run your tests
61-
4. HIG (Human Interface Guidelines)
62-
5. Authors
61+
4. Getting up and running with QtCreator and QGIS
62+
4.1. Installing QtCreator
63+
4.2. Setting up your project
64+
4.3. Setting up your build environment
65+
4.4. Setting your run environment
66+
4.5. Running and debugging
67+
5. HIG (Human Interface Guidelines)
68+
6. Authors
6369

6470

6571
------------------------------------------------------------------------
@@ -1208,7 +1214,163 @@ works in a truly platform way. I will update this document as things
12081214
progress.
12091215

12101216

1211-
4. HIG (Human Interface Guidelines)
1217+
4. Getting up and running with QtCreator and QGIS
1218+
=================================================
1219+
1220+
QtCreator is a newish IDE from the makers of the Qt library. With QtCreator you
1221+
can build any C++ project, but it's really optimised for people working on
1222+
Qt(4) based applications (including mobile apps). Everything I describe below
1223+
assumes you are running Ubuntu 11.04 'Natty'.
1224+
1225+
1226+
4.1. Installing QtCreator
1227+
=========================
1228+
1229+
This part is easy:
1230+
1231+
sudo apt-get install qtcreator qtcreator-doc
1232+
1233+
After installing you should find it in your gnome menu.
1234+
1235+
1236+
4.2. Setting up your project
1237+
============================
1238+
1239+
I'm assuming you have already got a local Quantum-GIS clone containing the
1240+
source code, and have installed all needed build dependencies etc. There are
1241+
detailed in instructions on doing that here:
1242+
1243+
http://github.com/qgis/Quantum-GIS/blob/master/CODING
1244+
1245+
On my system I have checked out the code into $HOME/dev/cpp/Quantum-GIS and the
1246+
rest of the article is written assuming that, you should update these paths as
1247+
appropriate for your local system.
1248+
1249+
On launching QtCreator do:
1250+
1251+
File->Open File or Project
1252+
1253+
Then use the resulting file selection dialog to browse to and open this file:
1254+
1255+
$HOME/dev/cpp/Quantum-GIS/CMakeLists.txt
1256+
1257+
[images/image01.jpeg]
1258+
1259+
Next you will be prompted for a build location. I create a specific build dir
1260+
for QtCreator to work in under:
1261+
1262+
$HOME/dev/cpp/Quantum-GIS/build-master-qtcreator
1263+
1264+
Its probably a good idea to create separate build directories for different
1265+
branches if you can afford the disk space.
1266+
1267+
[images/image02.jpeg]
1268+
1269+
Next you will be asked if you have any CMake build options to pass to CMake. We
1270+
will tell CMake that we want a debug build by adding this option:
1271+
1272+
-DCMAKE_BUILD_TYPE=Debug
1273+
1274+
[images/image03.jpeg]
1275+
1276+
Thats the basics of it. When you complete the Wizard, QtCreator will start
1277+
scanning the source tree for autocompletion support and do some other
1278+
housekeeping stuff in the background. We want to tweak a few things before we
1279+
start to build though.
1280+
1281+
1282+
4.3. Setting up your build environment
1283+
======================================
1284+
1285+
Click on the 'Projects' icon on the left of the QtCreator window.
1286+
1287+
[images/image04.jpeg]
1288+
1289+
Select the build settings tab (normally active by default).
1290+
1291+
[images/image05.jpeg]
1292+
1293+
We now want to add a custom process step. Why? Because QGIS can currently only
1294+
run from an install directory, not its build directory, so we need to ensure
1295+
that it is installed whenever we build it. Under 'Build Steps', click on the
1296+
'Add Build Step' combo button and choose 'Custom Process Step'.
1297+
1298+
[images/image06.jpeg]
1299+
1300+
Now we set the following details:
1301+
1302+
Enable custom process step [yes]
1303+
Command: make
1304+
Working directory: $HOME/dev/cpp/Quantum-GIS/build-master-qtcreator
1305+
Command arguments: install
1306+
1307+
[images/image07.jpeg]
1308+
1309+
You are almost ready to build. Just one note: QtCreator will need write
1310+
permissions on the install prefix. By default (which I am using here) QGIS is
1311+
going to get installed to /usr/local. For my purposes on my development
1312+
machine, I just gave myself write permissions to the /usr/local directory.
1313+
1314+
To start the build, click that big hammer icon on the bottom left of the
1315+
window.
1316+
1317+
[images/image08.jpeg]
1318+
1319+
1320+
4.4. Setting your run environment
1321+
=================================
1322+
1323+
As mentioned above, we cannot run QGIS from directly in the build directly, so
1324+
we need to create a custom run target to tell QtCreator to run QGIS from the
1325+
install dir (in my case /usr/local/). To do that, return to the projects
1326+
configuration screen.
1327+
1328+
[images/image04.jpeg]
1329+
1330+
Now select the 'Run Settings' tab
1331+
1332+
[images/image09.jpeg]
1333+
1334+
We need to update the default run settings from using the 'qgis' run
1335+
configuration to using a custom one.
1336+
1337+
[images/image10.jpeg]
1338+
1339+
Do do that, click the 'Add v' combo button next to the Run configuration
1340+
combo and choose 'Custom Executable' from the top of the list.
1341+
1342+
[images/image11.jpeg]
1343+
1344+
Now in the properties area set the following details:
1345+
1346+
Executable: /usr/local/bin/qgis
1347+
Arguments :
1348+
Working directory: $HOME
1349+
Run in terminal: [no]
1350+
Debugger: C++ [yes]
1351+
Qml [no]
1352+
1353+
Then click the 'Rename' button and give your custom executable a meaning full
1354+
name e.g. 'Installed QGIS'
1355+
1356+
[images/image12.jpeg]
1357+
1358+
1359+
4.5. Running and debugging
1360+
==========================
1361+
1362+
Now you are ready to run and debug QGIS. To set a break point, simply open a
1363+
source file and click in the left column.
1364+
1365+
[images/image14.jpeg]
1366+
1367+
Now launch QGIS under the debugger by clicking the icon with a bug on it in the
1368+
bottom left of the window.
1369+
1370+
[images/image13.jpeg]
1371+
1372+
1373+
5. HIG (Human Interface Guidelines)
12121374
===================================
12131375

12141376
In order for all graphical user interface elements to appear consistant and to
@@ -1257,7 +1419,7 @@ guidelines are followed in layout and design of GUIs.
12571419
suffixed to the button text.
12581420

12591421

1260-
5. Authors
1422+
6. Authors
12611423
==========
12621424

12631425
- Tim Sutton (author and editor)

‎INSTALL

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
Quantum GIS (QGIS)
22
Building QGIS from source - step by step
3-
Sunday June 12, 2011
3+
Thursday August 04, 2011
44

55

6-
Last Updated: Sunday June 12, 2011
7-
Last Change : Sunday June 05, 2011
6+
Last Updated: Thursday August 04, 2011
7+
Last Change : Tuesday June 28, 2011
88

99

1010
1. Introduction

‎doc/INSTALL.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@
4545
<DIV CLASS="header" ID="header">
4646
<H1>Quantum GIS (QGIS)</H1>
4747
<H2>Building QGIS from source - step by step</H2>
48-
<H3>Sunday June 12, 2011</H3>
48+
<H3>Thursday August 04, 2011</H3>
4949
</DIV>
5050

5151
<DIV CLASS="body" ID="body">
5252
<P>
53-
Last Updated: Sunday June 12, 2011
54-
Last Change : Sunday June 05, 2011
53+
Last Updated: Thursday August 04, 2011
54+
Last Change : Tuesday June 28, 2011
5555
</P>
5656
<DIV CLASS="toc">
5757

‎src/app/qgsrasterlayerproperties.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1882,7 +1882,7 @@ void QgsRasterLayerProperties::refreshHistogram()
18821882
// bin in all selected layers, and the min. It then draws a scaled line between min
18831883
// and max - scaled to image height. 1 line drawn per selected band
18841884
//
1885-
const int BINCOUNT = 255;
1885+
const int BINCOUNT = 256;
18861886
bool myIgnoreOutOfRangeFlag = true;
18871887
bool myThoroughBandScanFlag = false;
18881888
int myBandCountInt = mRasterLayer->bandCount();

‎src/core/qgsapplication.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ QString QgsApplication::mBuildOutputPath;
6464
*/
6565
QgsApplication::QgsApplication( int & argc, char ** argv, bool GUIenabled, QString customConfigPath )
6666
: QApplication( argc, argv, GUIenabled )
67+
{
68+
init( customConfigPath ); //initi can also be called directly by e.g. unit tests that dont inherit QApplication.
69+
}
70+
void QgsApplication::init( QString customConfigPath )
6771
{
6872
// check if QGIS is run from build directory (not the install directory)
6973
QDir appDir( applicationDirPath() );

‎src/core/qgsapplication.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class CORE_EXPORT QgsApplication: public QApplication
3232
QgsApplication( int & argc, char ** argv, bool GUIenabled, QString customConfigPath = QString() );
3333
virtual ~QgsApplication();
3434

35+
/** This method initialises paths etc for QGIS. Called by the ctor or call it manually
36+
when your app does not extend the QApplication class. */
37+
static void init( QString customConfigPath = QString() );
38+
3539
//! Watch for QFileOpenEvent.
3640
virtual bool event( QEvent * event );
3741

‎src/core/qgsrasterdataprovider.cpp

Lines changed: 191 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,31 +201,31 @@ QByteArray QgsRasterDataProvider::noValueBytes( int theBandNo )
201201
double d;
202202
switch ( type )
203203
{
204-
case QgsRasterDataProvider::Byte:
204+
case Byte:
205205
uc = ( unsigned char )noval;
206206
memcpy( data, &uc, size );
207207
break;
208-
case QgsRasterDataProvider::UInt16:
208+
case UInt16:
209209
us = ( unsigned short )noval;
210210
memcpy( data, &us, size );
211211
break;
212-
case QgsRasterDataProvider::Int16:
212+
case Int16:
213213
s = ( short )noval;
214214
memcpy( data, &s, size );
215215
break;
216-
case QgsRasterDataProvider::UInt32:
216+
case UInt32:
217217
ui = ( unsigned int )noval;
218218
memcpy( data, &ui, size );
219219
break;
220-
case QgsRasterDataProvider::Int32:
220+
case Int32:
221221
i = ( int )noval;
222222
memcpy( data, &i, size );
223223
break;
224-
case QgsRasterDataProvider::Float32:
224+
case Float32:
225225
f = ( float )noval;
226226
memcpy( data, &f, size );
227227
break;
228-
case QgsRasterDataProvider::Float64:
228+
case Float64:
229229
d = ( double )noval;
230230
memcpy( data, &d, size );
231231
break;
@@ -235,4 +235,188 @@ QByteArray QgsRasterDataProvider::noValueBytes( int theBandNo )
235235
return ba;
236236
}
237237

238+
239+
QgsRasterBandStats QgsRasterDataProvider::bandStatistics( int theBandNo )
240+
{
241+
double myNoDataValue = noDataValue();
242+
QgsRasterBandStats myRasterBandStats;
243+
myRasterBandStats.elementCount = 0; // because we'll be counting only VALID pixels later
244+
245+
int myDataType = dataType( theBandNo );
246+
247+
int myNXBlocks, myNYBlocks, myXBlockSize, myYBlockSize;
248+
myXBlockSize = xBlockSize();
249+
myYBlockSize = yBlockSize();
250+
251+
myNXBlocks = ( xSize() + myXBlockSize - 1 ) / myXBlockSize;
252+
myNYBlocks = ( ySize() + myYBlockSize - 1 ) / myYBlockSize;
253+
254+
void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( dataTypeSize( theBandNo ) / 8 ) );
255+
256+
// unfortunately we need to make two passes through the data to calculate stddev
257+
bool myFirstIterationFlag = true;
258+
259+
int myBandXSize = xSize();
260+
int myBandYSize = ySize();
261+
for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
262+
{
263+
for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
264+
{
265+
int nXValid, nYValid;
266+
readBlock( theBandNo, iXBlock, iYBlock, myData );
267+
268+
// Compute the portion of the block that is valid
269+
// for partial edge blocks.
270+
if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
271+
nXValid = myBandXSize - iXBlock * myXBlockSize;
272+
else
273+
nXValid = myXBlockSize;
274+
275+
if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
276+
nYValid = myBandYSize - iYBlock * myYBlockSize;
277+
else
278+
nYValid = myYBlockSize;
279+
280+
// Collect the histogram counts.
281+
for ( int iY = 0; iY < nYValid; iY++ )
282+
{
283+
for ( int iX = 0; iX < nXValid; iX++ )
284+
{
285+
double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
286+
//QgsDebugMsg ( QString ( "%1 %2 value %3" ).arg (iX).arg(iY).arg( myValue ) );
287+
288+
if ( mValidNoDataValue && ( qAbs( myValue - myNoDataValue ) <= TINY_VALUE ) )
289+
{
290+
continue; // NULL
291+
}
292+
293+
myRasterBandStats.sum += myValue;
294+
++myRasterBandStats.elementCount;
295+
//only use this element if we have a non null element
296+
if ( myFirstIterationFlag )
297+
{
298+
//this is the first iteration so initialise vars
299+
myFirstIterationFlag = false;
300+
myRasterBandStats.minimumValue = myValue;
301+
myRasterBandStats.maximumValue = myValue;
302+
} //end of true part for first iteration check
303+
else
304+
{
305+
//this is done for all subsequent iterations
306+
if ( myValue < myRasterBandStats.minimumValue )
307+
{
308+
myRasterBandStats.minimumValue = myValue;
309+
}
310+
if ( myValue > myRasterBandStats.maximumValue )
311+
{
312+
myRasterBandStats.maximumValue = myValue;
313+
}
314+
} //end of false part for first iteration check
315+
}
316+
}
317+
} //end of column wise loop
318+
} //end of row wise loop
319+
320+
321+
//end of first pass through data now calculate the range
322+
myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
323+
//calculate the mean
324+
myRasterBandStats.mean = myRasterBandStats.sum / myRasterBandStats.elementCount;
325+
326+
//for the second pass we will get the sum of the squares / mean
327+
for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
328+
{
329+
for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
330+
{
331+
int nXValid, nYValid;
332+
333+
readBlock( theBandNo, iXBlock, iYBlock, myData );
334+
335+
// Compute the portion of the block that is valid
336+
// for partial edge blocks.
337+
if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
338+
nXValid = myBandXSize - iXBlock * myXBlockSize;
339+
else
340+
nXValid = myXBlockSize;
341+
342+
if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
343+
nYValid = myBandYSize - iYBlock * myYBlockSize;
344+
else
345+
nYValid = myYBlockSize;
346+
347+
// Collect the histogram counts.
348+
for ( int iY = 0; iY < nYValid; iY++ )
349+
{
350+
for ( int iX = 0; iX < nXValid; iX++ )
351+
{
352+
double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
353+
//QgsDebugMsg ( "myValue = " + QString::number(myValue) );
354+
355+
if ( mValidNoDataValue && ( qAbs( myValue - myNoDataValue ) <= TINY_VALUE ) )
356+
{
357+
continue; // NULL
358+
}
359+
360+
myRasterBandStats.sumOfSquares += static_cast < double >
361+
( pow( myValue - myRasterBandStats.mean, 2 ) );
362+
}
363+
}
364+
} //end of column wise loop
365+
} //end of row wise loop
366+
367+
//divide result by sample size - 1 and get square root to get stdev
368+
myRasterBandStats.stdDev = static_cast < double >( sqrt( myRasterBandStats.sumOfSquares /
369+
( myRasterBandStats.elementCount - 1 ) ) );
370+
371+
#ifdef QGISDEBUG
372+
QgsLogger::debug( "************ STATS **************", 1, __FILE__, __FUNCTION__, __LINE__ );
373+
QgsLogger::debug( "VALID NODATA", mValidNoDataValue, 1, __FILE__, __FUNCTION__, __LINE__ );
374+
QgsLogger::debug( "NULL", noDataValue() , 1, __FILE__, __FUNCTION__, __LINE__ );
375+
QgsLogger::debug( "MIN", myRasterBandStats.minimumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
376+
QgsLogger::debug( "MAX", myRasterBandStats.maximumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
377+
QgsLogger::debug( "RANGE", myRasterBandStats.range, 1, __FILE__, __FUNCTION__, __LINE__ );
378+
QgsLogger::debug( "MEAN", myRasterBandStats.mean, 1, __FILE__, __FUNCTION__, __LINE__ );
379+
QgsLogger::debug( "STDDEV", myRasterBandStats.stdDev, 1, __FILE__, __FUNCTION__, __LINE__ );
380+
#endif
381+
382+
CPLFree( myData );
383+
myRasterBandStats.statsGathered = true;
384+
return myRasterBandStats;
385+
}
386+
387+
double QgsRasterDataProvider::readValue( void *data, int type, int index )
388+
{
389+
if ( !data )
390+
return mValidNoDataValue ? noDataValue() : 0.0;
391+
392+
switch ( type )
393+
{
394+
case Byte:
395+
return ( double )(( GByte * )data )[index];
396+
break;
397+
case UInt16:
398+
return ( double )(( GUInt16 * )data )[index];
399+
break;
400+
case Int16:
401+
return ( double )(( GInt16 * )data )[index];
402+
break;
403+
case UInt32:
404+
return ( double )(( GUInt32 * )data )[index];
405+
break;
406+
case Int32:
407+
return ( double )(( GInt32 * )data )[index];
408+
break;
409+
case Float32:
410+
return ( double )(( float * )data )[index];
411+
break;
412+
case Float64:
413+
return ( double )(( double * )data )[index];
414+
break;
415+
default:
416+
QgsLogger::warning( "GDAL data type is not supported" );
417+
}
418+
419+
return mValidNoDataValue ? noDataValue() : 0.0;
420+
}
421+
238422
// ENDS

‎src/core/qgsrasterdataprovider.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "qgscoordinatereferencesystem.h"
3131
#include "qgsrasterbandstats.h"
3232

33+
#include "cpl_conv.h"
3334
#include <cmath>
3435

3536
class QImage;
@@ -109,10 +110,11 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider
109110
};
110111

111112
// Progress types
112-
enum Progress
113+
enum RasterProgressType
113114
{
114115
ProgressHistogram = 0,
115-
ProgressPyramids = 1
116+
ProgressPyramids = 1,
117+
ProgressStatistics = 2
116118
};
117119

118120
QgsRasterDataProvider();
@@ -325,6 +327,9 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider
325327

326328
/** read block of data using give extent and size */
327329
virtual void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, QgsCoordinateReferenceSystem theSrcCRS, QgsCoordinateReferenceSystem theDestCRS, void *data );
330+
331+
/* Read a value from a data block at a given index. */
332+
virtual double readValue( void *data, int type, int index );
328333

329334
/** value representing null data */
330335
virtual double noDataValue() const { return 0; }
@@ -365,13 +370,16 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider
365370
*/
366371
virtual QList<QgsRasterPyramid> buildPyramidList() { return QList<QgsRasterPyramid>(); };
367372

373+
/** If the provider supports it, return band stats for the
374+
given band. Default behaviour is to blockwise read the data
375+
and generate the stats unless the provider overloads this function. */
376+
virtual QgsRasterBandStats bandStatistics( int theBandNo );
368377

369378
/** \brief helper function to create zero padded band names */
370379
QString generateBandName( int theBandNumber )
371380
{
372381
return tr( "Band" ) + QString( " %1" ) .arg( theBandNumber, 1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) );
373-
}
374-
382+
};
375383

376384
/**
377385
* Get metadata in a format suitable for feeding directly

‎src/core/raster/qgspseudocolorshader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ bool QgsPseudoColorShader::shade( double theValue, int* theReturnRedValue, int*
4444
}
4545

4646
//check if we are in the first class break
47-
if (( myPixelValue >= mClassBreakMin1 ) && ( myPixelValue < mClassBreakMax1 ) )
47+
if ( ( myPixelValue >= mClassBreakMin1 ) && ( myPixelValue < mClassBreakMax1 ) )
4848
{
4949
*theReturnRedValue = 0;
5050
*theReturnGreenValue = static_cast < int >((( 255 / mMinimumMaximumRange ) * ( myPixelValue - mClassBreakMin1 ) ) * 3 );

‎src/core/raster/qgsrasterlayer.cpp

Lines changed: 6 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,6 @@ const QgsRasterBandStats QgsRasterLayer::bandStatistics( int theBandNo )
327327
QgsRasterBandStats myNullReturnStats;
328328
return myNullReturnStats;
329329
}
330-
331330
// check if we have received a valid band number
332331
if (( mDataProvider->bandCount() < theBandNo ) && mRasterType != Palette )
333332
{
@@ -341,7 +340,6 @@ const QgsRasterBandStats QgsRasterLayer::bandStatistics( int theBandNo )
341340
QgsRasterBandStats myNullReturnStats;
342341
return myNullReturnStats;
343342
}
344-
345343
// check if we have previously gathered stats for this band...
346344
if ( theBandNo < 1 || theBandNo > mRasterStatsList.size() )
347345
{
@@ -358,174 +356,23 @@ const QgsRasterBandStats QgsRasterLayer::bandStatistics( int theBandNo )
358356
{
359357
return myRasterBandStats;
360358
}
361-
// only print message if we are actually gathering the stats
362-
emit statusChanged( tr( "Retrieving stats for %1" ).arg( name() ) );
363-
qApp->processEvents();
364-
QgsDebugMsg( "stats for band " + QString::number( theBandNo ) );
365-
366-
myRasterBandStats.elementCount = 0; // because we'll be counting only VALID pixels later
367-
368-
emit statusChanged( tr( "Calculating stats for %1" ).arg( name() ) );
369-
//reset the main app progress bar
370-
emit drawingProgress( 0, 0 );
371-
372-
int myDataType = mDataProvider->dataType( theBandNo );
373-
374-
int myNXBlocks, myNYBlocks, myXBlockSize, myYBlockSize;
375-
myXBlockSize = mDataProvider->xBlockSize();
376-
myYBlockSize = mDataProvider->yBlockSize();
377-
378-
myNXBlocks = ( mDataProvider->xSize() + myXBlockSize - 1 ) / myXBlockSize;
379-
myNYBlocks = ( mDataProvider->ySize() + myYBlockSize - 1 ) / myYBlockSize;
380-
381-
void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( mDataProvider->dataTypeSize( theBandNo ) / 8 ) );
382-
383-
// unfortunately we need to make two passes through the data to calculate stddev
384-
bool myFirstIterationFlag = true;
385-
386-
int myBandXSize = mDataProvider->xSize();
387-
int myBandYSize = mDataProvider->ySize();
388-
for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
389-
{
390-
emit drawingProgress( iYBlock, myNYBlocks * 2 );
391-
392-
for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
393-
{
394-
int nXValid, nYValid;
395-
mDataProvider->readBlock( theBandNo, iXBlock, iYBlock, myData );
396-
397-
// Compute the portion of the block that is valid
398-
// for partial edge blocks.
399-
if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
400-
nXValid = myBandXSize - iXBlock * myXBlockSize;
401-
else
402-
nXValid = myXBlockSize;
403-
404-
if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
405-
nYValid = myBandYSize - iYBlock * myYBlockSize;
406-
else
407-
nYValid = myYBlockSize;
408-
409-
// Collect the histogram counts.
410-
for ( int iY = 0; iY < nYValid; iY++ )
411-
{
412-
for ( int iX = 0; iX < nXValid; iX++ )
413-
{
414-
double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
415-
//QgsDebugMsg ( QString ( "%1 %2 value %3" ).arg (iX).arg(iY).arg( myValue ) );
416-
417-
if ( mValidNoDataValue && ( qAbs( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
418-
{
419-
continue; // NULL
420-
}
421-
422-
myRasterBandStats.sum += myValue;
423-
++myRasterBandStats.elementCount;
424-
//only use this element if we have a non null element
425-
if ( myFirstIterationFlag )
426-
{
427-
//this is the first iteration so initialise vars
428-
myFirstIterationFlag = false;
429-
myRasterBandStats.minimumValue = myValue;
430-
myRasterBandStats.maximumValue = myValue;
431-
} //end of true part for first iteration check
432-
else
433-
{
434-
//this is done for all subsequent iterations
435-
if ( myValue < myRasterBandStats.minimumValue )
436-
{
437-
myRasterBandStats.minimumValue = myValue;
438-
}
439-
if ( myValue > myRasterBandStats.maximumValue )
440-
{
441-
myRasterBandStats.maximumValue = myValue;
442-
}
443-
} //end of false part for first iteration check
444-
}
445-
}
446-
} //end of column wise loop
447-
} //end of row wise loop
448-
449-
450-
//end of first pass through data now calculate the range
451-
myRasterBandStats.range = myRasterBandStats.maximumValue - myRasterBandStats.minimumValue;
452-
//calculate the mean
453-
myRasterBandStats.mean = myRasterBandStats.sum / myRasterBandStats.elementCount;
454-
455-
//for the second pass we will get the sum of the squares / mean
456-
for ( int iYBlock = 0; iYBlock < myNYBlocks; iYBlock++ )
457-
{
458-
emit drawingProgress( iYBlock + myNYBlocks, myNYBlocks * 2 );
459-
460-
for ( int iXBlock = 0; iXBlock < myNXBlocks; iXBlock++ )
461-
{
462-
int nXValid, nYValid;
463-
464-
mDataProvider->readBlock( theBandNo, iXBlock, iYBlock, myData );
465-
466-
// Compute the portion of the block that is valid
467-
// for partial edge blocks.
468-
if (( iXBlock + 1 ) * myXBlockSize > myBandXSize )
469-
nXValid = myBandXSize - iXBlock * myXBlockSize;
470-
else
471-
nXValid = myXBlockSize;
472-
473-
if (( iYBlock + 1 ) * myYBlockSize > myBandYSize )
474-
nYValid = myBandYSize - iYBlock * myYBlockSize;
475-
else
476-
nYValid = myYBlockSize;
477-
478-
// Collect the histogram counts.
479-
for ( int iY = 0; iY < nYValid; iY++ )
480-
{
481-
for ( int iX = 0; iX < nXValid; iX++ )
482-
{
483-
double myValue = readValue( myData, myDataType, iX + ( iY * myXBlockSize ) );
484-
//QgsDebugMsg ( "myValue = " + QString::number(myValue) );
485-
486-
if ( mValidNoDataValue && ( qAbs( myValue - mNoDataValue ) <= TINY_VALUE || myValue != myValue ) )
487-
{
488-
continue; // NULL
489-
}
490-
491-
myRasterBandStats.sumOfSquares += static_cast < double >
492-
( pow( myValue - myRasterBandStats.mean, 2 ) );
493-
}
494-
}
495-
} //end of column wise loop
496-
} //end of row wise loop
497-
498-
//divide result by sample size - 1 and get square root to get stdev
499-
myRasterBandStats.stdDev = static_cast < double >( sqrt( myRasterBandStats.sumOfSquares /
500-
( myRasterBandStats.elementCount - 1 ) ) );
501-
502-
#ifdef QGISDEBUG
503-
QgsLogger::debug( "************ STATS **************", 1, __FILE__, __FUNCTION__, __LINE__ );
504-
QgsLogger::debug( "VALID NODATA", mValidNoDataValue, 1, __FILE__, __FUNCTION__, __LINE__ );
505-
QgsLogger::debug( "NULL", mNoDataValue, 1, __FILE__, __FUNCTION__, __LINE__ );
506-
QgsLogger::debug( "MIN", myRasterBandStats.minimumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
507-
QgsLogger::debug( "MAX", myRasterBandStats.maximumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
508-
QgsLogger::debug( "RANGE", myRasterBandStats.range, 1, __FILE__, __FUNCTION__, __LINE__ );
509-
QgsLogger::debug( "MEAN", myRasterBandStats.mean, 1, __FILE__, __FUNCTION__, __LINE__ );
510-
QgsLogger::debug( "STDDEV", myRasterBandStats.stdDev, 1, __FILE__, __FUNCTION__, __LINE__ );
511-
#endif
512-
513-
CPLFree( myData );
514-
myRasterBandStats.statsGathered = true;
515359

360+
myRasterBandStats = mDataProvider->bandStatistics( theBandNo );
516361
QgsDebugMsg( "adding stats to stats collection at position " + QString::number( theBandNo - 1 ) );
517362
//add this band to the class stats map
518363
mRasterStatsList[theBandNo - 1] = myRasterBandStats;
519364
emit drawingProgress( mHeight, mHeight ); //reset progress
520-
//QApplication::restoreOverrideCursor(); //restore the cursor
521365
QgsDebugMsg( "Stats collection completed returning" );
522366
return myRasterBandStats;
523-
524367
} // QgsRasterLayer::bandStatistics
525368

526369
const QgsRasterBandStats QgsRasterLayer::bandStatistics( QString const & theBandName )
527370
{
528-
371+
// only print message if we are actually gathering the stats
372+
emit statusChanged( tr( "Retrieving stats for %1" ).arg( name() ) );
373+
qApp->processEvents();
374+
//reset the main app progress bar
375+
emit drawingProgress( 0, 0 );
529376
//we cant use a vector iterator because the iterator is astruct not a class
530377
//and the qvector model does not like this.
531378
for ( int i = 1; i <= mDataProvider->bandCount(); i++ )

‎src/providers/gdal/qgsgdalprovider.cpp

Lines changed: 94 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ QgsGdalProvider::QgsGdalProvider( QString const & uri )
105105

106106
// To get buildSupportedRasterFileFilter the provider is called with empty uri
107107
if ( uri.isEmpty() )
108+
{
108109
return;
110+
}
109111

110112
mGdalDataset = NULL;
111113

@@ -287,51 +289,6 @@ QgsGdalProvider::QgsGdalProvider( QString const & uri )
287289
QgsDebugMsg( QString( "mNoDataValue[%1] = %1" ).arg( i - 1 ).arg( mNoDataValue[i-1] ) );
288290
}
289291

290-
// This block of code was in old version in QgsRasterLayer::bandStatistics
291-
//ifdefs below to remove compiler warning about unused vars
292-
#ifdef QGISDEBUG
293-
#if 0
294-
int success;
295-
double GDALminimum = GDALGetRasterMinimum( myGdalBand, &success );
296-
297-
if ( ! success )
298-
{
299-
QgsDebugMsg( "myGdalBand->GetMinimum() failed" );
300-
}
301-
302-
double GDALmaximum = GDALGetRasterMaximum( myGdalBand, &success );
303-
304-
if ( ! success )
305-
{
306-
QgsDebugMsg( "myGdalBand->GetMaximum() failed" );
307-
}
308-
309-
double GDALnodata = GDALGetRasterNoDataValue( myGdalBand, &success );
310-
311-
if ( ! success )
312-
{
313-
QgsDebugMsg( "myGdalBand->GetNoDataValue() failed" );
314-
}
315-
316-
QgsLogger::debug( "GDALminium: ", GDALminimum, __FILE__, __FUNCTION__, __LINE__ );
317-
QgsLogger::debug( "GDALmaximum: ", GDALmaximum, __FILE__, __FUNCTION__, __LINE__ );
318-
QgsLogger::debug( "GDALnodata: ", GDALnodata, __FILE__, __FUNCTION__, __LINE__ );
319-
320-
double GDALrange[2]; // calculated min/max, as opposed to the
321-
// dataset provided
322-
323-
GDALComputeRasterMinMax( myGdalBand, 1, GDALrange );
324-
QgsLogger::debug( "approximate computed GDALminium:", GDALrange[0], __FILE__, __FUNCTION__, __LINE__, 1 );
325-
QgsLogger::debug( "approximate computed GDALmaximum:", GDALrange[1], __FILE__, __FUNCTION__, __LINE__, 1 );
326-
327-
GDALComputeRasterMinMax( myGdalBand, 0, GDALrange );
328-
QgsLogger::debug( "exactly computed GDALminium:", GDALrange[0] );
329-
QgsLogger::debug( "exactly computed GDALmaximum:", GDALrange[1] );
330-
331-
QgsDebugMsg( "starting manual stat computation" );
332-
#endif
333-
#endif
334-
335292
mValid = true;
336293
QgsDebugMsg( "end" );
337294
}
@@ -391,7 +348,9 @@ QgsGdalProvider::~QgsGdalProvider()
391348
void QgsGdalProvider::closeDataset()
392349
{
393350
if ( !mValid )
351+
{
394352
return;
353+
}
395354
mValid = false;
396355

397356
GDALDereferenceDataset( mGdalBaseDataset );
@@ -921,25 +880,37 @@ void QgsGdalProvider::computeMinMax( int theBandNo )
921880
{
922881
QgsDebugMsg( QString( "theBandNo = %1 mMinMaxComputed = %2" ).arg( theBandNo ).arg( mMinMaxComputed[theBandNo-1] ) );
923882
if ( mMinMaxComputed[theBandNo-1] )
883+
{
924884
return;
925-
double GDALrange[2];
885+
}
886+
int bApproxOK=false;
887+
double pdfMin;
888+
double pdfMax;
889+
double pdfMean;
890+
double pdfStdDev;
926891
GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
927-
GDALComputeRasterMinMax( myGdalBand, 1, GDALrange ); //Approximate
928-
QgsDebugMsg( QString( "GDALrange[0] = %1 GDALrange[1] = %2" ).arg( GDALrange[0] ).arg( GDALrange[1] ) );
929-
mMinimum[theBandNo-1] = GDALrange[0];
930-
mMaximum[theBandNo-1] = GDALrange[1];
892+
double myerval = GDALGetRasterStatistics (
893+
myGdalBand,
894+
bApproxOK,
895+
TRUE,
896+
&pdfMin,
897+
&pdfMax,
898+
&pdfMean,
899+
&pdfStdDev
900+
);
901+
Q_UNUSED(myerval);
902+
mMinimum[theBandNo-1] = pdfMin;
903+
mMaximum[theBandNo-1] = pdfMax;
931904
}
932905

933906
double QgsGdalProvider::minimumValue( int theBandNo ) const
934907
{
935908
QgsDebugMsg( QString( "theBandNo = %1" ).arg( theBandNo ) );
936-
//computeMinMax ( theBandNo );
937909
return mMinimum[theBandNo-1];
938910
}
939911
double QgsGdalProvider::maximumValue( int theBandNo ) const
940912
{
941913
QgsDebugMsg( QString( "theBandNo = %1" ).arg( theBandNo ) );
942-
//computeMinMax ( theBandNo );
943914
return mMaximum[theBandNo-1];
944915
}
945916

@@ -1294,7 +1265,9 @@ void QgsGdalProvider::populateHistogram( int theBandNo, QgsRasterBandStats & t
12941265
//vector is not equal to the number of bins
12951266
//i.e if the histogram has never previously been generated or the user has
12961267
//selected a new number of bins.
1297-
if ( theBandStats.histogramVector->size() != theBinCount ||
1268+
bool myCollectHistogramFlag = true;
1269+
if ( theBandStats.histogramVector == 0 ||
1270+
theBandStats.histogramVector->size() != theBinCount ||
12981271
theIgnoreOutOfRangeFlag != theBandStats.isHistogramOutOfRange ||
12991272
theHistogramEstimatedFlag != theBandStats.isHistogramEstimated )
13001273
{
@@ -1865,6 +1838,74 @@ QGISEXTERN bool isValidRasterFileName( QString const & theFileNameQString, QStri
18651838
}
18661839
}
18671840

1841+
1842+
1843+
QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo )
1844+
{
1845+
GDALRasterBandH myGdalBand = GDALGetRasterBand( mGdalDataset, theBandNo );
1846+
QgsRasterBandStats myRasterBandStats;
1847+
int bApproxOK=false;
1848+
double pdfMin;
1849+
double pdfMax;
1850+
double pdfMean;
1851+
double pdfStdDev;
1852+
QgsGdalProgress myProg;
1853+
myProg.type = ProgressHistogram;
1854+
myProg.provider = this;
1855+
1856+
// Suggested by Etienne Sky to use getrasterstatistics instead of compute
1857+
// since computerasterstatistics forces collection each time
1858+
// where as getrasterstatistics uses aux.xml cached copy if available
1859+
// Note: there is currently no progress callback in this method
1860+
double myerval = GDALGetRasterStatistics (
1861+
myGdalBand,
1862+
bApproxOK,
1863+
TRUE,
1864+
&pdfMin,
1865+
&pdfMax,
1866+
&pdfMean,
1867+
&pdfStdDev
1868+
);
1869+
//double myerval = GDALComputeRasterStatistics ( myGdalBand,
1870+
// bApproxOK,
1871+
// &pdfMin,
1872+
// &pdfMax,
1873+
// &pdfMean,
1874+
// &pdfStdDev,
1875+
// progressCallback,
1876+
// &myProg
1877+
//) ;
1878+
//end of first pass through data now calculate the range
1879+
myRasterBandStats.bandName = generateBandName( theBandNo );
1880+
myRasterBandStats.bandNumber = theBandNo;
1881+
myRasterBandStats.range = pdfMax - pdfMin;
1882+
myRasterBandStats.minimumValue = pdfMin;
1883+
myRasterBandStats.maximumValue = pdfMax;
1884+
//calculate the mean
1885+
myRasterBandStats.mean = pdfMean;
1886+
myRasterBandStats.sum = 0; //not available via gdal
1887+
myRasterBandStats.elementCount = mWidth * mHeight;
1888+
myRasterBandStats.sumOfSquares = 0; //not available via gdal
1889+
myRasterBandStats.stdDev = pdfStdDev;
1890+
myRasterBandStats.statsGathered = true;
1891+
1892+
#ifdef QGISDEBUG
1893+
QgsLogger::debug( "************ STATS **************", 1, __FILE__, __FUNCTION__, __LINE__ );
1894+
QgsLogger::debug( "VALID NODATA", mValidNoDataValue, 1, __FILE__, __FUNCTION__, __LINE__ );
1895+
QgsLogger::debug( "MIN", myRasterBandStats.minimumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
1896+
QgsLogger::debug( "MAX", myRasterBandStats.maximumValue, 1, __FILE__, __FUNCTION__, __LINE__ );
1897+
QgsLogger::debug( "RANGE", myRasterBandStats.range, 1, __FILE__, __FUNCTION__, __LINE__ );
1898+
QgsLogger::debug( "MEAN", myRasterBandStats.mean, 1, __FILE__, __FUNCTION__, __LINE__ );
1899+
QgsLogger::debug( "STDDEV", myRasterBandStats.stdDev, 1, __FILE__, __FUNCTION__, __LINE__ );
1900+
#endif
1901+
1902+
myRasterBandStats.statsGathered = true;
1903+
1904+
return myRasterBandStats;
1905+
1906+
} // QgsGdalProvider::bandStatistics
1907+
1908+
18681909
/**
18691910
Builds the list of file filter strings to later be used by
18701911
QgisApp::addRasterLayer()

‎src/providers/gdal/qgsgdalprovider.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "qgsrasterdataprovider.h"
2727
#include "qgsrectangle.h"
2828
#include "qgscolorrampshader.h"
29+
#include "qgsrasterbandstats.h"
2930

3031
#include <QString>
3132
#include <QStringList>
@@ -222,6 +223,13 @@ class QgsGdalProvider : public QgsRasterDataProvider
222223

223224
/** \brief Returns the sublayers of this layer - Useful for providers that manage their own layers, such as WMS */
224225
QStringList subLayers() const;
226+
/** \brief If the provider supports it, return band stats for the
227+
given band.
228+
@note added in QGIS 1.7
229+
@note overloads virtual method from QgsRasterProvider::bandStatistics
230+
231+
*/
232+
QgsRasterBandStats bandStatistics( int theBandNo );
225233

226234
void populateHistogram( int theBandNoInt,
227235
QgsRasterBandStats & theBandStats,

‎tests/src/core/testqgsapplication.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void TestQgsApplication::initTestCase()
4141
// init QGIS's paths - true means that all path will be inited from prefix
4242
QString qgisPath = QCoreApplication::applicationDirPath();
4343
QgsApplication::setPrefixPath( INSTALL_PREFIX, true );
44-
QgsApplication::showSettings();
44+
qDebug( QgsApplication::showSettings().toUtf8() );
4545
};
4646

4747
void TestQgsApplication::checkTheme()

‎tests/src/core/testqgsrasterlayer.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class TestQgsRasterLayer: public QObject
5757
void landsatBasic();
5858
void landsatBasic875Qml();
5959
void checkDimensions();
60+
void checkStats();
6061
void buildExternalOverviews();
6162
void registry();
6263
private:
@@ -73,9 +74,10 @@ class TestQgsRasterLayer: public QObject
7374
void TestQgsRasterLayer::initTestCase()
7475
{
7576
// init QGIS's paths - true means that all path will be inited from prefix
76-
QString qgisPath = QCoreApplication::applicationDirPath();
77-
QgsApplication::setPrefixPath( INSTALL_PREFIX, true );
78-
QgsApplication::showSettings();
77+
QgsApplication::init( QString() );
78+
QgsApplication::initQgis();
79+
QString mySettings = QgsApplication::showSettings();
80+
mySettings = mySettings.replace("\n","<br />");
7981
//create some objects that will be used in all tests...
8082
//create a raster layer that will be used in all tests...
8183
mTestDataDir = QString( TEST_DATA_DIR ) + QDir::separator(); //defined in CmakeLists.txt
@@ -96,6 +98,7 @@ void TestQgsRasterLayer::initTestCase()
9698
myLayers << mpRasterLayer->id();
9799
mpMapRenderer->setLayerSet( myLayers );
98100
mReport += "<h1>Raster Layer Tests</h1>\n";
101+
mReport += "<p>" + mySettings + "</p>";
99102
}
100103
//runs after all tests
101104
void TestQgsRasterLayer::cleanupTestCase()
@@ -115,6 +118,7 @@ void TestQgsRasterLayer::cleanupTestCase()
115118
void TestQgsRasterLayer::isValid()
116119
{
117120
QVERIFY( mpRasterLayer->isValid() );
121+
mpRasterLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, false );
118122
mpMapRenderer->setExtent( mpRasterLayer->extent() );
119123
QVERIFY( render( "raster" ) );
120124
}
@@ -133,6 +137,7 @@ void TestQgsRasterLayer::pseudoColor()
133137

134138
void TestQgsRasterLayer::landsatBasic()
135139
{
140+
mpLandsatRasterLayer->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum, false );
136141
QStringList myLayers;
137142
myLayers << mpLandsatRasterLayer->id();
138143
mpMapRenderer->setLayerSet( myLayers );
@@ -156,13 +161,26 @@ void TestQgsRasterLayer::checkDimensions()
156161
// regression check for ticket #832
157162
// note bandStatistics call is base 1
158163
QVERIFY( mpRasterLayer->bandStatistics( 1 ).elementCount == 100 );
164+
mReport += "<h2>Check Dimensions</h2>\n";
165+
mReport += "<p>Passed</p>";
166+
}
167+
void TestQgsRasterLayer::checkStats()
168+
{
169+
QVERIFY( mpRasterLayer->width() == 10 );
170+
QVERIFY( mpRasterLayer->height() == 10 );
171+
QVERIFY( mpRasterLayer->bandStatistics( 1 ).elementCount == 100 );
172+
QVERIFY( mpRasterLayer->bandStatistics( 1 ).minimumValue == 0 );
173+
QVERIFY( mpRasterLayer->bandStatistics( 1 ).maximumValue == 9 );
174+
QVERIFY( mpRasterLayer->bandStatistics( 1 ).mean == 4.5 );
175+
QVERIFY( mpRasterLayer->bandStatistics( 1 ).stdDev == 2.872281323269 );
176+
mReport += "<h2>Check Stats</h2>\n";
177+
mReport += "<p>Passed</p>";
159178
}
160179

161180
void TestQgsRasterLayer::buildExternalOverviews()
162181
{
163182
//before we begin delete any old ovr file (if it exists)
164183
//and make a copy of the landsat raster into the temp dir
165-
166184
QString myTempPath = QDir::tempPath() + QDir::separator();
167185
QFile::remove( myTempPath + "landsat.tif.ovr" );
168186
QFile::copy( mTestDataDir + "landsat.tif", myTempPath + "landsat.tif" );
@@ -205,6 +223,8 @@ void TestQgsRasterLayer::buildExternalOverviews()
205223
QVERIFY( QFile::exists( myTempPath + "landsat.tif.ovr" ) );
206224
//cleanup
207225
delete mypLayer;
226+
mReport += "<h2>Check Overviews</h2>\n";
227+
mReport += "<p>Passed</p>";
208228
}
209229

210230

-553 Bytes
Loading
-1.21 KB
Loading

‎tests/testdata/landsat_875.qml

Lines changed: 62 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,64 @@
11
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
2-
<qgis projectname="" version="0.9.2-Ganymede" >
3-
<maplayer minimumScale="1" maximumScale="1e+08" hasScaleBasedVisibilityFlag="0" type="raster" >
4-
<id>landsat_clip20080125220410500</id>
5-
<datasource>landsat_clip.tif</datasource>
6-
<layername>landsat_clip</layername>
7-
<srs>
8-
<spatialrefsys>
9-
<proj4>+proj=utm +zone=33 +ellps=WGS84 +datum=WGS84 +units=m +no_defs</proj4>
10-
<srsid>2267</srsid>
11-
<srid>32633</srid>
12-
<epsg>32633</epsg>
13-
<description>WGS 84 / UTM zone 33N</description>
14-
<projectionacronym>utm</projectionacronym>
15-
<ellipsoidacronym>WGS84</ellipsoidacronym>
16-
<geographicflag>true</geographicflag>
17-
</spatialrefsys>
18-
</srs>
19-
<transparencyLevelInt>255</transparencyLevelInt>
20-
<provider></provider>
21-
<rasterproperties>
22-
<mDebugOverlayFlag boolean="false" />
23-
<drawingStyle>MULTI_BAND_COLOR</drawingStyle>
24-
<mColorShadingAlgorithm>UNDEFINED_SHADING_ALGORITHM</mColorShadingAlgorithm>
25-
<mInvertPixelsFlag boolean="false" />
26-
<mRedBandName>8 : Undefined</mRedBandName>
27-
<mGreenBandName>7 : Undefined</mGreenBandName>
28-
<mBlueBandName>5 : Undefined</mBlueBandName>
29-
<mGrayBandName>Not Set</mGrayBandName>
30-
<mStandardDeviations>0</mStandardDeviations>
31-
<mContrastEnhancementAlgorithm>STRETCH_TO_MINMAX</mContrastEnhancementAlgorithm>
32-
<contrastEnhancementMinMaxValues>
33-
<minMaxEntry>
34-
<min>122</min>
35-
<max>130</max>
36-
</minMaxEntry>
37-
<minMaxEntry>
38-
<min>133</min>
39-
<max>148</max>
40-
</minMaxEntry>
41-
<minMaxEntry>
42-
<min>57</min>
43-
<max>157</max>
44-
</minMaxEntry>
45-
<minMaxEntry>
46-
<min>0</min>
47-
<max>255</max>
48-
</minMaxEntry>
49-
<minMaxEntry>
50-
<min>61</min>
51-
<max>117</max>
52-
</minMaxEntry>
53-
<minMaxEntry>
54-
<min>0</min>
55-
<max>255</max>
56-
</minMaxEntry>
57-
<minMaxEntry>
58-
<min>92</min>
59-
<max>213</max>
60-
</minMaxEntry>
61-
<minMaxEntry>
62-
<min>122</min>
63-
<max>255</max>
64-
</minMaxEntry>
65-
<minMaxEntry>
66-
<min>0</min>
67-
<max>255</max>
68-
</minMaxEntry>
69-
</contrastEnhancementMinMaxValues>
70-
<mNoDataValue mValidNoDataValue="false" >-9999.000000</mNoDataValue>
71-
</rasterproperties>
72-
</maplayer>
2+
<qgis version="1.8.0-Trunk" minimumScale="0" maximumScale="1e+08" hasScaleBasedVisibilityFlag="0">
3+
<transparencyLevelInt>255</transparencyLevelInt>
4+
<rasterproperties>
5+
<mDrawingStyle>MultiBandColor</mDrawingStyle>
6+
<mColorShadingAlgorithm>UndefinedShader</mColorShadingAlgorithm>
7+
<mInvertColor boolean="false"/>
8+
<mRedBandName>Band 8</mRedBandName>
9+
<mGreenBandName>Band 7</mGreenBandName>
10+
<mBlueBandName>Band 5</mBlueBandName>
11+
<mGrayBandName>Band 1</mGrayBandName>
12+
<mStandardDeviations>0</mStandardDeviations>
13+
<mUserDefinedRGBMinimumMaximum boolean="false"/>
14+
<mRGBMinimumMaximumEstimated boolean="true"/>
15+
<mUserDefinedGrayMinimumMaximum boolean="false"/>
16+
<mGrayMinimumMaximumEstimated boolean="true"/>
17+
<mContrastEnhancementAlgorithm>StretchToMinimumMaximum</mContrastEnhancementAlgorithm>
18+
<contrastEnhancementMinMaxValues>
19+
<minMaxEntry>
20+
<min>0</min>
21+
<max>255</max>
22+
</minMaxEntry>
23+
<minMaxEntry>
24+
<min>0</min>
25+
<max>255</max>
26+
</minMaxEntry>
27+
<minMaxEntry>
28+
<min>0</min>
29+
<max>255</max>
30+
</minMaxEntry>
31+
<minMaxEntry>
32+
<min>0</min>
33+
<max>255</max>
34+
</minMaxEntry>
35+
<minMaxEntry>
36+
<min>61</min>
37+
<max>123</max>
38+
</minMaxEntry>
39+
<minMaxEntry>
40+
<min>0</min>
41+
<max>255</max>
42+
</minMaxEntry>
43+
<minMaxEntry>
44+
<min>92</min>
45+
<max>232</max>
46+
</minMaxEntry>
47+
<minMaxEntry>
48+
<min>122</min>
49+
<max>255</max>
50+
</minMaxEntry>
51+
<minMaxEntry>
52+
<min>0</min>
53+
<max>255</max>
54+
</minMaxEntry>
55+
</contrastEnhancementMinMaxValues>
56+
<mNoDataValue mValidNoDataValue="true">-32768.000000</mNoDataValue>
57+
<singleValuePixelList>
58+
<pixelListEntry pixelValue="-32768.000000" percentTransparent="100"/>
59+
</singleValuePixelList>
60+
<threeValuePixelList>
61+
<pixelListEntry red="-32768.000000" blue="-32768.000000" green="-32768.000000" percentTransparent="100"/>
62+
</threeValuePixelList>
63+
</rasterproperties>
7364
</qgis>

0 commit comments

Comments
 (0)
Please sign in to comment.