diff --git a/python/core/raster/qgsrasterdataprovider.sip b/python/core/raster/qgsrasterdataprovider.sip index 67208258091..f4da2bd2d52 100644 --- a/python/core/raster/qgsrasterdataprovider.sip +++ b/python/core/raster/qgsrasterdataprovider.sip @@ -135,12 +135,12 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface // TODO: Get the file masks supported by this provider, suitable for feeding into the file open dialog box /** Returns data type for the band specified by number */ - virtual QgsRasterBlock::DataType dataType( int bandNo ) const; + virtual QgsRasterBlock::DataType dataType( int bandNo ) const = 0; /** Returns source data type for the band specified by number, * source data type may be shorter than dataType */ - virtual QgsRasterBlock::DataType srcDataType( int bandNo ) const; + virtual QgsRasterBlock::DataType srcDataType( int bandNo ) const = 0; /** Returns data type for the band specified by number */ virtual int colorInterpretation( int theBandNo ) const; @@ -388,9 +388,6 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface static QString makeTableCell( const QString & value ); static QString makeTableCells( const QStringList & values ); - /** \brief Set null value in char */ - QByteArray noValueBytes( int theBandNo ); - /** Time stamp of data source in the moment when data/metadata were loaded by provider */ virtual QDateTime timestamp() const; diff --git a/python/gui/raster/qgsmultibandcolorrendererwidget.sip b/python/gui/raster/qgsmultibandcolorrendererwidget.sip index 1237f5e99be..13cb3e9a0ae 100644 --- a/python/gui/raster/qgsmultibandcolorrendererwidget.sip +++ b/python/gui/raster/qgsmultibandcolorrendererwidget.sip @@ -20,5 +20,5 @@ class QgsMultiBandColorRendererWidget: QgsRasterRendererWidget int selectedBand( int index = 0 ); public slots: - void loadMinMax( int theBandNo, double theMin, double theMax ); + void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin ); }; diff --git a/src/core/raster/qgsrasterblock.cpp b/src/core/raster/qgsrasterblock.cpp index c2cd0f9db90..205138a891d 100644 --- a/src/core/raster/qgsrasterblock.cpp +++ b/src/core/raster/qgsrasterblock.cpp @@ -75,7 +75,8 @@ bool QgsRasterBlock::reset( DataType theDataType, int theWidth, int theHeight, d if ( typeIsNumeric( theDataType ) ) { QgsDebugMsg( "Numeric type" ); - int tSize = typeSize( theDataType ) / 8; + size_t tSize = typeSize( theDataType ); + QgsDebugMsg( QString( "allocate %1 bytes" ).arg( tSize * theWidth * theHeight ) ); mData = QgsMalloc( tSize * theWidth * theHeight ); if ( mData == 0 ) { @@ -341,6 +342,36 @@ bool QgsRasterBlock::setColor( size_t index, QRgb color ) return true; } +bool QgsRasterBlock::setIsNoData( int row, int column ) +{ + return setIsNoData(( size_t )row*column ); +} + +bool QgsRasterBlock::setIsNoData( size_t index ) +{ + return setValue( index, mNoDataValue ); +} + +bool QgsRasterBlock::setIsNoData() +{ + if ( !mData ) + { + QgsDebugMsg( "Data block not allocated" ); + return false; + } + + int dataTypeSize = typeSize( mDataType ); + QByteArray noDataByteArray = valueBytes( mDataType, mNoDataValue ); + + char *nodata = noDataByteArray.data(); + for ( size_t i = 0; i < ( size_t )mWidth*mHeight; i++ ) + { + memcpy(( char* )mData + i*dataTypeSize, nodata, dataTypeSize ); + } + + return true; +} + char * QgsRasterBlock::bits( size_t index ) { // Not testing type to avoid too much overhead because this method is called per pixel @@ -481,7 +512,7 @@ QString QgsRasterBlock::printValue( double value ) void * QgsRasterBlock::convert( void *srcData, QgsRasterBlock::DataType srcDataType, QgsRasterBlock::DataType destDataType, size_t size ) { - int destDataTypeSize = typeSize( destDataType ) / 8; + int destDataTypeSize = typeSize( destDataType ); void *destData = QgsMalloc( destDataTypeSize * size ); for ( size_t i = 0; i < size; i++ ) { @@ -492,3 +523,53 @@ void * QgsRasterBlock::convert( void *srcData, QgsRasterBlock::DataType srcDataT } return destData; } + +QByteArray QgsRasterBlock::valueBytes( DataType theDataType, double theValue ) +{ + size_t size = QgsRasterBlock::typeSize( theDataType ); + QByteArray ba; + ba.resize(( int )size ); + char * data = ba.data(); + unsigned char uc; + unsigned short us; + short s; + unsigned int ui; + int i; + float f; + double d; + // TODO: define correct data types (typedef) like in GDAL + switch ( theDataType ) + { + case QgsRasterBlock::Byte: + uc = ( unsigned char )theValue; + memcpy( data, &uc, size ); + break; + case QgsRasterBlock::UInt16: + us = ( unsigned short )theValue; + memcpy( data, &us, size ); + break; + case QgsRasterBlock::Int16: + s = ( short )theValue; + memcpy( data, &s, size ); + break; + case QgsRasterBlock::UInt32: + ui = ( unsigned int )theValue; + memcpy( data, &ui, size ); + break; + case QgsRasterBlock::Int32: + i = ( int )theValue; + memcpy( data, &i, size ); + break; + case QgsRasterBlock::Float32: + f = ( float )theValue; + memcpy( data, &f, size ); + break; + case QgsRasterBlock::Float64: + d = ( double )theValue; + memcpy( data, &d, size ); + break; + default: + QgsDebugMsg( "Data type is not supported" ); + } + return ba; +} diff --git a/src/core/raster/qgsrasterblock.h b/src/core/raster/qgsrasterblock.h index 025dc568696..2afd703a1a8 100644 --- a/src/core/raster/qgsrasterblock.h +++ b/src/core/raster/qgsrasterblock.h @@ -92,41 +92,43 @@ class CORE_EXPORT QgsRasterBlock //bool isValid() const { return mValid; } bool isEmpty() const; + // Return data type size in bytes static int typeSize( int dataType ) { // Modified and extended copy from GDAL switch ( dataType ) { case Byte: - return 8; + return 1; case UInt16: case Int16: - return 16; + return 2; case UInt32: case Int32: case Float32: case CInt16: - return 32; + return 4; case Float64: case CInt32: case CFloat32: - return 64; + return 8; case CFloat64: - return 128; + return 16; case ARGB32: case ARGB32_Premultiplied: - return 32; + return 4; default: return 0; } } + // Data type in bytes int dataTypeSize( int bandNo ) const { Q_UNUSED( bandNo ); @@ -165,6 +167,9 @@ class CORE_EXPORT QgsRasterBlock * @return true if value is nodata */ bool isNoDataValue( double value ) const; + // get byte array representing no data value + static QByteArray valueBytes( DataType theDataType, double theValue ); + /** \brief Read a single value * @param row row index * @param column column index @@ -218,6 +223,21 @@ class CORE_EXPORT QgsRasterBlock * @return true on success */ bool setColor( int row, int column, QRgb color ); + /** \brief Set no data on pixel + * @param row row index + * @param column column index + * @return true on success */ + bool setIsNoData( int row, int column ); + + /** \brief Set no data on pixel + * @param index data matrix index + * @return true on success */ + bool setIsNoData( size_t index ); + + /** \brief Set the whole block to no data + * @return true on success */ + bool setIsNoData( ); + /** \brief Set color on index (indexed line by line) * @param index data matrix index * @param color the color to be set, QRgb value @@ -289,7 +309,6 @@ class CORE_EXPORT QgsRasterBlock static QImage::Format imageFormat( QgsRasterBlock::DataType theDataType ); static DataType dataType( QImage::Format theFormat ); - // Valid //bool isValid; diff --git a/src/core/raster/qgsrasterdataprovider.cpp b/src/core/raster/qgsrasterdataprovider.cpp index c4ec50e9803..d282e89028c 100644 --- a/src/core/raster/qgsrasterdataprovider.cpp +++ b/src/core/raster/qgsrasterdataprovider.cpp @@ -46,86 +46,12 @@ double QgsRasterDataProvider::noDataValue( int bandNo ) const return mInternalNoDataValue.value( bandNo -1 ); } -#if 0 -void QgsRasterDataProvider::readBlock( int bandNo, QgsRectangle - const & viewExtent, int width, - int height, - QgsCoordinateReferenceSystem theSrcCRS, - QgsCoordinateReferenceSystem theDestCRS, - void *data ) +QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle const & theExtent, int theWidth, int theHeight ) { - QgsDebugMsg( "Entered" ); - QgsDebugMsg( "viewExtent = " + viewExtent.toString() ); + QgsDebugMsg( QString( "theBandNo = %1 theWidth = %2 theHeight = %3" ).arg( theBandNo ).arg( theWidth ).arg( theHeight ) ); + QgsDebugMsg( QString( "theExtent = %1" ).arg( theExtent.toString() ) ); - if ( ! theSrcCRS.isValid() || ! theDestCRS.isValid() || theSrcCRS == theDestCRS ) - { - readBlock( bandNo, viewExtent, width, height, data ); - return; - } - - QTime time; - time.start(); - - double mMaxSrcXRes = 0; - double mMaxSrcYRes = 0; - - if ( capabilities() & QgsRasterDataProvider::ExactResolution ) - { - mMaxSrcXRes = extent().width() / xSize(); - mMaxSrcYRes = extent().height() / ySize(); - } - - QgsRasterProjector myProjector( theSrcCRS, theDestCRS, viewExtent, height, width, mMaxSrcXRes, mMaxSrcYRes, extent() ); - - QgsDebugMsg( QString( "create projector time (ms): %1" ).arg( time.elapsed() ) ); - - // TODO: init data by nulls - - // If we zoom out too much, projector srcRows / srcCols maybe 0, which can cause problems in providers - if ( myProjector.srcRows() <= 0 || myProjector.srcCols() <= 0 ) - return; - - // Allocate memory for not projected source data - size_t mySize = dataTypeSize( bandNo ) / 8; - void *mySrcData = malloc( mySize * myProjector.srcRows() * myProjector.srcCols() ); - - time.restart(); - - readBlock( bandNo, myProjector.srcExtent(), myProjector.srcCols(), myProjector.srcRows(), mySrcData ); - - QgsDebugMsg( QString( "read not projected block time (ms): %1" ).arg( time.elapsed() ) ); - time.restart(); - - // Project data from source - int mySrcRow; - int mySrcCol; - int mySrcOffset; - int myDestOffset; - for ( int r = 0; r < height; r++ ) - { - for ( int c = 0; c < width; c++ ) - { - myProjector.srcRowCol( r, c, &mySrcRow, &mySrcCol ); - mySrcOffset = mySize * ( mySrcRow * myProjector.srcCols() + mySrcCol ); - myDestOffset = mySize * ( r * width + c ); - // retype to char is just to avoid g++ warning - memcpy(( char* ) data + myDestOffset, ( char* )mySrcData + mySrcOffset, mySize ); - } - } - QgsDebugMsg( QString( "reproject block time (ms): %1" ).arg( time.elapsed() ) ); - - free( mySrcData ); -} -#endif - -//void * QgsRasterDataProvider::readBlock( int bandNo, QgsRectangle const & extent, int width, int height ) -QgsRasterBlock * QgsRasterDataProvider::block( int bandNo, QgsRectangle const & extent, int width, int height ) -{ - QgsDebugMsg( QString( "bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ) ); - - //void * data = QgsMalloc( dataTypeSize( bandNo ) * width * height ); - - QgsRasterBlock *block = new QgsRasterBlock( dataType( bandNo ), width, height, noDataValue( bandNo ) ); + QgsRasterBlock *block = new QgsRasterBlock( dataType( theBandNo ), theWidth, theHeight, noDataValue( theBandNo ) ); if ( block->isEmpty() ) { @@ -133,16 +59,145 @@ QgsRasterBlock * QgsRasterDataProvider::block( int bandNo, QgsRectangle const & return block; } - readBlock( bandNo, extent, width, height, block->data() ); + // Read necessary extent only + QgsRectangle tmpExtent = extent().intersect( &theExtent ); + + if ( tmpExtent.isEmpty() ) + { + QgsDebugMsg( "Extent outside provider extent" ); + block->setIsNoData(); + return block; + } + + double xRes = theExtent.width() / theWidth; + double yRes = theExtent.height() / theHeight; + double tmpXRes, tmpYRes; + double providerXRes = 0; + double providerYRes = 0; + if ( capabilities() & ExactResolution ) + { + providerXRes = extent().width() / xSize(); + providerYRes = extent().height() / ySize(); + tmpXRes = qMax( providerXRes, xRes ); + tmpYRes = qMax( providerYRes, yRes ); + if ( doubleNear( tmpXRes, xRes ) ) tmpXRes = xRes; + if ( doubleNear( tmpYRes, yRes ) ) tmpYRes = yRes; + } + else + { + tmpXRes = xRes; + tmpYRes = yRes; + } + + if ( tmpExtent != theExtent || + tmpXRes > xRes || tmpYRes > yRes ) + { + // Read smaller extent or lower resolution + + // Calculate row/col limits (before tmpExtent is aligned) + int fromRow = qRound(( theExtent.yMaximum() - tmpExtent.yMaximum() ) / yRes ); + int toRow = qRound(( theExtent.yMaximum() - tmpExtent.yMinimum() ) / yRes ) - 1; + int fromCol = qRound(( tmpExtent.xMinimum() - theExtent.xMinimum() ) / xRes ) ; + int toCol = qRound(( tmpExtent.xMaximum() - theExtent.xMinimum() ) / xRes ) - 1; + + QgsDebugMsg( QString( "fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ) ); + + if ( fromRow < 0 || fromRow >= theHeight || toRow < 0 || toRow >= theHeight || + fromCol < 0 || fromCol >= theWidth || toCol < 0 || toCol >= theWidth ) + { + // Should not happen + QgsDebugMsg( "Row or column limits out of range" ); + return block; + } + + // If lower source resolution is used, the extent must beS aligned to original + // resolution to avoid possible shift due to resampling + if ( tmpXRes > xRes ) + { + int col = floor(( tmpExtent.xMinimum() - extent().xMinimum() ) / providerXRes ); + tmpExtent.setXMinimum( extent().xMinimum() + col * providerXRes ); + col = ceil(( tmpExtent.xMaximum() - extent().xMinimum() ) / providerXRes ); + tmpExtent.setXMaximum( extent().xMinimum() + col * providerXRes ); + } + if ( tmpYRes > yRes ) + { + int row = floor(( extent().yMaximum() - tmpExtent.yMaximum() ) / providerYRes ); + tmpExtent.setYMaximum( extent().yMaximum() - row * providerYRes ); + row = ceil(( extent().yMaximum() - tmpExtent.yMinimum() ) / providerYRes ); + tmpExtent.setYMinimum( extent().yMaximum() - row * providerYRes ); + } + int tmpWidth = qRound( tmpExtent.width() / tmpXRes ); + int tmpHeight = qRound( tmpExtent.height() / tmpYRes ); + tmpXRes = tmpExtent.width() / tmpWidth; + tmpYRes = tmpExtent.height() / tmpHeight; + + QgsDebugMsg( QString( "Reading smaller block tmpWidth = %1 theHeight = %2" ).arg( tmpWidth ).arg( tmpHeight ) ); + QgsDebugMsg( QString( "tmpExtent = %1" ).arg( tmpExtent.toString() ) ); + + block->setIsNoData(); + + QgsRasterBlock *tmpBlock = new QgsRasterBlock( dataType( theBandNo ), tmpWidth, tmpHeight, noDataValue( theBandNo ) ); + + readBlock( theBandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->data() ); + + int pixelSize = dataTypeSize( theBandNo ); + + double xMin = theExtent.xMinimum(); + double yMax = theExtent.yMaximum(); + double tmpXMin = tmpExtent.xMinimum(); + double tmpYMax = tmpExtent.yMaximum(); + + for ( int row = fromRow; row <= toRow; row++ ) + { + double y = yMax - ( row + 0.5 ) * yRes; + int tmpRow = floor(( tmpYMax - y ) / tmpYRes ); + + for ( int col = fromCol; col <= toCol; col++ ) + { + double x = xMin + ( col + 0.5 ) * xRes; + int tmpCol = floor(( x - tmpXMin ) / tmpXRes ); + + if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth ) + { + QgsDebugMsg( "Source row or column limits out of range" ); + block->setIsNoData(); // so that the problem becomes obvious and fixed + delete tmpBlock; + return block; + } + + size_t tmpIndex = tmpRow * tmpWidth + tmpCol; + size_t index = row * theWidth + col; + + char *tmpBits = tmpBlock->bits( tmpIndex ); + char *bits = block->bits( index ); + if ( !tmpBits ) + { + QgsDebugMsg( QString( "Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) ); + continue; + } + if ( !bits ) + { + QgsDebugMsg( "Cannot set output block data." ); + continue; + } + memcpy( bits, tmpBits, pixelSize ); + } + } + + delete tmpBlock; + } + else + { + readBlock( theBandNo, theExtent, theWidth, theHeight, block->data() ); + } // apply user no data values // TODO: there are other readBlock methods where no data are not applied - QList myNoDataRangeList = userNoDataValue( bandNo ); + QList myNoDataRangeList = userNoDataValue( theBandNo ); if ( !myNoDataRangeList.isEmpty() ) { - //QgsRasterBlock::DataType type = dataType( bandNo ); - double myNoDataValue = noDataValue( bandNo ); - size_t size = width * height; + double myNoDataValue = noDataValue( theBandNo ); + size_t size = theWidth * theHeight; for ( size_t i = 0; i < size; i++ ) { double value = block->value( i ); @@ -308,58 +363,6 @@ QString QgsRasterDataProvider::lastErrorFormat() return "text/plain"; } -QByteArray QgsRasterDataProvider::noValueBytes( int theBandNo ) -{ - int type = dataType( theBandNo ); - size_t size = QgsRasterBlock::typeSize( dataType( theBandNo ) ) / 8; - QByteArray ba; - ba.resize(( int )size ); - char * data = ba.data(); - double noval = noDataValue( theBandNo - 1 ); - unsigned char uc; - unsigned short us; - short s; - unsigned int ui; - int i; - float f; - double d; - // TODO: define correct data types (typedef) like in GDAL - switch ( type ) - { - case QgsRasterBlock::Byte: - uc = ( unsigned char )noval; - memcpy( data, &uc, size ); - break; - case QgsRasterBlock::UInt16: - us = ( unsigned short )noval; - memcpy( data, &us, size ); - break; - case QgsRasterBlock::Int16: - s = ( short )noval; - memcpy( data, &s, size ); - break; - case QgsRasterBlock::UInt32: - ui = ( unsigned int )noval; - memcpy( data, &ui, size ); - break; - case QgsRasterBlock::Int32: - i = ( int )noval; - memcpy( data, &i, size ); - break; - case QgsRasterBlock::Float32: - f = ( float )noval; - memcpy( data, &f, size ); - break; - case QgsRasterBlock::Float64: - d = ( double )noval; - memcpy( data, &d, size ); - break; - default: - QgsLogger::warning( "GDAL data type is not supported" ); - } - return ba; -} - bool QgsRasterDataProvider::hasPyramids() { QList myPyramidList = buildPyramidList(); @@ -401,7 +404,7 @@ QgsRasterBandStats QgsRasterDataProvider::bandStatistics( int theBandNo ) int myNXBlocks = ( xSize() + xBlockSize() - 1 ) / xBlockSize(); int myNYBlocks = ( ySize() + yBlockSize() - 1 ) / yBlockSize(); - void *myData = CPLMalloc( xBlockSize() * yBlockSize() * ( dataTypeSize( theBandNo ) / 8 ) ); + void *myData = CPLMalloc( xBlockSize() * yBlockSize() * ( dataTypeSize( theBandNo ) ) ); // unfortunately we need to make two passes through the data to calculate stddev bool myFirstIterationFlag = true; @@ -659,7 +662,7 @@ QgsRasterBandStats QgsRasterDataProvider::bandStatistics( int theBandNo, int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize; int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize; - void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( QgsRasterBlock::typeSize( dataType( theBandNo ) ) / 8 ) ); + void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( QgsRasterBlock::typeSize( dataType( theBandNo ) ) ) ); double myXRes = myExtent.width() / myWidth; double myYRes = myExtent.height() / myHeight; @@ -935,7 +938,7 @@ QgsRasterHistogram QgsRasterDataProvider::histogram( int theBandNo, int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize; int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize; - void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( QgsRasterBlock::typeSize( dataType( theBandNo ) ) / 8 ) ); + void *myData = CPLMalloc( myXBlockSize * myYBlockSize * ( QgsRasterBlock::typeSize( dataType( theBandNo ) ) ) ); double myXRes = myExtent.width() / myWidth; double myYRes = myExtent.height() / myHeight; diff --git a/src/core/raster/qgsrasterdataprovider.h b/src/core/raster/qgsrasterdataprovider.h index 00b89c4ec24..abcf154908c 100644 --- a/src/core/raster/qgsrasterdataprovider.h +++ b/src/core/raster/qgsrasterdataprovider.h @@ -179,19 +179,12 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast // TODO: Get the file masks supported by this provider, suitable for feeding into the file open dialog box /** Returns data type for the band specified by number */ - virtual QgsRasterBlock::DataType dataType( int bandNo ) const - { - return srcDataType( bandNo ); - } + virtual QgsRasterBlock::DataType dataType( int bandNo ) const = 0; /** Returns source data type for the band specified by number, * source data type may be shorter than dataType */ - virtual QgsRasterBlock::DataType srcDataType( int bandNo ) const - { - Q_UNUSED( bandNo ); - return QgsRasterBlock::UnknownDataType; - } + virtual QgsRasterBlock::DataType srcDataType( int bandNo ) const = 0; /** Returns data type for the band specified by number */ virtual int colorInterpretation( int theBandNo ) const @@ -289,15 +282,8 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast 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 give extent and size */ - // @note not available in python bindings - //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. */ - // @note not available in python bindings - //virtual void *readBlock( int bandNo, QgsRectangle const & extent, int width, int height ); - - virtual QgsRasterBlock *block( int bandNo, const QgsRectangle &extent, int width, int height ); + 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 ); @@ -528,9 +514,6 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast static QString makeTableCell( const QString & value ); static QString makeTableCells( const QStringList & values ); - /** \brief Set null value in char */ - QByteArray noValueBytes( int theBandNo ); - /** Time stamp of data source in the moment when data/metadata were loaded by provider */ virtual QDateTime timestamp() const { return mTimestamp; } diff --git a/src/core/raster/qgsrasterfilewriter.cpp b/src/core/raster/qgsrasterfilewriter.cpp index 4bd80573781..31aa477d17d 100644 --- a/src/core/raster/qgsrasterfilewriter.cpp +++ b/src/core/raster/qgsrasterfilewriter.cpp @@ -437,7 +437,7 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeImageRaster( QgsRaste iter->setMaximumTileWidth( mMaxTileWidth ); iter->setMaximumTileHeight( mMaxTileHeight ); - //void* data = VSIMalloc( QgsRasterBlock::typeSize( inputDataType ) / 8 * mMaxTileWidth * mMaxTileHeight ); + //void* data = VSIMalloc( QgsRasterBlock::typeSize( inputDataType ) * mMaxTileWidth * mMaxTileHeight ); void* redData = VSIMalloc( mMaxTileWidth * mMaxTileHeight ); void* greenData = VSIMalloc( mMaxTileWidth * mMaxTileHeight ); void* blueData = VSIMalloc( mMaxTileWidth * mMaxTileHeight ); diff --git a/src/core/raster/qgsrasterlayer.cpp b/src/core/raster/qgsrasterlayer.cpp index de20607a43f..59b5faa93db 100644 --- a/src/core/raster/qgsrasterlayer.cpp +++ b/src/core/raster/qgsrasterlayer.cpp @@ -2819,7 +2819,7 @@ QString QgsRasterLayer::projectionWkt() #if 0 void *QgsRasterLayer::readData( int bandNo, QgsRasterViewPort *viewPort ) { - int size = mDataProvider->dataTypeSize( bandNo ) / 8; + int size = mDataProvider->dataTypeSize( bandNo ); #if 0 QgsDebugMsg( "calling RasterIO with " + diff --git a/src/core/raster/qgsrasterprojector.cpp b/src/core/raster/qgsrasterprojector.cpp index d1aec58c8db..fa806bb392d 100644 --- a/src/core/raster/qgsrasterprojector.cpp +++ b/src/core/raster/qgsrasterprojector.cpp @@ -734,7 +734,7 @@ QgsRasterBlock * QgsRasterProjector::block( int bandNo, QgsRectangle const & ex return outputBlock; } - size_t pixelSize = QgsRasterBlock::typeSize( mInput->dataType( bandNo ) ) / 8; + size_t pixelSize = QgsRasterBlock::typeSize( mInput->dataType( bandNo ) ); if ( !outputBlock->reset( QgsRasterBlock::ARGB32_Premultiplied, width, height ) ) { diff --git a/src/gui/raster/qgsmultibandcolorrendererwidget.cpp b/src/gui/raster/qgsmultibandcolorrendererwidget.cpp index 40fd9bc7e16..0448fa70bb9 100644 --- a/src/gui/raster/qgsmultibandcolorrendererwidget.cpp +++ b/src/gui/raster/qgsmultibandcolorrendererwidget.cpp @@ -35,8 +35,8 @@ QgsMultiBandColorRendererWidget::QgsMultiBandColorRendererWidget( QgsRasterLayer mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this ); mMinMaxWidget->setExtent( extent ); layout()->addWidget( mMinMaxWidget ); - connect( mMinMaxWidget, SIGNAL( load( int, double, double ) ), - this, SLOT( loadMinMax( int, double, double ) ) ); + connect( mMinMaxWidget, SIGNAL( load( int, double, double, int ) ), + this, SLOT( loadMinMax( int, double, double, int ) ) ); connect( mRedBandComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onBandChanged( int ) ) ); @@ -191,7 +191,7 @@ void QgsMultiBandColorRendererWidget::onBandChanged( int index ) mMinMaxWidget->setBands( myBands ); } -void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax ) +void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin ) { QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) ); diff --git a/src/gui/raster/qgsmultibandcolorrendererwidget.h b/src/gui/raster/qgsmultibandcolorrendererwidget.h index bb5b958539c..2a0cb5c4da1 100644 --- a/src/gui/raster/qgsmultibandcolorrendererwidget.h +++ b/src/gui/raster/qgsmultibandcolorrendererwidget.h @@ -48,7 +48,7 @@ class GUI_EXPORT QgsMultiBandColorRendererWidget: public QgsRasterRendererWidget int selectedBand( int index = 0 ); public slots: - void loadMinMax( int theBandNo, double theMin, double theMax ); + void loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin ); private slots: //void on_mLoadPushButton_clicked(); diff --git a/src/providers/gdal/qgsgdalprovider.cpp b/src/providers/gdal/qgsgdalprovider.cpp index e5838db5119..c50405a7953 100644 --- a/src/providers/gdal/qgsgdalprovider.cpp +++ b/src/providers/gdal/qgsgdalprovider.cpp @@ -378,10 +378,10 @@ void QgsGdalProvider::readBlock( int theBandNo, QgsRectangle const & theExtent, QgsDebugMsg( QString( "transform : %1" ).arg( mGeoTransform[i] ) ); } - int dataSize = dataTypeSize( theBandNo ) / 8; + int dataSize = dataTypeSize( theBandNo ); // fill with null values - QByteArray ba = noValueBytes( theBandNo ); + QByteArray ba = QgsRasterBlock::valueBytes( dataType( theBandNo ), noDataValue( theBandNo ) ); char *nodata = ba.data(); char *block = ( char * ) theBlock; for ( int i = 0; i < thePixelWidth * thePixelHeight; i++ ) @@ -835,7 +835,7 @@ QMap QgsGdalProvider::identify( const QgsPoint & point ) // Outside the raster for ( int i = 1; i <= GDALGetRasterCount( mGdalDataset ); i++ ) { - void * data = VSIMalloc( dataTypeSize( i ) / 8 ); + void * data = VSIMalloc( dataTypeSize( i ) ); QgsRasterBlock::writeValue( data, dataType( i ), 0, noDataValue( i ) ); results.insert( i, data ); } @@ -884,7 +884,7 @@ QMap QgsGdalProvider::identify( const QgsPoint & point ) } } #endif - int typeSize = dataTypeSize( i ) / 8; + int typeSize = dataTypeSize( i ); void * tmpData = VSIMalloc( typeSize * width * height ); CPLErr err = GDALRasterIO( gdalBand, GF_Read, col, row, width, height, diff --git a/src/providers/grass/qgsgrassrasterprovider.cpp b/src/providers/grass/qgsgrassrasterprovider.cpp index aa2e9d98d7a..f6801d9b5c0 100644 --- a/src/providers/grass/qgsgrassrasterprovider.cpp +++ b/src/providers/grass/qgsgrassrasterprovider.cpp @@ -128,7 +128,7 @@ QgsGrassRasterProvider::QgsGrassRasterProvider( QString const & uri ) // memory, not too small to result in too many calls to readBlock -> qgis.d.rast // for statistics int cache_size = 10000000; // ~ 10 MB - mYBlockSize = cache_size / ( dataTypeSize( dataType( 1 ) ) / 8 ) / mCols; + mYBlockSize = cache_size / ( dataTypeSize( dataType( 1 ) ) ) / mCols; if ( mYBlockSize > mRows ) { mYBlockSize = mRows; @@ -232,7 +232,7 @@ void QgsGrassRasterProvider::readBlock( int bandNo, int xBlock, int yBlock, void QgsDebugMsg( QString( "%1 bytes read from modules stdout" ).arg( data.size() ) ); // byteCount() in Qt >= 4.6 //int size = image->byteCount() < data.size() ? image->byteCount() : data.size(); - int size = mCols * mYBlockSize * dataTypeSize( bandNo ) / 8; + int size = mCols * mYBlockSize * dataTypeSize( bandNo ); QgsDebugMsg( QString( "mCols = %1 mYBlockSize = %2 dataTypeSize = %3" ).arg( mCols ).arg( mYBlockSize ).arg( dataTypeSize( bandNo ) ) ); if ( size != data.size() ) { @@ -279,7 +279,7 @@ void QgsGrassRasterProvider::readBlock( int bandNo, QgsRectangle const & viewEx QgsDebugMsg( QString( "%1 bytes read from modules stdout" ).arg( data.size() ) ); // byteCount() in Qt >= 4.6 //int size = image->byteCount() < data.size() ? image->byteCount() : data.size(); - int size = pixelWidth * pixelHeight * dataTypeSize( bandNo ) / 8; + int size = pixelWidth * pixelHeight * dataTypeSize( bandNo ); if ( size != data.size() ) { QMessageBox::warning( 0, QObject::tr( "Warning" ), @@ -439,7 +439,7 @@ QMap QgsGrassRasterProvider::identify( const QgsPoint & thePoint ) QgsDebugMsg( "Cannot convert string to double" ); } } - void * data = malloc( dataTypeSize( 1 ) / 8 ); + void * data = malloc( dataTypeSize( 1 ) ); QgsRasterBlock::writeValue( data, dataType( 1 ), 0, value ); results.insert( 1, data ); diff --git a/src/providers/wcs/qgswcsprovider.cpp b/src/providers/wcs/qgswcsprovider.cpp index 15abcc2dbda..8b35a6c1afe 100644 --- a/src/providers/wcs/qgswcsprovider.cpp +++ b/src/providers/wcs/qgswcsprovider.cpp @@ -503,7 +503,7 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in QgsDebugMsg( "Entered" ); // TODO: set block to null values, move that to function and call only if fails - memset( block, 0, pixelWidth * pixelHeight * QgsRasterBlock::typeSize( dataType( bandNo ) ) / 8 ); + memset( block, 0, pixelWidth * pixelHeight * QgsRasterBlock::typeSize( dataType( bandNo ) ) ); // Requested extent must at least partialy overlap coverage extent, otherwise // server gives error. QGIS usually does not request blocks outside raster extent @@ -579,7 +579,7 @@ void QgsWcsProvider::readBlock( int bandNo, QgsRectangle const & viewExtent, in // Rotate counter clockwise // If GridOffsets With GeoServer, QgsDebugMsg( tr( "Rotating raster" ) ); - int pixelSize = QgsRasterBlock::typeSize( dataType( bandNo ) ) / 8; + int pixelSize = QgsRasterBlock::typeSize( dataType( bandNo ) ); QgsDebugMsg( QString( "pixelSize = %1" ).arg( pixelSize ) ); int size = width * height * pixelSize; void * tmpData = malloc( size ); @@ -1643,7 +1643,7 @@ QMap QgsWcsProvider::identify( const QgsPoint & thePoint ) // Outside the raster for ( int i = 1; i <= bandCount(); i++ ) { - void * data = VSIMalloc( dataTypeSize( i ) / 8 ); + void * data = VSIMalloc( dataTypeSize( i ) ); QgsRasterBlock::writeValue( data, dataType( i ), 0, noDataValue( i ) ); results.insert( i, data ); } @@ -1708,7 +1708,7 @@ QMap QgsWcsProvider::identify( const QgsPoint & thePoint ) { GDALRasterBandH gdalBand = GDALGetRasterBand( mCachedGdalDataset, i ); - void * data = VSIMalloc( dataTypeSize( i ) / 8 ); + void * data = VSIMalloc( dataTypeSize( i ) ); CPLErr err = GDALRasterIO( gdalBand, GF_Read, col, row, 1, 1, data, 1, 1, ( GDALDataType ) mGdalDataType[i-1], 0, 0 );