mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
undersampling if possible in QgsRasterDataProvider, multicolor widget loadMinMax fix
This commit is contained in:
parent
c46009e133
commit
6b55ee4fa0
@ -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;
|
||||
|
||||
|
@ -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 );
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<QgsRasterBlock::Range> myNoDataRangeList = userNoDataValue( bandNo );
|
||||
QList<QgsRasterBlock::Range> 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<QgsRasterPyramid> 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;
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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 " +
|
||||
|
@ -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 ) )
|
||||
{
|
||||
|
@ -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 ) );
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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<int, void *> 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<int, void *> 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,
|
||||
|
@ -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<int, void *> 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 );
|
||||
|
@ -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<int, void *> 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<int, void *> 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 );
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user