raster cleanup

This commit is contained in:
Radim Blazek 2013-04-16 20:05:37 +02:00
parent d3a7e04bd3
commit 22e54b9210
14 changed files with 139 additions and 512 deletions

View File

@ -120,22 +120,8 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
virtual int ySize() const;
/** read block of data */
// TODO clarify what happens on the last block (the part outside raster)
// virtual void readBlock( int bandNo, int xBlock, int yBlock, void *data );
/** read block of data using give extent and size */
// virtual void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data );
/** read block of data using give extent and size */
// virtual void *readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, QgsCoordinateReferenceSystem theSrcCRS, QgsCoordinateReferenceSystem theDestCRS, void *data );
/** Read block of data using given extent and size. */
// virtual void *readBlock( int bandNo, QgsRectangle const & extent, int width, int height );
virtual QgsRasterBlock *block( int bandNo, const QgsRectangle &extent, int width, int height ) / Factory /;
/* Read a value from a data block at a given index. */
//virtual double readValue( void *data, int type, int index );
/* Return true if source band has no data value */
virtual bool srcHasNoDataValue( int bandNo ) const;
@ -145,14 +131,6 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
/** \brief Set source nodata value usage */
virtual void setUseSrcNoDataValue( int bandNo, bool use );
/** value representing null data */
//virtual double noDataValue() const;
/** Value representing currentno data.
* WARNING: this value returned by this method is not constant. It may change
* for example if user disable use of source no data value. */
//virtual double noDataValue( int bandNo ) const;
/** Value representing no data value. */
virtual double srcNoDataValue( int bandNo ) const;
@ -161,9 +139,6 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
/** Get list of user no data value ranges */
virtual QgsRasterRangeList userNoDataValue( int bandNo ) const;
virtual double minimumValue( int bandNo ) const;
virtual double maximumValue( int bandNo ) const;
virtual QList<QgsColorRampShader::ColorRampItem> colorTable( int bandNo ) const;
// Defined in parent
@ -235,11 +210,6 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
@note: this method was added in version 1.2*/
void setDpi( int dpi );
static QStringList cStringList2Q_( char ** stringList );
static QString makeTableCell( const QString & value );
static QString makeTableCells( const QStringList & values );
/** Time stamp of data source in the moment when data/metadata were loaded by provider */
virtual QDateTime timestamp() const;
@ -273,9 +243,7 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
virtual bool remove();
/** Returns a list of pyramid resampling method names for given provider */
static QStringList pyramidResamplingMethods( QString providerKey = "gdal" );
/** Returns the pyramid resampling argument that corresponds to a given method */
static QString pyramidResamplingArg( QString method, QString providerKey = "gdal" );
static QList<QPair<QString,QString> > pyramidResamplingMethods( QString providerKey );
/** Validates creation options for a specific dataset and destination format.
* @note used by GDAL provider only

View File

@ -164,9 +164,11 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
{
// initialize resampling methods
cboResamplingMethod->clear();
foreach ( QString method, QgsRasterDataProvider::pyramidResamplingMethods( mRasterLayer->providerType() ) )
cboResamplingMethod->addItem( method );
QPair<QString, QString> method;
foreach ( method, QgsRasterDataProvider::pyramidResamplingMethods( mRasterLayer->providerType() ) )
{
cboResamplingMethod->addItem( method.second, method.first );
}
// build pyramid list
QList< QgsRasterPyramid > myPyramidList = provider->buildPyramidList();
QList< QgsRasterPyramid >::iterator myRasterPyramidIterator;
@ -936,7 +938,7 @@ void QgsRasterLayerProperties::on_buttonBuildPyramids_clicked()
QApplication::setOverrideCursor( Qt::WaitCursor );
QString res = provider->buildPyramids(
myPyramidList,
cboResamplingMethod->currentText(),
cboResamplingMethod->itemData( cboResamplingMethod->currentIndex() ).toString(),
( QgsRasterDataProvider::RasterPyramidsFormat ) cbxPyramidsFormat->currentIndex() );
QApplication::restoreOverrideCursor();
mPyramidProgress->setValue( 0 );

View File

@ -145,12 +145,16 @@ bool QgsRasterChecker::runTest( QString theVerifiedKey, QString theVerifiedUri,
int width = expectedProvider->xSize();
int height = expectedProvider->ySize();
int blockSize = width * height * QgsRasterBlock::typeSize( expectedProvider->dataType( band ) ) ;
void * expectedData = malloc( blockSize );
void * verifiedData = malloc( blockSize );
QgsRasterBlock *expectedBlock = expectedProvider->block( band, expectedProvider->extent(), width, height );
QgsRasterBlock *verifiedBlock = verifiedProvider->block( band, expectedProvider->extent(), width, height );
expectedProvider->readBlock( band, expectedProvider->extent(), width, height, expectedData );
verifiedProvider->readBlock( band, expectedProvider->extent(), width, height, verifiedData );
if ( !expectedBlock || !expectedBlock->isValid() ||
!verifiedBlock || !verifiedBlock->isValid() )
{
allOk = false;
mReport += "cannot read raster block";
continue;
}
// compare data values
QString htmlTable = QString( "<table style='%1'>" ).arg( mTabStyle );
@ -160,8 +164,8 @@ bool QgsRasterChecker::runTest( QString theVerifiedKey, QString theVerifiedUri,
for ( int col = 0; col < width; col ++ )
{
bool cellOk = true;
double verifiedVal = QgsRasterBlock::readValue( verifiedData, verifiedProvider->dataType( band ), row * width + col );
double expectedVal = QgsRasterBlock::readValue( expectedData, expectedProvider->dataType( band ), row * width + col );
double verifiedVal = verifiedBlock->value( row, col );
double expectedVal = expectedBlock->value( row, col );
QString valStr;
if ( compare( verifiedVal, expectedVal, 0 ) )
@ -182,8 +186,8 @@ bool QgsRasterChecker::runTest( QString theVerifiedKey, QString theVerifiedUri,
mReport += htmlTable;
free( expectedData );
free( verifiedData );
delete expectedBlock;
delete verifiedBlock;
}
delete verifiedProvider;
delete expectedProvider;

View File

@ -43,33 +43,6 @@ void QgsRasterDataProvider::setUseSrcNoDataValue( int bandNo, bool use )
mUseSrcNoDataValue[bandNo-1] = use;
}
//bool QgsRasterDataProvider::hasNoDataValue ( int theBandNo )
//{
//return ( srcHasNoDataValue(theBandNo) && useSrcNoDataValue(theBandNo) ) ||
// mHasInternalNoDataValue[bandNo-1];
//return srcHasNoDataValue(theBandNo) && useSrcNoDataValue(theBandNo);
//}
//bool QgsRasterDataProvider::noDataValue( int bandNo ) const
//{
// return mHasNoDataValue.value( bandNo - 1 );
//}
#if 0
double QgsRasterDataProvider::noDataValue( int bandNo ) const
{
if ( mSrcHasNoDataValue.value( bandNo - 1 ) && mUseSrcNoDataValue.value( bandNo - 1 ) )
{
return mSrcNoDataValue.value( bandNo -1 );
}
//if ( mHasInternalNoDataValue[bandNo-1] )
//{
// return mInternalNoDataValue.value( bandNo -1 );
//}
return std::numeric_limits<double>::quiet_NaN();
}
#endif
QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle const & theExtent, int theWidth, int theHeight )
{
QgsDebugMsg( QString( "theBandNo = %1 theWidth = %2 theHeight = %3" ).arg( theBandNo ).arg( theWidth ).arg( theHeight ) );
@ -232,7 +205,6 @@ QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle cons
}
// apply user no data values
// TODO: there are other readBlock methods where no data are not applied
block->applyNoDataValues( userNoDataValue( theBandNo ) );
return block;
}
@ -254,7 +226,6 @@ QgsRasterDataProvider::QgsRasterDataProvider( QString const & uri )
//Random Static convenience function
//
/////////////////////////////////////////////////////////
//TODO: Change these to private function or make seprate class
// convenience function for building metadata() HTML table cells
// convenience function for creating a string list from a C style string list
QStringList QgsRasterDataProvider::cStringList2Q_( char ** stringList )
@ -271,14 +242,11 @@ QStringList QgsRasterDataProvider::cStringList2Q_( char ** stringList )
} // cStringList2Q_
QString QgsRasterDataProvider::makeTableCell( QString const & value )
{
return "<p>\n" + value + "</p>\n";
} // makeTableCell_
// convenience function for building metadata() HTML table cells
QString QgsRasterDataProvider::makeTableCells( QStringList const & values )
{
@ -303,7 +271,6 @@ QString QgsRasterDataProvider::metadata()
}
// Default implementation for values
//QMap<int, QVariant> QgsRasterDataProvider::identify( const QgsPoint & thePoint, IdentifyFormat theFormat, const QgsRectangle &theExtent, int theWidth, int theHeight )
QgsRasterIdentifyResult QgsRasterDataProvider::identify( const QgsPoint & thePoint, IdentifyFormat theFormat, const QgsRectangle &theExtent, int theWidth, int theHeight )
{
QgsDebugMsg( "Entered" );
@ -369,128 +336,24 @@ QgsRasterIdentifyResult QgsRasterDataProvider::identify( const QgsPoint & thePoi
return QgsRasterIdentifyResult( QgsRasterDataProvider::IdentifyFormatValue, results );
}
#if 0
QMap<QString, QString> QgsRasterDataProvider::identify( const QgsPoint & thePoint, const QgsRectangle &theExtent, int theWidth, int theHeight )
{
QMap<QString, QString> results;
QgsRasterDataProvider::IdentifyFormat identifyFormat;
if ( capabilities() & QgsRasterDataProvider::IdentifyValue )
{
identifyFormat = QgsRasterDataProvider::IdentifyFormatValue;
}
else if ( capabilities() & QgsRasterDataProvider::IdentifyHtml )
{
identifyFormat = QgsRasterDataProvider::IdentifyFormatHtml;
}
else if ( capabilities() & QgsRasterDataProvider::IdentifyText )
{
identifyFormat = QgsRasterDataProvider::IdentifyFormatText;
}
else
{
return results;
}
QgsRasterIdentifyResult myResult = identify( thePoint, identifyFormat, theExtent, theWidth, theHeight );
QMap<int, QVariant> myResults = myResult.results();
if ( identifyFormat == QgsRasterDataProvider::IdentifyFormatValue )
{
foreach ( int bandNo, myResults.keys() )
{
double value = myResults.value( bandNo ).toDouble();
QString valueString;
if ( isNoDataValue( bandNo, value ) )
{
valueString = tr( "no data" );
}
else
{
valueString = QgsRasterBlock::printValue( value );
}
results.insert( generateBandName( bandNo ), valueString );
}
}
else // text or html
{
foreach ( int bandNo, myResults.keys() )
{
QString value = myResults.value( bandNo ).toString();
// TODO: better 'attribute' name, in theory it may be something else than WMS
// feature info
if ( identifyFormat == QgsRasterDataProvider::IdentifyFormatText )
{
value = "<pre>" + value + "</pre>";
}
results.insert( tr( "Feature info" ), value );
}
}
return results;
}
#endif
QString QgsRasterDataProvider::lastErrorFormat()
{
return "text/plain";
}
// pyramids resampling
// TODO move this to gdal provider
// but we need some way to get a static instance of the provider
// or use function pointers like in QgsRasterFormatSaveOptionsWidget::helpOptions()
// see http://www.gdal.org/gdaladdo.html
// http://www.gdal.org/classGDALDataset.html#a2aa6f88b3bbc840a5696236af11dde15
// http://www.gdal.org/classGDALRasterBand.html#afaea945b13ec9c86c2d783b883c68432
// from http://www.gdal.org/gdaladdo.html
// average_mp is unsuitable for use thus not included
// from qgsgdalprovider.cpp (removed)
// NOTE magphase is disabled in the gui since it tends
// to create corrupted images. The images can be repaired
// by running one of the other resampling strategies below.
// see ticket #284
QStringList QgsRasterDataProvider::mPyramidResamplingListGdal = QStringList();
QgsStringMap QgsRasterDataProvider::mPyramidResamplingMapGdal = QgsStringMap();
void QgsRasterDataProvider::initPyramidResamplingDefs()
typedef QList<QPair<QString, QString> > pyramidResamplingMethods_t();
QList<QPair<QString, QString> > QgsRasterDataProvider::pyramidResamplingMethods( QString providerKey )
{
mPyramidResamplingListGdal.clear();
mPyramidResamplingListGdal << tr( "Nearest Neighbour" ) << tr( "Average" ) << tr( "Gauss" ) << tr( "Cubic" ) << tr( "Mode" ) << tr( "None" ); // << tr( "Average magphase" )
mPyramidResamplingMapGdal.clear();
mPyramidResamplingMapGdal[ tr( "Nearest Neighbour" )] = "NEAREST";
mPyramidResamplingMapGdal[ tr( "Average" )] = "AVERAGE";
mPyramidResamplingMapGdal[ tr( "Gauss" )] = "GAUSS";
mPyramidResamplingMapGdal[ tr( "Cubic" )] = "CUBIC";
mPyramidResamplingMapGdal[ tr( "Mode" )] = "MODE";
// mPyramidResamplingMapGdal[ tr( "Average magphase" ) ] = "average_magphase";
mPyramidResamplingMapGdal[ tr( "None" )] = "NONE" ;
}
QStringList QgsRasterDataProvider::pyramidResamplingMethods( QString providerKey )
{
if ( mPyramidResamplingListGdal.isEmpty() )
initPyramidResamplingDefs();
return providerKey == "gdal" ? mPyramidResamplingListGdal : QStringList();
}
QString QgsRasterDataProvider::pyramidResamplingArg( QString method, QString providerKey )
{
if ( providerKey != "gdal" )
return QString();
if ( mPyramidResamplingListGdal.isEmpty() )
initPyramidResamplingDefs();
if ( mPyramidResamplingMapGdal.contains( method ) )
return mPyramidResamplingMapGdal.value( method );
pyramidResamplingMethods_t *pPyramidResamplingMethods = ( pyramidResamplingMethods_t * ) cast_to_fptr( QgsProviderRegistry::instance()->function( providerKey, "pyramidResamplingMethods" ) );
if ( pPyramidResamplingMethods )
{
return pPyramidResamplingMethods();
}
else
return "NEAREST";
{
QgsDebugMsg( "Could not resolve pyramidResamplingMethods provider library" );
}
return QList<QPair<QString, QString> >();
}
bool QgsRasterDataProvider::hasPyramids()
@ -513,46 +376,8 @@ bool QgsRasterDataProvider::hasPyramids()
return false;
}
#if 0
double QgsRasterDataProvider::readValue( void *data, int type, int index )
{
if ( !data )
return std::numeric_limits<double>::quiet_NaN();
switch ( type )
{
case QGis::Byte:
return ( double )(( GByte * )data )[index];
break;
case QGis::UInt16:
return ( double )(( GUInt16 * )data )[index];
break;
case QGis::Int16:
return ( double )(( GInt16 * )data )[index];
break;
case QGis::UInt32:
return ( double )(( GUInt32 * )data )[index];
break;
case QGis::Int32:
return ( double )(( GInt32 * )data )[index];
break;
case QGis::Float32:
return ( double )(( float * )data )[index];
break;
case QGis::Float64:
return ( double )(( double * )data )[index];
break;
default:
QgsLogger::warning( "GDAL data type is not supported" );
}
return std::numeric_limits<double>::quiet_NaN();
}
#endif
void QgsRasterDataProvider::setUserNoDataValue( int bandNo, QgsRasterRangeList noData )
{
//if ( bandNo > bandCount() ) return;
if ( bandNo >= mUserNoDataValue.size() )
{
for ( int i = mUserNoDataValue.size(); i < bandNo; i++ )
@ -668,4 +493,10 @@ QgsRasterInterface::Capability QgsRasterDataProvider::identifyFormatToCapability
}
}
bool QgsRasterDataProvider::userNoDataValueContains( int bandNo, double value ) const
{
QgsRasterRangeList rangeList = mUserNoDataValue.value( bandNo - 1 );
return QgsRasterRange::contains( value, rangeList );
}
// ENDS

View File

@ -20,25 +20,24 @@
#ifndef QGSRASTERDATAPROVIDER_H
#define QGSRASTERDATAPROVIDER_H
#include <cmath>
#include <QDateTime>
#include <QVariant>
#include "qgslogger.h"
#include "qgsrectangle.h"
#include "qgscolorrampshader.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsdataprovider.h"
#include "qgserror.h"
#include "qgsfeature.h"
#include "qgsfield.h"
#include "qgsrasterinterface.h"
#include "qgscolorrampshader.h"
#include "qgsrasterpyramid.h"
#include "qgscoordinatereferencesystem.h"
#include "qgslogger.h"
#include "qgsrasterbandstats.h"
#include "qgsrasterhistogram.h"
#include "qgsrasterinterface.h"
#include "qgsrasterpyramid.h"
#include "qgsrasterrange.h"
#include "cpl_conv.h"
#include <cmath>
#include "qgsrectangle.h"
class QImage;
class QByteArray;
@ -46,23 +45,14 @@ class QByteArray;
class QgsPoint;
class QgsRasterIdentifyResult;
#define TINY_VALUE std::numeric_limits<double>::epsilon() * 20
#define RASTER_HISTOGRAM_BINS 256
/** \ingroup core
* Base class for raster data providers.
*
* \note This class has been copied and pasted from
* QgsVectorDataProvider, and does not yet make
* sense for Raster layers.
*/
class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRasterInterface
{
Q_OBJECT
public:
// This is modified copy of GDALColorInterp
enum ColorInterpretation
{
@ -90,13 +80,10 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
enum IdentifyFormat
{
IdentifyFormatUndefined = 0,
IdentifyFormatValue = 1,
IdentifyFormatText = 1 << 1,
IdentifyFormatHtml = 1 << 2,
// In future it should be possible to get from GetFeatureInfo (WMS) in GML
// vector features. It is possible to use a user type with QVariant if
// a class is declared with Q_DECLARE_METATYPE
IdentifyFormatFeature = 1 << 3
IdentifyFormatValue = 1, // numerical pixel value
IdentifyFormatText = 1 << 1, // WMS text
IdentifyFormatHtml = 1 << 2, // WMS HTML
IdentifyFormatFeature = 1 << 3 // WMS GML -> feature
};
// Progress types
@ -132,27 +119,18 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
/* It makes no sense to set input on provider */
bool setInput( QgsRasterInterface* input ) { Q_UNUSED( input ); return false; }
// TODO: Document this better.
/** \brief Renders the layer as an image
*/
/** \brief Renders the layer as an image */
virtual QImage* draw( const QgsRectangle & viewExtent, int pixelWidth, int pixelHeight ) = 0;
// TODO: Get the supported formats by this provider
// TODO: Get the file masks supported by this provider, suitable for feeding into the file open dialog box
/**
* Get the extent of the data source.
* @return QgsRectangle containing the extent of the layer
*/
/** Get the extent of the data source.
* @return QgsRectangle containing the extent of the layer */
virtual QgsRectangle extent() = 0;
/** Returns data type for the band specified by number */
virtual QGis::DataType dataType( int bandNo ) const = 0;
/** Returns source data type for the band specified by number,
* source data type may be shorter than dataType
*/
* source data type may be shorter than dataType */
virtual QGis::DataType srcDataType( int bandNo ) const = 0;
/** Returns data type for the band specified by number */
@ -232,23 +210,9 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
// TODO: remove or make protected all readBlock working with void*
/** read block of data */
// TODO clarify what happens on the last block (the part outside raster)
// @note not available in python bindings
virtual void readBlock( int bandNo, int xBlock, int yBlock, void *data )
{ Q_UNUSED( bandNo ); Q_UNUSED( xBlock ); Q_UNUSED( yBlock ); Q_UNUSED( data ); }
/** read block of data using give extent and size */
// @note not available in python bindings
virtual void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data )
{ Q_UNUSED( bandNo ); Q_UNUSED( viewExtent ); Q_UNUSED( width ); Q_UNUSED( height ); Q_UNUSED( data ); }
/** Read block of data using given extent and size. */
virtual QgsRasterBlock *block( int theBandNo, const QgsRectangle &theExtent, int theWidth, int theHeight );
/* Read a value from a data block at a given index. */
//virtual double readValue( void *data, int type, int index );
/* Return true if source band has no data value */
virtual bool srcHasNoDataValue( int bandNo ) const { return mSrcHasNoDataValue.value( bandNo -1 ); }
@ -258,14 +222,6 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
/** \brief Set source nodata value usage */
virtual void setUseSrcNoDataValue( int bandNo, bool use );
/** value representing null data */
//virtual double noDataValue() const { return 0; }
/** Value representing currentno data.
* WARNING: this value returned by this method is not constant. It may change
* for example if user disable use of source no data value. */
//virtual double noDataValue( int bandNo ) const;
/** Value representing no data value. */
virtual double srcNoDataValue( int bandNo ) const { return mSrcNoDataValue.value( bandNo -1 ); }
@ -274,14 +230,11 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
/** Get list of user no data value ranges */
virtual QgsRasterRangeList userNoDataValue( int bandNo ) const { return mUserNoDataValue.value( bandNo -1 ); }
virtual double minimumValue( int bandNo ) const { Q_UNUSED( bandNo ); return 0; }
virtual double maximumValue( int bandNo ) const { Q_UNUSED( bandNo ); return 0; }
virtual QList<QgsColorRampShader::ColorRampItem> colorTable( int bandNo ) const
{ Q_UNUSED( bandNo ); return QList<QgsColorRampShader::ColorRampItem>(); }
// Defined in parent
/** \brief Returns the sublayers of this layer - Useful for providers that manage their own layers, such as WMS */
/** \brief Returns the sublayers of this layer - useful for providers that manage
* their own layers, such as WMS */
virtual QStringList subLayers() const
{
return QStringList();
@ -342,9 +295,6 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
//virtual QMap<int, QVariant> identify( const QgsPoint & thePoint, IdentifyFormat theFormat, const QgsRectangle &theExtent = QgsRectangle(), int theWidth = 0, int theHeight = 0 );
virtual QgsRasterIdentifyResult identify( const QgsPoint & thePoint, IdentifyFormat theFormat, const QgsRectangle &theExtent = QgsRectangle(), int theWidth = 0, int theHeight = 0 );
// TODO: remove in 2.0
//QMap<QString, QString> identify( const QgsPoint & thePoint, const QgsRectangle &theExtent = QgsRectangle(), int theWidth = 0, int theHeight = 0 );
/**
* \brief Returns the caption error text for the last error in this provider
*
@ -382,11 +332,6 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
@note: this method was added in version 1.2*/
void setDpi( int dpi ) {mDpi = dpi;}
static QStringList cStringList2Q_( char ** stringList );
static QString makeTableCell( const QString & value );
static QString makeTableCells( const QStringList & values );
/** Time stamp of data source in the moment when data/metadata were loaded by provider */
virtual QDateTime timestamp() const { return mTimestamp; }
@ -406,27 +351,7 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
return false;
}
/** Creates a new dataset with mDataSourceURI
@return true in case of success*/
#if 0
virtual bool create( const QString& format, int nBands,
QGis::DataType type,
int width, int height, double* geoTransform,
const QgsCoordinateReferenceSystem& crs,
QStringList createOptions = QStringList() /*e.v. color table*/ )
{
Q_UNUSED( format );
Q_UNUSED( nBands );
Q_UNUSED( type );
Q_UNUSED( width );
Q_UNUSED( height );
Q_UNUSED( geoTransform );
Q_UNUSED( crs );
Q_UNUSED( createOptions );
return false;
}
#endif
/** Creates a new dataset with mDataSourceURI */
static QgsRasterDataProvider* create( const QString &providerKey,
const QString &uri,
const QString& format, int nBands,
@ -435,23 +360,21 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
const QgsCoordinateReferenceSystem& crs,
QStringList createOptions = QStringList() );
/** Set no data value on created dataset
* @param bandNo band number
* @param noDataValue no data value
*/
virtual bool setNoDataValue( int bandNo, double noDataValue ) { Q_UNUSED( bandNo ); Q_UNUSED( noDataValue ); return false; }
/**Returns the formats supported by create()*/
/** Returns the formats supported by create() */
virtual QStringList createFormats() const { return QStringList(); }
/** Remove dataset*/
virtual bool remove() { return false; }
/** Returns a list of pyramid resampling method names for given provider */
static QStringList pyramidResamplingMethods( QString providerKey = "gdal" );
/** Returns the pyramid resampling argument that corresponds to a given method */
static QString pyramidResamplingArg( QString method, QString providerKey = "gdal" );
/** Returns a list of pyramid resampling method name and label pairs
* for given provider */
static QList<QPair<QString, QString> > pyramidResamplingMethods( QString providerKey );
/** Validates creation options for a specific dataset and destination format.
* @note used by GDAL provider only
@ -477,7 +400,25 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
void progressUpdate( int theProgress );
protected:
/**Dots per inch. Extended WMS (e.g. QGIS mapserver) support DPI dependent output and therefore
/** Read block of data
* @note not available in python bindings */
virtual void readBlock( int bandNo, int xBlock, int yBlock, void *data )
{ Q_UNUSED( bandNo ); Q_UNUSED( xBlock ); Q_UNUSED( yBlock ); Q_UNUSED( data ); }
/** Read block of data using give extent and size
* @note not available in python bindings */
virtual void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data )
{ Q_UNUSED( bandNo ); Q_UNUSED( viewExtent ); Q_UNUSED( width ); Q_UNUSED( height ); Q_UNUSED( data ); }
/** Returns true if user no data contains value */
bool userNoDataValueContains( int bandNo, double value ) const;
static QStringList cStringList2Q_( char ** stringList );
static QString makeTableCell( const QString & value );
static QString makeTableCells( const QStringList & values );
/** Dots per inch. Extended WMS (e.g. QGIS mapserver) support DPI dependent output and therefore
are suited for printing. A value of -1 means it has not been set
@note: this member has been added in version 1.2*/
int mDpi;
@ -492,31 +433,11 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
/** \brief Source no data value exists. */
QList<bool> mSrcHasNoDataValue;
/** \brief No data value exists. May exist even if source no data value does not
* exist, for example, if data type is wide enough a large number is used as no data. */
//QList<bool> mHasNoDataValue;
/** \brief Use source nodata value. User can disable usage of source nodata
* value as nodata. It may happen that a value is wrongly given by GDAL
* as nodata (e.g. 0) and it has to be treated as regular value. */
QList<bool> mUseSrcNoDataValue;
/** \brief Internal no data value was set and is used. */
//QList<bool> mHasInternalNoDataValue;
/** \brief Internal value representing nodata. Indexed from 0.
* This values is used to represent nodata if no source nodata is available
* or if the source nodata use was disabled.
* It would be also possible to use wider type only if nodata is really necessary
* in following interfaces, but that could make difficult to subclass
* QgsRasterInterface.
*/
// TODO: probably remove (move to providers if used)
QList<double> mInternalNoDataValue;
/** \brief Flag indicating if the nodatavalue is valid*/
//bool mValidNoDataValue;
/** \brief List of lists of user defined additional no data values
* for each band, indexed from 0 */
QList< QgsRasterRangeList > mUserNoDataValue;

