205 changes: 18 additions & 187 deletions src/core/raster/qgsrasterdataprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) );
Expand Down Expand Up @@ -106,7 +79,7 @@ QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle cons
double tmpXRes, tmpYRes;
double providerXRes = 0;
double providerYRes = 0;
if ( capabilities() & ExactResolution )
if ( capabilities() & Size )
{
providerXRes = extent().width() / xSize();
providerYRes = extent().height() / ySize();
Expand Down Expand Up @@ -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;
}
Expand All @@ -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 )
Expand All @@ -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 )
{
Expand All @@ -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" );
Expand Down Expand Up @@ -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()
{
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 )
typedef QList<QPair<QString, QString> > pyramidResamplingMethods_t();
QList<QPair<QString, QString> > QgsRasterDataProvider::pyramidResamplingMethods( 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()
Expand All @@ -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++ )
Expand Down Expand Up @@ -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
171 changes: 42 additions & 129 deletions src/core/raster/qgsrasterdataprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,49 +20,39 @@
#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;

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
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -230,33 +208,11 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
return colorName( colorInterpretation( theBandNo ) );
}

/** Get block size */
//virtual int xBlockSize() const { return 0; }
//virtual int yBlockSize() const { return 0; }

/** Get raster size */
//virtual int xSize() const { return 0; }
//virtual int ySize() const { return 0; }

// 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 ); }

Expand All @@ -266,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 ); }

Expand All @@ -282,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();
Expand Down Expand Up @@ -350,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
*
Expand Down Expand Up @@ -390,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; }

Expand All @@ -414,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,
Expand All @@ -443,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
Expand All @@ -485,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;
Expand All @@ -500,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;
Expand Down
119 changes: 11 additions & 108 deletions src/core/raster/qgsrasterinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,21 @@
#include <qmath.h>

#include "qgslogger.h"
#include "qgsrasterinterface.h"
#include "qgsrasterbandstats.h"
#include "qgsrasterhistogram.h"
#include "qgsrasterinterface.h"
#include "qgsrectangle.h"

//#include "cpl_conv.h"

QgsRasterInterface::QgsRasterInterface( QgsRasterInterface * input )
: mInput( input )
, mOn( true )
//, mStatsOn( false )
{
}

QgsRasterInterface::~QgsRasterInterface()
{
}

//bool QgsRasterInterface::isNoDataValue( int bandNo, double value ) const
//{
// return QgsRasterBlock::isNoDataValue( value, noDataValue( bandNo ) );
//}

