mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-01 00:46:20 -05:00
nodata rendered transparent
This commit is contained in:
parent
5579962fb0
commit
4ae7b522ab
@ -1298,9 +1298,9 @@ void QgsRasterLayerProperties::pixelSelected( const QgsPoint& canvasPoint )
|
||||
mRasterLayer->identify( mMapCanvas->mapRenderer()->mapToLayerCoordinates( mRasterLayer, canvasPoint ), myPixelMap );
|
||||
|
||||
QList<int> bands = renderer->usesBands();
|
||||
tableTransparency->insertRow( tableTransparency->rowCount() );
|
||||
setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 );
|
||||
delete renderer;
|
||||
|
||||
QList<double> values;
|
||||
for ( int i = 0; i < bands.size(); ++i )
|
||||
{
|
||||
QMap< int, QString >::const_iterator pixelResult = myPixelMap.find( bands.at( i ) );
|
||||
@ -1309,20 +1309,31 @@ void QgsRasterLayerProperties::pixelSelected( const QgsPoint& canvasPoint )
|
||||
QString value = pixelResult.value();
|
||||
if ( value != tr( "out of extent" ) )
|
||||
{
|
||||
setTransparencyCell( tableTransparency->rowCount() - 1, i, value.toDouble() );
|
||||
QgsDebugMsg( QString( "Is it %1 of band %2 nodata?" ).arg( value ).arg( bands.at( i ) ) );
|
||||
if ( value == tr( "null (no data)" ) || // Very bad! TODO: improve identify
|
||||
mRasterLayer->dataProvider()->isNoDataValue( bands.at( i ), value.toDouble() ) )
|
||||
{
|
||||
return; // Dont add nodata, transparent anyway
|
||||
}
|
||||
values.append( value.toDouble() );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( bands.size() == 1 )
|
||||
{
|
||||
// Set 'to'
|
||||
setTransparencyCell( tableTransparency->rowCount() - 1, 1, transparencyCellValue( tableTransparency->rowCount() - 1, 0 ) );
|
||||
values.insert( 1, values.value( 0 ) );
|
||||
}
|
||||
tableTransparency->insertRow( tableTransparency->rowCount() );
|
||||
for ( int i = 0; i < values.size(); i++ )
|
||||
{
|
||||
setTransparencyCell( tableTransparency->rowCount() - 1, i, values.value( i ) );
|
||||
}
|
||||
setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 );
|
||||
}
|
||||
|
||||
tableTransparency->resizeColumnsToContents();
|
||||
tableTransparency->resizeRowsToContents();
|
||||
delete renderer;
|
||||
}
|
||||
|
||||
void QgsRasterLayerProperties::sliderTransparency_valueChanged( int theValue )
|
||||
|
@ -234,22 +234,42 @@ void * QgsMultiBandColorRenderer::readBlock( int bandNo, QgsRectangle const & e
|
||||
redVal = readValue( redData, redType, currentRasterPos );
|
||||
greenVal = readValue( greenData, greenType, currentRasterPos );
|
||||
blueVal = readValue( blueData, blueType, currentRasterPos );
|
||||
imageScanLine[j] = qRgba( redVal, greenVal, blueVal, 255 );
|
||||
if ( mInput->isNoDataValue( mRedBand, redVal ) ||
|
||||
mInput->isNoDataValue( mGreenBand, greenVal ) ||
|
||||
mInput->isNoDataValue( mBlueBand, blueVal ) )
|
||||
{
|
||||
imageScanLine[j] = defaultColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
imageScanLine[j] = qRgba( redVal, greenVal, blueVal, 255 );
|
||||
}
|
||||
|
||||
++currentRasterPos;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isNoData = false;
|
||||
if ( mRedBand > 0 )
|
||||
{
|
||||
redVal = readValue( redData, redType, currentRasterPos );
|
||||
if ( mInput->isNoDataValue( mRedBand, redVal ) ) isNoData = true;
|
||||
}
|
||||
if ( mGreenBand > 0 )
|
||||
{
|
||||
greenVal = readValue( greenData, greenType, currentRasterPos );
|
||||
if ( mInput->isNoDataValue( mGreenBand, greenVal ) ) isNoData = true;
|
||||
}
|
||||
if ( mBlueBand > 0 )
|
||||
{
|
||||
blueVal = readValue( blueData, blueType, currentRasterPos );
|
||||
if ( mInput->isNoDataValue( mBlueBand, blueVal ) ) isNoData = true;
|
||||
}
|
||||
if ( isNoData )
|
||||
{
|
||||
imageScanLine[j] = defaultColor;
|
||||
++currentRasterPos;
|
||||
continue;
|
||||
}
|
||||
|
||||
//apply default color if red, green or blue not in displayable range
|
||||
|
@ -93,6 +93,7 @@ void * QgsPalettedRasterRenderer::readBlock( int bandNo, QgsRectangle const & e
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
QRgb myDefaultColor = qRgba( 0, 0, 0, 0 );
|
||||
|
||||
QgsRasterInterface::DataType transparencyType = QgsRasterInterface::UnknownDataType;
|
||||
if ( mAlphaBand > 0 )
|
||||
@ -129,6 +130,12 @@ void * QgsPalettedRasterRenderer::readBlock( int bandNo, QgsRectangle const & e
|
||||
for ( int j = 0; j < width; ++j )
|
||||
{
|
||||
val = readValue( rasterData, rasterType, currentRasterPos );
|
||||
if ( mInput->isNoDataValue( mBandNumber, val ) )
|
||||
{
|
||||
imageScanLine[j] = myDefaultColor;
|
||||
++currentRasterPos;
|
||||
continue;
|
||||
}
|
||||
if ( !hasTransparency )
|
||||
{
|
||||
imageScanLine[j] = mColors[ val ].rgba();
|
||||
|
@ -120,6 +120,18 @@ QgsRasterInterface::DataType QgsRasterInterface::typeWithNoDataValue( DataType d
|
||||
return newDataType;
|
||||
}
|
||||
|
||||
inline bool QgsRasterInterface::isNoDataValue( int bandNo, double value ) const
|
||||
{
|
||||
// More precise would be qIsNaN(value) && qIsNaN(noDataValue(bandNo)), but probably
|
||||
// not important and slower
|
||||
if ( qIsNaN( value ) ||
|
||||
doubleNear( value, noDataValue( bandNo ) ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// To give to an image preallocated memory is the only way to avoid memcpy
|
||||
// when we want to keep data but delete QImage
|
||||
QImage * QgsRasterInterface::createImage( int width, int height, QImage::Format format )
|
||||
|
@ -125,8 +125,22 @@ class CORE_EXPORT QgsRasterInterface
|
||||
}
|
||||
|
||||
/** Retruns value representing 'no data' (NULL) */
|
||||
// TODO: Q_DECL_DEPRECATED
|
||||
virtual double noDataValue() const { return 0; }
|
||||
|
||||
/** 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 noDataValue(); }
|
||||
|
||||
/** 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 ;
|
||||
|
||||
/** Read block of data using given extent and size.
|
||||
* Returns pointer to data.
|
||||
* Caller is responsible to free the memory returned.
|
||||
|
@ -178,11 +178,17 @@ bool QgsRasterTransparency::isEmpty( double nodataValue ) const
|
||||
{
|
||||
return (
|
||||
( mTransparentSingleValuePixelList.isEmpty() ||
|
||||
( mTransparentSingleValuePixelList.size() == 1 && doubleNear( mTransparentSingleValuePixelList.at( 0 ).min, nodataValue ) && doubleNear( mTransparentSingleValuePixelList.at( 0 ).max, nodataValue ) ) )
|
||||
( mTransparentSingleValuePixelList.size() == 1 &&
|
||||
( doubleNear( mTransparentSingleValuePixelList.at( 0 ).min, nodataValue ) ||
|
||||
doubleNear( mTransparentSingleValuePixelList.at( 0 ).max, nodataValue ) ||
|
||||
( nodataValue > mTransparentSingleValuePixelList.at( 0 ).min &&
|
||||
nodataValue < mTransparentSingleValuePixelList.at( 0 ).max ) ) ) )
|
||||
&&
|
||||
( mTransparentThreeValuePixelList.isEmpty() ||
|
||||
( mTransparentThreeValuePixelList.size() < 4 && doubleNear( mTransparentThreeValuePixelList.at( 0 ).red, nodataValue ) &&
|
||||
doubleNear( mTransparentThreeValuePixelList.at( 0 ).green, nodataValue ) && doubleNear( mTransparentThreeValuePixelList.at( 0 ).blue, nodataValue ) ) ) );
|
||||
( mTransparentThreeValuePixelList.size() == 1 &&
|
||||
doubleNear( mTransparentThreeValuePixelList.at( 0 ).red, nodataValue ) &&
|
||||
doubleNear( mTransparentThreeValuePixelList.at( 0 ).green, nodataValue ) &&
|
||||
doubleNear( mTransparentThreeValuePixelList.at( 0 ).blue, nodataValue ) ) ) );
|
||||
}
|
||||
|
||||
void QgsRasterTransparency::writeXML( QDomDocument& doc, QDomElement& parentElem ) const
|
||||
|
@ -118,6 +118,13 @@ void * QgsSingleBandGrayRenderer::readBlock( int bandNo, QgsRectangle const & e
|
||||
{
|
||||
grayVal = readValue( rasterData, rasterType, currentRasterPos );
|
||||
|
||||
if ( mInput->isNoDataValue( mGrayBand, grayVal ) )
|
||||
{
|
||||
imageScanLine[j] = myDefaultColor;
|
||||
++currentRasterPos;
|
||||
continue;
|
||||
}
|
||||
|
||||
//alpha
|
||||
currentAlpha = mOpacity;
|
||||
if ( mRasterTransparency )
|
||||
|
@ -117,6 +117,12 @@ void * QgsSingleBandPseudoColorRenderer::readBlock( int bandNo, QgsRectangle co
|
||||
for ( int j = 0; j < width; ++j )
|
||||
{
|
||||
val = readValue( rasterData, rasterType, currentRasterPos );
|
||||
if ( mInput->isNoDataValue( mBand, val ) )
|
||||
{
|
||||
imageScanLine[j] = myDefaultColor;
|
||||
++currentRasterPos;
|
||||
continue;
|
||||
}
|
||||
if ( !mShader->shade( val, &red, &green, &blue ) )
|
||||
{
|
||||
imageScanLine[j] = myDefaultColor;
|
||||
|
Loading…
x
Reference in New Issue
Block a user