View File

@ -159,23 +159,6 @@ QgsRasterRenderer* QgsRasterRendererRegistry::defaultRendererForDrawingStyle( co
provider->dataType( grayBand ) ) );
// Default contrast enhancement is set from QgsRasterLayer, it has already setContrastEnhancementAlgorithm(). Default enhancement must only be set if default style was not loaded (to avoid stats calculation).
// TODO: reconsider moving contrast setting of enhancement somwhere down from QgsRasterLayer
#if 0
QSettings s;
QgsContrastEnhancement::ContrastEnhancementAlgorithm ceAlgorithm;
ceAlgorithm = QgsContrastEnhancement::contrastEnhancementAlgorithmFromString(
s.value( "/Raster/defaultContrastEnhancementAlgorithm", "NoEnhancement" ).toString() );
ce->setContrastEnhancementAlgorithm( ceAlgorithm );
if ( ceAlgorithm != QgsContrastEnhancement::NoEnhancement )
{
double minValue = 0;
double maxValue = 0;
minMaxValuesForBand( grayBand, provider, minValue, maxValue );
ce->setMinimumValue( minValue );
ce->setMaximumValue( maxValue );
}
#endif
(( QgsSingleBandGrayRenderer* )renderer )->setContrastEnhancement( ce );
break;
}
@ -193,15 +176,6 @@ QgsRasterRenderer* QgsRasterRendererRegistry::defaultRendererForDrawingStyle( co
case QgsRasterLayer::MultiBandColor:
{
QSettings s;
#if 0
QgsContrastEnhancement::ContrastEnhancementAlgorithm ceAlgorithm;
ceAlgorithm = QgsContrastEnhancement::contrastEnhancementAlgorithmFromString(
s.value( "/Raster/defaultContrastEnhancementAlgorithm", "NoEnhancement" ).toString() );
QgsContrastEnhancement* redEnhancement = 0;
QgsContrastEnhancement* greenEnhancement = 0;
QgsContrastEnhancement* blueEnhancement = 0;
#endif
int redBand = s.value( "/Raster/defaultRedBand", 1 ).toInt();
if ( redBand < 0 || redBand > provider->bandCount() )
@ -219,45 +193,6 @@ QgsRasterRenderer* QgsRasterRendererRegistry::defaultRendererForDrawingStyle( co
blueBand = -1;
}
#if 0
double minValue = 0;
double maxValue = 0;
if ( ceAlgorithm != QgsContrastEnhancement::NoEnhancement )
{
if ( redBand > 0 )
{
redEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )(
provider->dataType( redBand ) ) );
minMaxValuesForBand( redBand, provider, minValue, maxValue );
redEnhancement->setMinimumValue( minValue );
redEnhancement->setMaximumValue( maxValue );
redEnhancement->setContrastEnhancementAlgorithm( ceAlgorithm );
}
if ( greenBand > 0 )
{
greenEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )(
provider->dataType( greenBand ) ) );
minMaxValuesForBand( greenBand, provider, minValue, maxValue );
greenEnhancement->setMinimumValue( minValue );
greenEnhancement->setMaximumValue( maxValue );
greenEnhancement->setContrastEnhancementAlgorithm( ceAlgorithm );
}
if ( blueBand > 0 )
{
blueEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )(
provider->dataType( blueBand ) ) );
minMaxValuesForBand( blueBand, provider, minValue, maxValue );
blueEnhancement->setMinimumValue( minValue );
blueEnhancement->setMaximumValue( maxValue );
blueEnhancement->setContrastEnhancementAlgorithm( ceAlgorithm );
}
}
renderer = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand,
redEnhancement, greenEnhancement, blueEnhancement );
#endif
renderer = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand );
break;
}
@ -283,35 +218,6 @@ QgsRasterRenderer* QgsRasterRendererRegistry::defaultRendererForDrawingStyle( co
tr->setTransparentThreeValuePixelList( transparentThreeValueList );
}
renderer->setRasterTransparency( tr );
#if 0
if ( !renderer )
{
return;
}
renderer->setOpacity( mTransparencyLevel / 255.0 );
QgsRasterTransparency* tr = new QgsRasterTransparency(); //renderer takes ownership
if ( mDataProvider->bandCount() == 1 )
{
tr->setTransparentSingleValuePixelList( mRasterTransparency.transparentSingleValuePixelList() );
}
else if ( mDataProvider->bandCount() == 3 )
{
tr->setTransparentThreeValuePixelList( mRasterTransparency.transparentThreeValuePixelList() );
}
renderer->setRasterTransparency( tr );
if ( mTransparencyBandName != TRSTRING_NOT_SET )
{
int tBand = bandNumber( mTransparencyBandName );
if ( tBand > 0 )
{
renderer->setAlphaBand( tBand );
}
}
renderer->setInvertColor( mInvertColor );
#endif //0
return renderer;
}
@ -322,23 +228,24 @@ bool QgsRasterRendererRegistry::minMaxValuesForBand( int band, QgsRasterDataProv
return false;
}
minValue = 0;
maxValue = 0;
QSettings s;
if ( s.value( "/Raster/useStandardDeviation", false ).toBool() )
{
QgsRasterBandStats stats = provider->bandStatistics( band, QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev );
double stdDevFactor = s.value( "/Raster/defaultStandardDeviation", 2.0 ).toDouble();
QgsRasterBandStats stats = provider->bandStatistics( band );
double diff = stdDevFactor * stats.stdDev;
minValue = stats.mean - diff;
maxValue = stats.mean + diff;
}
else
{
minValue = provider->minimumValue( band );
maxValue = provider->maximumValue( band );
QgsRasterBandStats stats = provider->bandStatistics( band, QgsRasterBandStats::Min | QgsRasterBandStats::Max );
minValue = stats.minimumValue;
maxValue = stats.maximumValue;
}
return true;
}

