Skip to content

Commit

Permalink
undersampling if possible in QgsRasterDataProvider, multicolor widget…
Browse files Browse the repository at this point in the history
… loadMinMax fix
  • Loading branch information
blazek committed Oct 16, 2012
1 parent c46009e commit 6b55ee4
Show file tree
Hide file tree
Showing 14 changed files with 258 additions and 175 deletions.
7 changes: 2 additions & 5 deletions python/core/raster/qgsrasterdataprovider.sip
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion python/gui/raster/qgsmultibandcolorrendererwidget.sip
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
};
85 changes: 83 additions & 2 deletions src/core/raster/qgsrasterblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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++ )
{
Expand All @@ -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;
}
33 changes: 26 additions & 7 deletions src/core/raster/qgsrasterblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -289,7 +309,6 @@ class CORE_EXPORT QgsRasterBlock
static QImage::Format imageFormat( QgsRasterBlock::DataType theDataType );
static DataType dataType( QImage::Format theFormat );


// Valid
//bool isValid;

Expand Down

0 comments on commit 6b55ee4

Please sign in to comment.