void QgsRasterInterface::initStatistics( QgsRasterBandStats &theStatistics,
int theBandNo,
int theStats,
Expand Down Expand Up @@ -168,8 +160,6 @@ QgsRasterBandStats QgsRasterInterface::bandStatistics( int theBandNo,
int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;

// void *myData = qgsMalloc( myXBlockSize * myYBlockSize * ( QgsRasterBlock::typeSize( dataType( theBandNo ) ) ) );

double myXRes = myExtent.width() / myWidth;
double myYRes = myExtent.height() / myHeight;
// TODO: progress signals
Expand All @@ -194,20 +184,14 @@ QgsRasterBandStats QgsRasterInterface::bandStatistics( int theBandNo,

QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );

//readBlock( theBandNo, myPartExtent, myBlockWidth, myBlockHeight, myData );
QgsRasterBlock* blk = block( theBandNo, myPartExtent, myBlockWidth, myBlockHeight );

// Collect the histogram counts.
for ( size_t i = 0; i < (( size_t ) myBlockHeight ) * myBlockWidth; i++ )
{
if ( blk->isNoData( i ) )
{
continue; // NULL
}
if ( blk->isNoData( i ) ) continue; // NULL

//double myValue = readValue( myData, myDataType, myX + ( myY * myBlockWidth ) );
double myValue = blk->value( i );
//QgsDebugMsg ( QString ( "%1 %2 value %3" ).arg (myX).arg(myY).arg( myValue ) );

myRasterBandStats.sum += myValue;
myRasterBandStats.elementCount++;
Expand All @@ -230,9 +214,6 @@ QgsRasterBandStats QgsRasterInterface::bandStatistics( int theBandNo,
}
}

//myRasterBandStats.sumOfSquares += static_cast < double >
// ( qPow( myValue - myRasterBandStats.mean, 2 ) );

// Single pass stdev
double myDelta = myValue - myMean;
myMean += myDelta / myRasterBandStats.elementCount;
Expand All @@ -258,8 +239,6 @@ QgsRasterBandStats QgsRasterInterface::bandStatistics( int theBandNo,
QgsDebugMsg( QString( "MEAN %1" ).arg( myRasterBandStats.mean ) );
QgsDebugMsg( QString( "STDDEV %1" ).arg( myRasterBandStats.stdDev ) );

//qgsFree( myData );

myRasterBandStats.statsGathered = QgsRasterBandStats::All;
mStatistics.append( myRasterBandStats );

Expand Down Expand Up @@ -291,7 +270,7 @@ void QgsRasterInterface::initHistogram( QgsRasterHistogram &theHistogram,
}
else
{
// We need statistcs -> avoid histogramDefaults in hasHistogram if possible
// We need statistics -> avoid histogramDefaults in hasHistogram if possible
// TODO: use approximated statistics if aproximated histogram is requested
// (theSampleSize > 0)
QgsRasterBandStats stats = bandStatistics( theBandNo, QgsRasterBandStats::Min, theExtent, theSampleSize );
Expand Down Expand Up @@ -431,8 +410,6 @@ QgsRasterHistogram QgsRasterInterface::histogram( int theBandNo,
QgsRectangle myExtent = myHistogram.extent;
myHistogram.histogramVector.resize( myBinCount );

//int myDataType = dataType( theBandNo );

int myXBlockSize = xBlockSize();
int myYBlockSize = yBlockSize();
if ( myXBlockSize == 0 ) // should not happen, but happens
Expand All @@ -447,8 +424,6 @@ QgsRasterHistogram QgsRasterInterface::histogram( int theBandNo,
int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;

//void *myData = qgsMalloc( myXBlockSize * myYBlockSize * ( QgsRasterBlock::typeSize( dataType( theBandNo ) ) ) );

double myXRes = myExtent.width() / myWidth;
double myYRes = myExtent.height() / myHeight;

Expand Down Expand Up @@ -480,7 +455,6 @@ QgsRasterHistogram QgsRasterInterface::histogram( int theBandNo,

QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );

//readBlock( theBandNo, myPartExtent, myBlockWidth, myBlockHeight, myData );
QgsRasterBlock* blk = block( theBandNo, myPartExtent, myBlockWidth, myBlockHeight );

// Collect the histogram counts.
Expand All @@ -492,10 +466,7 @@ QgsRasterHistogram QgsRasterInterface::histogram( int theBandNo,
}
double myValue = blk->value( i );

//QgsDebugMsg ( QString ( "%1 %2 value %3" ).arg (myX).arg(myY).arg( myValue ) );

int myBinIndex = static_cast <int>( qFloor(( myValue - myMinimum ) / myBinSize ) ) ;
//QgsDebugMsg( QString( "myValue = %1 myBinIndex = %2" ).arg( myValue ).arg( myBinIndex ) );

if (( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !theIncludeOutOfRange )
{
Expand All @@ -510,8 +481,6 @@ QgsRasterHistogram QgsRasterInterface::histogram( int theBandNo,
}
}

//qgsFree( myData );

myHistogram.valid = true;
mHistograms.append( myHistogram );

Expand Down Expand Up @@ -572,16 +541,15 @@ QString QgsRasterInterface::capabilitiesString() const

int abilities = capabilities();

// Not all all capabilities are here (Size, IdentifyValue, IdentifyText,
// IdentifyHtml, IdentifyFeature) because those are quite technical and probably
// would be confusing for users

if ( abilities & QgsRasterInterface::Identify )
{
abilitiesList += tr( "Identify" );
}

if ( abilities & QgsRasterInterface::BuildPyramids )
{
abilitiesList += tr( "Build Pyramids" );
}

if ( abilities & QgsRasterInterface::Create )
{
abilitiesList += tr( "Create Datasources" );
Expand All @@ -592,77 +560,12 @@ QString QgsRasterInterface::capabilitiesString() const
abilitiesList += tr( "Remove Datasources" );
}

QgsDebugMsg( "Capability: " + abilitiesList.join( ", " ) );

return abilitiesList.join( ", " );
}

#if 0
// version with time counting
void * QgsRasterInterface::block( int bandNo, QgsRectangle const & extent, int width, int height )
{
QTime time;
time.start();

void * b = 0;

if ( !mOn )
{
// Switched off, pass input data unchanged
if ( mInput )
{
b = mInput->block( bandNo, extent, width, height );
}
}
else
{
b = readBlock( bandNo, extent, width, height );
}

if ( mStatsOn )
{
if ( mTime.size() <= bandNo )
{
mTime.resize( bandNo + 1 );
}
// QTime counts only in miliseconds
// We are adding time until next clear, this way the time may be collected
// for the whole QgsRasterLayer::draw() for example, not just for a single part
mTime[bandNo] += time.elapsed();
QgsDebugMsg( QString( "bandNo = %2 time = %3" ).arg( bandNo ).arg( mTime[bandNo] ) );
}
return b;
}
#endif

#if 0
void QgsRasterInterface::setStatsOn( bool on )
{
if ( on )
if ( abilities & QgsRasterInterface::BuildPyramids )
{
mTime.clear();
abilitiesList += tr( "Build Pyramids" );
}
if ( mInput ) mInput->setStatsOn( on );
mStatsOn = on;
}

double QgsRasterInterface::time( bool cumulative )
{
// We can calculate total time only, because we have to subtract time of previous
// interface(s) and we don't know how to assign bands to each other
double t = 0;
for ( int i = 1; i < mTime.size(); i++ )
{
t += mTime[i];
}
if ( cumulative ) return t;
QgsDebugMsg( "Capability: " + abilitiesList.join( ", " ) );

if ( mInput )
{
QgsDebugMsgLevel( QString( "%1 cumulative time = %2 time = %3" ).arg( typeid( *( this ) ).name() ).arg( t ).arg( t - mInput->time( true ) ), 3 );
t -= mInput->time( true );
}
return t;
return abilitiesList.join( ", " );
}
#endif

102 changes: 14 additions & 88 deletions src/core/raster/qgsrasterinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,52 +24,33 @@
#include <QImage>

#include "qgslogger.h"
#include "qgsrasterblock.h"
#include "qgsrectangle.h"
#include "qgsrasterbandstats.h"
#include "qgsrasterblock.h"
#include "qgsrasterhistogram.h"
#include "qgsrectangle.h"

/** \ingroup core
* Base class for processing modules.
* Base class for processing filters like renderers, reprojector, resampler etc.
*/
// TODO: inherit from QObject? It would be probably better but QgsDataProvider inherits already from QObject and multiple inheritance from QObject is not allowed
class CORE_EXPORT QgsRasterInterface
{
Q_DECLARE_TR_FUNCTIONS( QgsRasterInterface );

public:

//! If you add to this, please also add to capabilitiesString()
enum Capability
{
NoCapabilities = 0,
Identify = 1,
ExactMinimumMaximum = 1 << 1,
ExactResolution = 1 << 2,
EstimatedMinimumMaximum = 1 << 3,
BuildPyramids = 1 << 4,
Histogram = 1 << 5,
Size = 1 << 6, // has fixed source type
Create = 1 << 7, //create new datasets
Remove = 1 << 8, //delete datasets
IdentifyValue = 1 << 9,
IdentifyText = 1 << 10,
IdentifyHtml = 1 << 11,
IdentifyFeature = 1 << 12 // WMS GML -> feature
};


#if 0
struct Range
{
double min;
double max;
inline bool operator==( const Range &o ) const
{
return min == o.min && max == o.max;
}
Size = 1 << 1, // original data source size (and thus resolution) is known, it is not always available, for example for WMS
Create = 1 << 2, // create new datasets
Remove = 1 << 3, // delete datasets
BuildPyramids = 1 << 4, // supports building of pyramids (overviews)
Identify = 1 << 5, // at least one identify format supported
IdentifyValue = 1 << 6, // numerical values
IdentifyText = 1 << 7, // WMS text
IdentifyHtml = 1 << 8, // WMS HTML
IdentifyFeature = 1 << 9 // WMS GML -> feature
};
#endif

QgsRasterInterface( QgsRasterInterface * input = 0 );

Expand All @@ -78,8 +59,7 @@ class CORE_EXPORT QgsRasterInterface
/** Clone itself, create deep copy */
virtual QgsRasterInterface *clone() const = 0;

/** Returns a bitmask containing the supported capabilities
*/
/** Returns a bitmask containing the supported capabilities */
virtual int capabilities() const
{
return QgsRasterInterface::NoCapabilities;
Expand All @@ -94,8 +74,7 @@ class CORE_EXPORT QgsRasterInterface
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 { if ( mInput ) return mInput->srcDataType( bandNo ); else return QGis::UnknownDataType; };

/**
Expand Down Expand Up @@ -123,27 +102,6 @@ class CORE_EXPORT QgsRasterInterface
return tr( "Band" ) + QString( " %1" ) .arg( theBandNumber, 1 + ( int ) log10(( float ) bandCount() ), 10, QChar( '0' ) );
}

/** True if the interface has a no data value.
* It does not change during the life of the interface.
* @param bandNo band number
* @return true if the interface has a no data value */
//virtual bool hasNoDataValue( int bandNo ) const { Q_UNUSED( bandNo ); return false; }

/** Return no data value for specific band. Each band/provider must have
* no data value, if there is no one set in original data, provider decides one
* possibly using wider data type.
* @param bandNo band number
* @return No data value */
//virtual double noDataValue( int bandNo ) const { Q_UNUSED( bandNo ); return std::numeric_limits<double>::quiet_NaN(); }

#if 0
/** Test if value is nodata for specific band
* @param bandNo band number
* @param value tested value
* @return true if value is nodata */
virtual bool isNoDataValue( int bandNo, double value ) const;
#endif

/** Read block of data using given extent and size.
* Returns pointer to data.
* Caller is responsible to free the memory returned.
Expand All @@ -153,22 +111,6 @@ class CORE_EXPORT QgsRasterInterface
* @param height pixel height of block
*/
virtual QgsRasterBlock *block( int bandNo, const QgsRectangle &extent, int width, int height ) = 0;
//void *block( int bandNo, const QgsRectangle &extent, int width, int height );

#if 0
/** Read block of data using given extent and size.
* Method to be implemented by subclasses.
* Returns pointer to data.
* Caller is responsible to free the memory returned.
*/
virtual void *readBlock( int bandNo, const QgsRectangle &extent, int width, int height )
virtual QgsRasterBlock *readBlock( int bandNo, const QgsRectangle &extent, int width, int height ) const = 0;

{
Q_UNUSED( bandNo ); Q_UNUSED( extent ); Q_UNUSED( width ); Q_UNUSED( height );
return new QgsRasterBlock();
}
#endif

/** Set input.
* Returns true if set correctly, false if cannot use that input */
Expand Down Expand Up @@ -265,15 +207,6 @@ class CORE_EXPORT QgsRasterInterface
const QgsRectangle & theExtent = QgsRectangle(),
int theSampleSize = 0 );

/** Switch on (and clear old statistics) or off collection of statistics */
//void setStatsOn( bool on );

/** Last total time (for allbands) consumed by this interface for call to block()
* If cumulative is true, the result includes also time spent in all preceding
* interfaces. If cumulative is false, only time consumed by this interface is
* returned. */
//double time( bool cumulative = false );

/** Write base class members to xml. */
virtual void writeXML( QDomDocument& doc, QDomElement& parentElem ) const { Q_UNUSED( doc ); Q_UNUSED( parentElem ); }
/** Sets base class members from xml. Usually called from create() methods of subclasses */
Expand Down Expand Up @@ -308,13 +241,6 @@ class CORE_EXPORT QgsRasterInterface
int theStats = QgsRasterBandStats::All,
const QgsRectangle & theExtent = QgsRectangle(),
int theBinCount = 0 );

private:
// Last rendering cumulative (this and all preceding interfaces) times, from index 1
//QVector<double> mTime;

// Collect statistics
//int mStatsOn;
};

#endif
Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1454,7 +1454,7 @@ double QgsRasterLayer::rasterUnitsPerPixel()
// horisontal one.

//return qAbs( mGeoTransform[1] );
if ( mDataProvider->capabilities() & QgsRasterDataProvider::ExactResolution && mDataProvider->xSize() > 0 )
if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size && mDataProvider->xSize() > 0 )
{
return mDataProvider->extent().width() / mDataProvider->xSize();
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterprojector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ void QgsRasterProjector::calc()
if ( mInput )
{
QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider*>( mInput->srcInput() );
if ( provider && ( provider->capabilities() & QgsRasterDataProvider::ExactResolution ) )
if ( provider && ( provider->capabilities() & QgsRasterDataProvider::Size ) )
{
mMaxSrcXRes = provider->extent().width() / provider->xSize();
mMaxSrcYRes = provider->extent().height() / provider->ySize();
Expand Down
103 changes: 5 additions & 98 deletions src/core/raster/qgsrasterrendererregistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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() )
Expand All @@ -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;
}
Expand All @@ -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;
}

Expand All @@ -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;
}
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterresamplefilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ QgsRasterBlock * QgsRasterResampleFilter::block( int bandNo, QgsRectangle const
{
QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider*>( mInput->srcInput() );
// Do not oversample if data source does not have fixed resolution (WMS)
if ( provider && ( provider->capabilities() & QgsRasterDataProvider::ExactResolution ) )
if ( provider && ( provider->capabilities() & QgsRasterDataProvider::Size ) )
{
double xRes = extent.width() / width;
double providerXRes = provider->extent().width() / provider->xSize();
Expand Down
256 changes: 35 additions & 221 deletions src/core/symbology-ng/qgsellipsesymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
#include <QDomElement>

QgsEllipseSymbolLayerV2::QgsEllipseSymbolLayerV2(): mSymbolName( "circle" ), mSymbolWidth( 4 ), mSymbolWidthUnit( QgsSymbolV2::MM ), mSymbolHeight( 3 ),
mSymbolHeightUnit( QgsSymbolV2::MM ), mFillColor( Qt::white ), mOutlineColor( Qt::black ), mOutlineWidth( 0 ), mOutlineWidthUnit( QgsSymbolV2::MM ),
mWidthExpression( 0 ), mHeightExpression( 0 ), mRotationExpression( 0 ), mOutlineWidthExpression( 0 ), mFillColorExpression( 0 ),
mOutlineColorExpression( 0 ), mSymbolNameExpression( 0 )
mSymbolHeightUnit( QgsSymbolV2::MM ), mFillColor( Qt::white ), mOutlineColor( Qt::black ), mOutlineWidth( 0 ), mOutlineWidthUnit( QgsSymbolV2::MM )
{
mPen.setColor( mOutlineColor );
mPen.setWidth( 1.0 );
Expand Down Expand Up @@ -151,29 +149,36 @@ QgsSymbolLayerV2* QgsEllipseSymbolLayerV2::create( const QgsStringMap& propertie

void QgsEllipseSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context )
{
QgsExpression* outlineWidthExpression = expression( "outline_width" );
QgsExpression* fillColorExpression = expression( "fill_color" );
QgsExpression* outlineColorExpression = expression( "outline_color" );
QgsExpression* widthExpression = expression( "width" );
QgsExpression* heightExpression = expression( "height" );
QgsExpression* symbolNameExpression = expression( "symbol_name" );
QgsExpression* rotationExpression = expression( "rotation" );

if ( mOutlineWidthExpression )
if ( outlineWidthExpression )
{
double width = mOutlineWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
double width = outlineWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
width *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit );
mPen.setWidthF( width );
}
if ( mFillColorExpression )
if ( fillColorExpression )
{
QString colorString = mFillColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
QString colorString = fillColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
mBrush.setColor( QColor( colorString ) );
}
if ( mOutlineColorExpression )
if ( outlineColorExpression )
{
QString colorString = mOutlineColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
QString colorString = outlineColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
mPen.setColor( QColor( colorString ) );
}
if ( mWidthExpression || mHeightExpression || mSymbolNameExpression )
if ( widthExpression || heightExpression || symbolNameExpression )
{
QString symbolName = mSymbolName;
if ( mSymbolNameExpression )
if ( symbolNameExpression )
{
symbolName = mSymbolNameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
symbolName = symbolNameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
}
preparePath( symbolName, context, context.feature() );
}
Expand All @@ -186,9 +191,9 @@ void QgsEllipseSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Rend

//priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle)
double rotation = 0.0;
if ( mRotationExpression )
if ( rotationExpression )
{
rotation = mRotationExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
rotation = rotationExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}
else if ( !qgsDoubleNear( mAngle, 0.0 ) )
{
Expand Down Expand Up @@ -260,19 +265,21 @@ void QgsEllipseSymbolLayerV2::writeSldMarker( QDomDocument &doc, QDomElement &el
graphicElem.appendChild( factorElem );

// <Rotation>
const QgsExpression* rotationExpression = dataDefinedProperty( "rotation" );
QString angleFunc = props.value( "angle", "" );
if ( angleFunc.isEmpty() ) // symbol has no angle set
{
if ( mRotationExpression )
angleFunc = mRotationExpression->dump();

if ( rotationExpression )
angleFunc = rotationExpression->dump();
else if ( !qgsDoubleNear( mAngle, 0.0 ) )
angleFunc = QString::number( mAngle );
}
else if ( mRotationExpression )
else if ( rotationExpression )
{
// the symbol has an angle and the symbol layer have a rotation
// property set
angleFunc = QString( "%1 + %2" ).arg( angleFunc ).arg( mRotationExpression->dump() );
angleFunc = QString( "%1 + %2" ).arg( angleFunc ).arg( rotationExpression->dump() );
}
else if ( !qgsDoubleNear( mAngle, 0.0 ) )
{
Expand Down Expand Up @@ -355,67 +362,15 @@ QgsStringMap QgsEllipseSymbolLayerV2::properties() const
map["outline_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mOutlineWidthUnit );
map["fill_color"] = QgsSymbolLayerV2Utils::encodeColor( mFillColor );
map["outline_color"] = QgsSymbolLayerV2Utils::encodeColor( mOutlineColor );

//data defined properties
if ( mWidthExpression )
{
map["width_expression"] = mWidthExpression->dump();
}
if ( mHeightExpression )
{
map["height_expression"] = mHeightExpression->dump();
}
if ( mRotationExpression )
{
map["rotation_expression"] = mRotationExpression->dump();
}
if ( mOutlineWidthExpression )
{
map["outline_width_expression"] = mOutlineWidthExpression->dump();
}
if ( mFillColorExpression )
{
map["fill_color_expression"] = mFillColorExpression->dump();
}
if ( mOutlineColorExpression )
{
map["outline_color_expression"] = mOutlineColorExpression->dump();
}
if ( mSymbolNameExpression )
{
map["symbol_name_expression"] = mSymbolNameExpression->dump();
}
saveDataDefinedProperties( map );
return map;
}

bool QgsEllipseSymbolLayerV2::hasDataDefinedProperty() const
{
return ( mWidthExpression || mHeightExpression || mRotationExpression || mOutlineWidthExpression ||
mFillColorExpression || mOutlineColorExpression || mSymbolNameExpression );
}

void QgsEllipseSymbolLayerV2::prepareExpressions( const QgsVectorLayer* vl )
{
if ( !vl )
{
return;
}

const QgsFields& fields = vl->pendingFields();
if ( mWidthExpression )
mWidthExpression->prepare( fields );
if ( mHeightExpression )
mHeightExpression->prepare( fields );
if ( mRotationExpression )
mRotationExpression->prepare( fields );
if ( mOutlineWidthExpression )
mOutlineWidthExpression->prepare( fields );
if ( mFillColorExpression )
mFillColorExpression->prepare( fields );
if ( mOutlineColorExpression )
mOutlineColorExpression->prepare( fields );
if ( mSymbolNameExpression )
mSymbolNameExpression->prepare( fields );
return ( dataDefinedProperty( "width" ) || dataDefinedProperty( "height" ) || dataDefinedProperty( "rotation" )
|| dataDefinedProperty( "outline_width" ) || dataDefinedProperty( "fill_color" ) || dataDefinedProperty( "outline_color" )
|| dataDefinedProperty( "symbol_name" ) );
}

void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV2RenderContext& context, const QgsFeature* f )
Expand All @@ -425,9 +380,10 @@ void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV

double width = 0;

if ( mWidthExpression ) //1. priority: data defined setting on symbol layer level
QgsExpression* widthExpression = expression( "width" );
if ( widthExpression ) //1. priority: data defined setting on symbol layer level
{
width = mWidthExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
width = widthExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
}
else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
{
Expand All @@ -440,9 +396,10 @@ void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV
width *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( ct, mSymbolWidthUnit );

double height = 0;
if ( mHeightExpression ) //1. priority: data defined setting on symbol layer level
QgsExpression* heightExpression = expression( "height" );
if ( heightExpression ) //1. priority: data defined setting on symbol layer level
{
height = mHeightExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
height = heightExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
}
else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
{
Expand Down Expand Up @@ -478,35 +435,6 @@ void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV
}
}

QSet<QString> QgsEllipseSymbolLayerV2::usedAttributes() const
{
QSet<QString> attributes;

//add data defined attributes
QStringList columns;
if ( mWidthExpression )
columns.append( mWidthExpression->referencedColumns() );
if ( mHeightExpression )
columns.append( mHeightExpression->referencedColumns() );
if ( mRotationExpression )
columns.append( mRotationExpression->referencedColumns() );
if ( mOutlineWidthExpression )
columns.append( mOutlineWidthExpression->referencedColumns() );
if ( mFillColorExpression )
columns.append( mFillColorExpression->referencedColumns() );
if ( mOutlineColorExpression )
columns.append( mOutlineColorExpression->referencedColumns() );
if ( mSymbolNameExpression )
columns.append( mSymbolNameExpression->referencedColumns() );

QStringList::const_iterator it = columns.constBegin();
for ( ; it != columns.constEnd(); ++it )
{
attributes.insert( *it );
}
return attributes;
}

void QgsEllipseSymbolLayerV2::setOutputUnit( QgsSymbolV2::OutputUnit unit )
{
mSymbolWidthUnit = unit;
Expand All @@ -523,117 +451,3 @@ QgsSymbolV2::OutputUnit QgsEllipseSymbolLayerV2::outputUnit() const
}
return unit;
}

const QgsExpression* QgsEllipseSymbolLayerV2::dataDefinedProperty( const QString& property ) const
{
if ( property == "width" )
{
return mWidthExpression;
}
else if ( property == "height" )
{
return mHeightExpression;
}
else if ( property == "rotation" )
{
return mRotationExpression;
}
else if ( property == "outline_width" )
{
return mOutlineWidthExpression;
}
else if ( property == "fill_color" )
{
return mFillColorExpression;
}
else if ( property == "outline_color" )
{
return mOutlineColorExpression;
}
else if ( property == "symbol_name" )
{
return mSymbolNameExpression;
}
return 0;
}

QString QgsEllipseSymbolLayerV2::dataDefinedPropertyString( const QString& property ) const
{
const QgsExpression* ex = dataDefinedProperty( property );
return ( ex ? ex->dump() : QString() );
}

void QgsEllipseSymbolLayerV2::setDataDefinedProperty( const QString& property, const QString& expressionString )
{
if ( property == "width" )
{
delete mWidthExpression; mWidthExpression = new QgsExpression( expressionString );
}
else if ( property == "height" )
{
delete mHeightExpression; mHeightExpression = new QgsExpression( expressionString );
}
else if ( property == "rotation" )
{
delete mRotationExpression; mRotationExpression = new QgsExpression( expressionString );
}
else if ( property == "outline_width" )
{
delete mOutlineWidthExpression; mOutlineWidthExpression = new QgsExpression( expressionString );
}
else if ( property == "fill_color" )
{
delete mFillColorExpression; mFillColorExpression = new QgsExpression( expressionString );
}
else if ( property == "outline_color" )
{
delete mOutlineColorExpression; mOutlineColorExpression = new QgsExpression( expressionString );
}
else if ( property == "symbol_name" )
{
delete mSymbolNameExpression; mSymbolNameExpression = new QgsExpression( expressionString );
}
}

void QgsEllipseSymbolLayerV2::removeDataDefinedProperty( const QString& property )
{
if ( property == "width" )
{
delete mWidthExpression; mWidthExpression = 0;
}
else if ( property == "height" )
{
delete mHeightExpression; mHeightExpression = 0;
}
else if ( property == "rotation" )
{
delete mRotationExpression; mRotationExpression = 0;
}
else if ( property == "outline_width" )
{
delete mOutlineWidthExpression; mOutlineWidthExpression = 0;
}
else if ( property == "fill_color" )
{
delete mFillColorExpression; mFillColorExpression = 0;
}
else if ( property == "outline_color" )
{
delete mOutlineColorExpression; mOutlineColorExpression = 0;
}
else if ( property == "symbol_name" )
{
delete mSymbolNameExpression; mSymbolNameExpression = 0;
}
}

void QgsEllipseSymbolLayerV2::removeDataDefinedProperties()
{
delete mWidthExpression; mWidthExpression = 0;
delete mHeightExpression; mHeightExpression = 0;
delete mRotationExpression; mRotationExpression = 0;
delete mOutlineWidthExpression; mOutlineWidthExpression = 0;
delete mFillColorExpression; mFillColorExpression = 0;
delete mOutlineColorExpression; mOutlineColorExpression = 0;
delete mSymbolNameExpression; mSymbolNameExpression = 0;
}
19 changes: 0 additions & 19 deletions src/core/symbology-ng/qgsellipsesymbollayerv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ class CORE_EXPORT QgsEllipseSymbolLayerV2: public QgsMarkerSymbolLayerV2
void setOutlineColor( const QColor& c ) { mOutlineColor = c; }
QColor outlineColor() const { return mOutlineColor; }

QSet<QString> usedAttributes() const;

void setSymbolWidthUnit( QgsSymbolV2::OutputUnit unit ) { mSymbolWidthUnit = unit; }
QgsSymbolV2::OutputUnit symbolWidthUnit() const { return mSymbolWidthUnit; }

Expand All @@ -72,12 +70,6 @@ class CORE_EXPORT QgsEllipseSymbolLayerV2: public QgsMarkerSymbolLayerV2
void setOutputUnit( QgsSymbolV2::OutputUnit unit );
QgsSymbolV2::OutputUnit outputUnit() const;

const QgsExpression* dataDefinedProperty( const QString& property ) const;
QString dataDefinedPropertyString( const QString& property ) const;
void setDataDefinedProperty( const QString& property, const QString& expressionString );
void removeDataDefinedProperty( const QString& property );
void removeDataDefinedProperties();

private:
QString mSymbolName;
double mSymbolWidth;
Expand All @@ -89,15 +81,6 @@ class CORE_EXPORT QgsEllipseSymbolLayerV2: public QgsMarkerSymbolLayerV2
double mOutlineWidth;
QgsSymbolV2::OutputUnit mOutlineWidthUnit;

//data defined property fields
QgsExpression* mWidthExpression;
QgsExpression* mHeightExpression;
QgsExpression* mRotationExpression;
QgsExpression* mOutlineWidthExpression;
QgsExpression* mFillColorExpression;
QgsExpression* mOutlineColorExpression;
QgsExpression* mSymbolNameExpression;

QPainterPath mPainterPath;

QPen mPen;
Expand All @@ -111,8 +94,6 @@ class CORE_EXPORT QgsEllipseSymbolLayerV2: public QgsMarkerSymbolLayerV2

/**True if this symbol layer uses a data defined property*/
bool hasDataDefinedProperty() const;

void prepareExpressions( const QgsVectorLayer* vl );
};

#endif // QGSELLIPSESYMBOLLAYERV2_H
166 changes: 17 additions & 149 deletions src/core/symbology-ng/qgsfillsymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1292,8 +1292,7 @@ QgsSymbolLayerV2* QgsLinePatternFillSymbolLayer::createFromSld( QDomElement &ele

QgsPointPatternFillSymbolLayer::QgsPointPatternFillSymbolLayer(): QgsImageFillSymbolLayer(), mMarkerSymbol( 0 ), mDistanceX( 15 ),
mDistanceXUnit( QgsSymbolV2::MM ), mDistanceY( 15 ), mDistanceYUnit( QgsSymbolV2::MM ), mDisplacementX( 0 ), mDisplacementXUnit( QgsSymbolV2::MM ),
mDisplacementY( 0 ), mDisplacementYUnit( QgsSymbolV2::MM ), mDistanceXExpression( 0 ), mDistanceYExpression( 0 ),
mDisplacementXExpression( 0 ), mDisplacementYExpression( 0 )
mDisplacementY( 0 ), mDisplacementYUnit( QgsSymbolV2::MM )
{
mDistanceX = 15;
mDistanceY = 15;
Expand Down Expand Up @@ -1461,6 +1460,7 @@ void QgsPointPatternFillSymbolLayer::startRender( QgsSymbolV2RenderContext& cont
{
mOutline->startRender( context.renderContext() );
}
prepareExpressions( context.layer() );
}

void QgsPointPatternFillSymbolLayer::stopRender( QgsSymbolV2RenderContext& context )
Expand All @@ -1482,24 +1482,7 @@ QgsStringMap QgsPointPatternFillSymbolLayer::properties() const
propertyMap["distance_y_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mDistanceYUnit );
propertyMap["displacement_x_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mDisplacementXUnit );
propertyMap["displacement_y_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mDisplacementYUnit );

//data defined properties
if ( mDistanceXExpression )
{
propertyMap["distance_x_expression"] = mDistanceXExpression->dump();
}
if ( mDistanceYExpression )
{
propertyMap["distance_y_expression"] = mDistanceYExpression->dump();
}
if ( mDisplacementXExpression )
{
propertyMap["displacement_x_expression"] = mDisplacementXExpression->dump();
}
if ( mDisplacementYExpression )
{
propertyMap["displacement_y_expression"] = mDisplacementYExpression->dump();
}
saveDataDefinedProperties( propertyMap );
return propertyMap;
}

Expand All @@ -1510,10 +1493,7 @@ QgsSymbolLayerV2* QgsPointPatternFillSymbolLayer::clone() const
{
clonedLayer->setSubSymbol( mMarkerSymbol->clone() );
}
clonedLayer->setDistanceXUnit( mDistanceXUnit );
clonedLayer->setDistanceYUnit( mDistanceYUnit );
clonedLayer->setDisplacementXUnit( mDisplacementXUnit );
clonedLayer->setDisplacementYUnit( mDisplacementYUnit );
copyDataDefinedProperties( clonedLayer );
return clonedLayer;
}

Expand Down Expand Up @@ -1576,152 +1556,40 @@ bool QgsPointPatternFillSymbolLayer::setSubSymbol( QgsSymbolV2* symbol )
return true;
}

const QgsExpression* QgsPointPatternFillSymbolLayer::dataDefinedProperty( const QString& property ) const
{
if ( property == "distance_x" )
{
return mDistanceXExpression;
}
else if ( property == "distance_x" )
{
return mDistanceYExpression;
}
else if ( property == "displacement_x" )
{
return mDisplacementXExpression;
}
else if ( property == "displacement_y" )
{
return mDisplacementYExpression;
}
return 0;
}

QString QgsPointPatternFillSymbolLayer::dataDefinedPropertyString( const QString& property ) const
{
const QgsExpression* ex = dataDefinedProperty( property );
return ex ? ex->dump() : QString();
}

void QgsPointPatternFillSymbolLayer::setDataDefinedProperty( const QString& property, const QString& expressionString )
{
if ( property == "distance_x" )
{
delete mDistanceXExpression; mDistanceXExpression = new QgsExpression( expressionString );
}
else if ( property == "distance_x" )
{
delete mDistanceYExpression; mDistanceYExpression = new QgsExpression( expressionString );
}
else if ( property == "displacement_x" )
{
delete mDisplacementXExpression; mDisplacementXExpression = new QgsExpression( expressionString );
}
else if ( property == "displacement_y" )
{
delete mDisplacementYExpression; mDisplacementYExpression = new QgsExpression( expressionString );
}
}

void QgsPointPatternFillSymbolLayer::removeDataDefinedProperty( const QString& property )
{
if ( property == "distance_x" )
{
delete mDistanceXExpression; mDistanceXExpression = 0;
}
else if ( property == "distance_x" )
{
delete mDistanceYExpression; mDistanceYExpression = 0;
}
else if ( property == "displacement_x" )
{
delete mDisplacementXExpression; mDisplacementXExpression = 0;
}
else if ( property == "displacement_y" )
{
delete mDisplacementYExpression; mDisplacementYExpression = 0;
}
}

void QgsPointPatternFillSymbolLayer::removeDataDefinedProperties()
{
delete mDistanceXExpression; mDistanceXExpression = 0;
delete mDistanceYExpression; mDistanceYExpression = 0;
delete mDisplacementXExpression; mDisplacementXExpression = 0;
delete mDisplacementYExpression; mDisplacementYExpression = 0;
}

QSet<QString> QgsPointPatternFillSymbolLayer::usedAttributes() const
{
QSet<QString> attributes;

//add data defined attributes
QStringList columns;
if ( mDistanceXExpression )
columns.append( mDistanceXExpression->referencedColumns() );
if ( mDistanceYExpression )
columns.append( mDistanceYExpression->referencedColumns() );
if ( mDisplacementXExpression )
columns.append( mDisplacementXExpression->referencedColumns() );
if ( mDisplacementYExpression )
columns.append( mDisplacementYExpression->referencedColumns() );

QStringList::const_iterator it = columns.constBegin();
for ( ; it != columns.constEnd(); ++it )
{
attributes.insert( *it );
}
return attributes;
}

void QgsPointPatternFillSymbolLayer::applyDataDefinedSettings( const QgsSymbolV2RenderContext& context )
{
if ( !mDistanceXExpression && !mDistanceYExpression && !mDisplacementXExpression && !mDisplacementYExpression )
QgsExpression* distanceXExpression = expression( "distance_x" );
QgsExpression* distanceYExpression = expression( "distance_y" );
QgsExpression* displacementXExpression = expression( "displacement_x" );
QgsExpression* displacementYExpression = expression( "displacement_y" );
if ( !distanceXExpression && !distanceYExpression && !displacementXExpression && !displacementYExpression )
{
return;
}

double distanceX = mDistanceX;
if ( mDistanceXExpression )
if ( distanceXExpression )
{
distanceX = mDistanceXExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
distanceX = distanceXExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}
double distanceY = mDistanceY;
if ( mDistanceYExpression )
if ( distanceYExpression )
{
distanceY = mDistanceYExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
distanceY = distanceYExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}
double displacementX = mDisplacementX;
if ( mDisplacementXExpression )
if ( displacementXExpression )
{
displacementX = mDisplacementXExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
displacementX = displacementXExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}
double displacementY = mDisplacementY;
if ( mDisplacementYExpression )
if ( displacementYExpression )
{
displacementY = mDisplacementYExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
displacementY = displacementYExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}
applyPattern( context, mBrush, distanceX, distanceY, displacementX, displacementY );
}

void QgsPointPatternFillSymbolLayer::prepareExpressions( const QgsVectorLayer* vl )
{
if ( !vl )
{
return;
}

const QgsFields& fields = vl->pendingFields();
if ( mDistanceXExpression )
mDistanceXExpression->prepare( fields );
if ( mDistanceYExpression )
mDistanceYExpression->prepare( fields );
if ( mDisplacementXExpression )
mDisplacementXExpression->prepare( fields );
if ( mDisplacementYExpression )
mDisplacementYExpression->prepare( fields );
}

//////////////


Expand Down
14 changes: 0 additions & 14 deletions src/core/symbology-ng/qgsfillsymbollayerv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,14 +330,6 @@ class CORE_EXPORT QgsPointPatternFillSymbolLayer: public QgsImageFillSymbolLayer
void setOutputUnit( QgsSymbolV2::OutputUnit unit );
QgsSymbolV2::OutputUnit outputUnit() const;

const QgsExpression* dataDefinedProperty( const QString& property ) const;
QString dataDefinedPropertyString( const QString& property ) const;
void setDataDefinedProperty( const QString& property, const QString& expressionString );
void removeDataDefinedProperty( const QString& property );
void removeDataDefinedProperties();

QSet<QString> usedAttributes() const;

protected:
QgsMarkerSymbolV2* mMarkerSymbol;
double mDistanceX;
Expand All @@ -349,17 +341,11 @@ class CORE_EXPORT QgsPointPatternFillSymbolLayer: public QgsImageFillSymbolLayer
double mDisplacementY;
QgsSymbolV2::OutputUnit mDisplacementYUnit;

QgsExpression* mDistanceXExpression;
QgsExpression* mDistanceYExpression;
QgsExpression* mDisplacementXExpression;
QgsExpression* mDisplacementYExpression;

void applyDataDefinedSettings( const QgsSymbolV2RenderContext& context );

private:
void applyPattern( const QgsSymbolV2RenderContext& context, QBrush& brush, double distanceX, double distanceY,
double displacementX, double displacementY );
void prepareExpressions( const QgsVectorLayer* vl );
};

class CORE_EXPORT QgsCentroidFillSymbolLayerV2 : public QgsFillSymbolLayerV2
Expand Down
9 changes: 5 additions & 4 deletions src/gui/attributetable/qgsfeaturelistview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,18 @@ void QgsFeatureListView::mousePressEvent( QMouseEvent *event )
{
QPoint pos = event->pos();

QModelIndex index = mModel->mapToMaster( indexAt( pos ) );
QModelIndex index = indexAt( pos );

if ( QgsFeatureListViewDelegate::EditElement == mItemDelegate->positionToElement( event->pos() ) )
{
mEditSelectionDrag = true;
mCurrentEditSelectionModel->select( index, QItemSelectionModel::ClearAndSelect );
mCurrentEditSelectionModel->select( mModel->mapToMaster( index ), QItemSelectionModel::ClearAndSelect );
}
else
{
mFeatureSelectionModel->enableSync( false );
selectRow( index, true );
repaintRequested();
}
}

Expand Down Expand Up @@ -176,11 +177,11 @@ void QgsFeatureListView::mouseMoveEvent( QMouseEvent *event )
{
QPoint pos = event->pos();

QModelIndex index = mModel->mapToMaster( indexAt( pos ) );
QModelIndex index = indexAt( pos );

if ( mEditSelectionDrag )
{
mCurrentEditSelectionModel->select( index, QItemSelectionModel::ClearAndSelect );
mCurrentEditSelectionModel->select( mModel->mapToMaster( index ), QItemSelectionModel::ClearAndSelect );
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/gui/attributetable/qgsfeatureselectionmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ bool QgsFeatureSelectionModel::isSelected( QgsFeatureId fid )
if ( mDeselectedBuffer.contains( fid ) )
return false;

if ( mLayer->selectedFeaturesIds().contains( fid ) )
if ( !mClearAndSelectBuffer && mLayer->selectedFeaturesIds().contains( fid ) )
return true;

return false;
Expand Down
6 changes: 3 additions & 3 deletions src/gui/qgsrasterlayersaveasdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog( QgsRasterLayer* rasterLa
//extent
setOutputExtent( mDataProvider->extent(), mLayerCrs, OriginalExtent );

if ( mDataProvider->capabilities() & QgsRasterDataProvider::ExactResolution )
if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
{
setOriginalResolution();
int xSize = mDataProvider->xSize();
Expand Down Expand Up @@ -335,7 +335,7 @@ void QgsRasterLayerSaveAsDialog::hideOutput()

void QgsRasterLayerSaveAsDialog::toggleResolutionSize()
{
bool hasResolution = mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::ExactResolution;
bool hasResolution = mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::Size;

bool on = mResolutionRadioButton->isChecked();
mXResolutionLineEdit->setEnabled( on );
Expand All @@ -350,7 +350,7 @@ void QgsRasterLayerSaveAsDialog::setOriginalResolution()
{
double xRes, yRes;

if ( mDataProvider->capabilities() & QgsRasterDataProvider::ExactResolution )
if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
{
xRes = mDataProvider->extent().width() / mDataProvider->xSize();
yRes = mDataProvider->extent().height() / mDataProvider->ySize();
Expand Down
15 changes: 9 additions & 6 deletions src/gui/qgsrasterpyramidsoptionswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() );
Expand Down Expand Up @@ -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()
Expand All @@ -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
Expand Down
6 changes: 4 additions & 2 deletions src/gui/raster/qgsrasterhistogramwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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." );
Expand Down
64 changes: 38 additions & 26 deletions src/providers/gdal/qgsgdalprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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] ) );
Expand All @@ -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
Expand Down Expand Up @@ -986,7 +967,10 @@ QgsRasterIdentifyResult QgsGdalProvider::identify( const QgsPoint & thePoint, Id
{
results.insert( i, QVariant() ); // null QVariant represents no data
}
results.insert( i, value );
else
{
results.insert( i, value );
}
}
return QgsRasterIdentifyResult( QgsRasterDataProvider::IdentifyFormatValue, results );
}
Expand All @@ -995,10 +979,8 @@ int QgsGdalProvider::capabilities() const
{
int capability = QgsRasterDataProvider::Identify
| QgsRasterDataProvider::IdentifyValue
| QgsRasterDataProvider::ExactResolution
| QgsRasterDataProvider::EstimatedMinimumMaximum
| QgsRasterDataProvider::Size
| QgsRasterDataProvider::BuildPyramids
| QgsRasterDataProvider::Histogram
| QgsRasterDataProvider::Create
| QgsRasterDataProvider::Remove;
GDALDriverH myDriver = GDALGetDatasetDriver( mGdalDataset );
Expand Down Expand Up @@ -2285,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
Expand Down Expand Up @@ -2754,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;
}

15 changes: 3 additions & 12 deletions src/providers/gdal/qgsgdalprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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;
Expand All @@ -317,7 +309,6 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase

/** \brief sublayers list saved for subsequent access */
QStringList mSubLayers;

};

#endif
Expand Down
17 changes: 2 additions & 15 deletions src/providers/grass/qgsgrassrasterprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 ) );
Expand Down Expand Up @@ -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;
}
Expand All @@ -489,8 +478,6 @@ int QgsGrassRasterProvider::capabilities() const
{
int capability = QgsRasterDataProvider::Identify
| QgsRasterDataProvider::IdentifyValue
| QgsRasterDataProvider::ExactResolution
| QgsRasterDataProvider::ExactMinimumMaximum
| QgsRasterDataProvider::Size;
return capability;
}
Expand Down
7 changes: 1 addition & 6 deletions src/providers/grass/qgsgrassrasterprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -232,7 +227,7 @@ class QgsGrassRasterProvider : public QgsRasterDataProvider

QgsGrassRasterValue mRasterValue;

//double mNoDataValue;
double mNoDataValue;
};

#endif
4 changes: 2 additions & 2 deletions src/providers/wcs/qgswcsprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -1433,11 +1435,9 @@ int QgsWcsProvider::capabilities() const
int capability = NoCapabilities;
capability |= QgsRasterDataProvider::Identify;
capability |= QgsRasterDataProvider::IdentifyValue;
capability |= QgsRasterDataProvider::Histogram;

if ( mHasSize )
{
capability |= QgsRasterDataProvider::ExactResolution;
capability |= QgsRasterDataProvider::Size;
}

Expand Down
1 change: 1 addition & 0 deletions src/providers/wcs/qgswcsprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class QNetworkRequest;

#define CPL_SUPRESS_CPLUSPLUS
#include <gdal.h>
#include "cpl_conv.h"

/**
Expand Down