View File

@ -62,10 +62,13 @@ void QgsRasterPyramidsOptionsWidget::updateUi()
// initialize resampling methods
cboResamplingMethod->clear();
foreach ( QString method, QgsRasterDataProvider::pyramidResamplingMethods( mProvider ) )
cboResamplingMethod->addItem( method );
cboResamplingMethod->setCurrentIndex( cboResamplingMethod->findText(
mySettings.value( prefix + "resampling", "Average" ).toString() ) );
QPair<QString, QString> method;
foreach ( method, QgsRasterDataProvider::pyramidResamplingMethods( mProvider ) )
{
cboResamplingMethod->addItem( method.second, method.first );
}
cboResamplingMethod->setCurrentIndex( cboResamplingMethod->findData(
mySettings.value( prefix + "resampling", "AVERAGE" ).toString() ) );
// validate string, only space-separated positive integers are allowed
lePyramidsLevels->setEnabled( cbxPyramidsLevelsCustom->isChecked() );
@ -112,7 +115,7 @@ void QgsRasterPyramidsOptionsWidget::updateUi()
QString QgsRasterPyramidsOptionsWidget::resamplingMethod() const
{
return QgsRasterDataProvider::pyramidResamplingArg( cboResamplingMethod->currentText().trimmed() );
return cboResamplingMethod->itemData( cboResamplingMethod->currentIndex() ).toString();
}
void QgsRasterPyramidsOptionsWidget::apply()
@ -129,7 +132,7 @@ void QgsRasterPyramidsOptionsWidget::apply()
else
tmpStr = "external";
mySettings.setValue( prefix + "format", tmpStr );
mySettings.setValue( prefix + "resampling", cboResamplingMethod->currentText().trimmed() );
mySettings.setValue( prefix + "resampling", resamplingMethod() );
mySettings.setValue( prefix + "overviewStr", lePyramidsLevels->text().trimmed() );
// overview list

View File

@ -42,6 +42,8 @@
#include <qwt_plot_renderer.h>
#endif
#define RASTER_HISTOGRAM_BINS 256
QgsRasterHistogramWidget::QgsRasterHistogramWidget( QgsRasterLayer* lyr, QWidget *parent )
: QWidget( parent ),
mRasterLayer( lyr ), mRendererWidget( 0 )
@ -206,7 +208,7 @@ void QgsRasterHistogramWidget::on_btnHistoCompute_clicked()
bool QgsRasterHistogramWidget::computeHistogram( bool forceComputeFlag )
{
const int BINCOUNT = RASTER_HISTOGRAM_BINS; // 256 - defined in qgsrasterdataprovider.h
const int BINCOUNT = RASTER_HISTOGRAM_BINS;
//bool myIgnoreOutOfRangeFlag = true;
//bool myThoroughBandScanFlag = false;
int myBandCountInt = mRasterLayer->bandCount();
@ -262,7 +264,7 @@ void QgsRasterHistogramWidget::refreshHistogram()
// bin in all selected layers, and the min. It then draws a scaled line between min
// and max - scaled to image height. 1 line drawn per selected band
//
const int BINCOUNT = RASTER_HISTOGRAM_BINS; // 256 - defined in qgsrasterdataprovider.h
const int BINCOUNT = RASTER_HISTOGRAM_BINS;
int myBandCountInt = mRasterLayer->bandCount();
QgsDebugMsg( "entered." );

View File

@ -815,6 +815,7 @@ double QgsGdalProvider::noDataValue() const
}
#endif
#if 0
void QgsGdalProvider::computeMinMax( int theBandNo ) const
{
QgsDebugMsg( QString( "theBandNo = %1 mMinMaxComputed = %2" ).arg( theBandNo ).arg( mMinMaxComputed[theBandNo-1] ) );
@ -834,27 +835,7 @@ void QgsGdalProvider::computeMinMax( int theBandNo ) const
mMinimum[theBandNo-1] = adfMinMax[0];
mMaximum[theBandNo-1] = adfMinMax[1];
}
double QgsGdalProvider::minimumValue( int theBandNo ) const
{
QgsDebugMsg( QString( "theBandNo = %1" ).arg( theBandNo ) );
if ( !mMinMaxComputed[theBandNo-1] )
{
computeMinMax( theBandNo );
mMinMaxComputed[theBandNo-1] = true;
}
return mMinimum[theBandNo-1];
}
double QgsGdalProvider::maximumValue( int theBandNo ) const
{
QgsDebugMsg( QString( "theBandNo = %1" ).arg( theBandNo ) );
if ( !mMinMaxComputed[theBandNo-1] )
{
computeMinMax( theBandNo );
mMinMaxComputed[theBandNo-1] = true;
}
return mMaximum[theBandNo-1];
}
#endif
/**
* @param theBandNumber the number of the band for which you want a color table
@ -2286,13 +2267,14 @@ QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, int theStats,
void QgsGdalProvider::initBaseDataset()
{
#if 0
for ( int i = 0; i < GDALGetRasterCount( mGdalBaseDataset ); i++ )
{
mMinMaxComputed.append( false );
mMinimum.append( 0 );
mMaximum.append( 0 );
}
#endif
// Check if we need a warped VRT for this file.
bool hasGeoTransform = GDALGetGeoTransform( mGdalBaseDataset, mGeoTransform ) == CE_None;
if (( hasGeoTransform
@ -2755,3 +2737,32 @@ QString QgsGdalProvider::validatePyramidsCreationOptions( RasterPyramidsFormat p
return QString();
}
// pyramids resampling
// see http://www.gdal.org/gdaladdo.html
// http://www.gdal.org/classGDALDataset.html#a2aa6f88b3bbc840a5696236af11dde15
// http://www.gdal.org/classGDALRasterBand.html#afaea945b13ec9c86c2d783b883c68432
// from http://www.gdal.org/gdaladdo.html
// average_mp is unsuitable for use thus not included
// from qgsgdalprovider.cpp (removed)
// NOTE magphase is disabled in the gui since it tends
// to create corrupted images. The images can be repaired
// by running one of the other resampling strategies below.
// see ticket #284
QGISEXTERN QList<QPair<QString, QString> > pyramidResamplingMethods()
{
QList<QPair<QString, QString> > methods;
methods.append( QPair<QString, QString>( "NEAREST", QObject::tr( "Nearest Neighbour" ) ) );
methods.append( QPair<QString, QString>( "AVERAGE", QObject::tr( "Average" ) ) );
methods.append( QPair<QString, QString>( "GAUSS", QObject::tr( "Gauss" ) ) );
methods.append( QPair<QString, QString>( "CUBIC", QObject::tr( "Cubic" ) ) );
methods.append( QPair<QString, QString>( "MODE", QObject::tr( "Mode" ) ) );
methods.append( QPair<QString, QString>( "NONE", QObject::tr( "None" ) ) );
return methods;
}

View File

@ -175,14 +175,6 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
void readBlock( int bandNo, int xBlock, int yBlock, void *data );
void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data );
//void * readBlock( int bandNo, QgsRectangle const & extent, int width, int height );
//bool srcHasNoDataValue( int bandNo ) const;
//double noDataValue() const;
void computeMinMax( int bandNo ) const;
double minimumValue( int bandNo ) const;
double maximumValue( int bandNo ) const;
QList<QgsColorRampShader::ColorRampItem> colorTable( int bandNo )const;
/**
@ -294,13 +286,13 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
int mXBlockSize;
int mYBlockSize;
mutable QList<bool> mMinMaxComputed;
//mutable QList<bool> mMinMaxComputed;
// List of estimated min values, index 0 for band 1
mutable QList<double> mMinimum;
//mutable QList<double> mMinimum;
// List of estimated max values, index 0 for band 1
mutable QList<double> mMaximum;
//mutable QList<double> mMaximum;
/** \brief Pointer to the gdaldataset */
GDALDatasetH mGdalBaseDataset;
@ -317,7 +309,6 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
/** \brief sublayers list saved for subsequent access */
QStringList mSubLayers;
};
#endif

View File

@ -127,7 +127,7 @@ QgsGrassRasterProvider::QgsGrassRasterProvider( QString const & uri )
//myInternalNoDataValue = -1e+30;
myInternalNoDataValue = std::numeric_limits<float>::quiet_NaN();
}
mInternalNoDataValue.append( myInternalNoDataValue );
mNoDataValue = myInternalNoDataValue;
QgsDebugMsg( QString( "myInternalNoDataValue = %1" ).arg( myInternalNoDataValue ) );
// TODO: refresh mRows and mCols if raster was rewritten
@ -303,17 +303,6 @@ void QgsGrassRasterProvider::readBlock( int bandNo, QgsRectangle const & viewEx
memcpy( block, data.data(), size );
}
double QgsGrassRasterProvider::minimumValue( int bandNo ) const
{
Q_UNUSED( bandNo );
return mInfo["MIN_VALUE"].toDouble();
}
double QgsGrassRasterProvider::maximumValue( int bandNo ) const
{
Q_UNUSED( bandNo );
return mInfo["MAX_VALUE"].toDouble();
}
QgsRasterBandStats QgsGrassRasterProvider::bandStatistics( int theBandNo, int theStats, const QgsRectangle & theExtent, int theSampleSize )
{
QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );
@ -468,7 +457,7 @@ QgsRasterIdentifyResult QgsGrassRasterProvider::identify( const QgsPoint & thePo
}
// no data?
if ( qIsNaN( value ) || qgsDoubleNear( value, mInternalNoDataValue[0] ) )
if ( qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue ) )
{
return noDataResult;
}

View File

@ -184,14 +184,9 @@ class QgsGrassRasterProvider : public QgsRasterDataProvider
int xSize() const;
int ySize() const;
void readBlock( int bandNo, int xBlock, int yBlock, void *data );
void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data );
//double noDataValue() const;
double minimumValue( int bandNo )const;
double maximumValue( int bandNo )const;
QgsRasterBandStats bandStatistics( int theBandNo,
int theStats = QgsRasterBandStats::All,
const QgsRectangle & theExtent = QgsRectangle(),
@ -232,7 +227,7 @@ class QgsGrassRasterProvider : public QgsRasterDataProvider
QgsGrassRasterValue mRasterValue;
//double mNoDataValue;
double mNoDataValue;
};
#endif

View File

@ -62,6 +62,8 @@
#include "cpl_conv.h"
#include "cpl_string.h"
#define TINY_VALUE std::numeric_limits<double>::epsilon() * 20
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
#define TO8F(x) (x).toUtf8().constData()
#define FROM8(x) QString::fromUtf8(x)

View File

@ -44,6 +44,7 @@ class QNetworkRequest;
#define CPL_SUPRESS_CPLUSPLUS
#include <gdal.h>
#include "cpl_conv.h"
/**