Skip to content

Commit 3e33cf8

Browse files
committed
more robust raster color map conversion from 1.8 project and style file, fixes #7023
1 parent d818561 commit 3e33cf8

File tree

2 files changed

+52
-8
lines changed

2 files changed

+52
-8
lines changed

src/core/qgsprojectfiletransform.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,31 @@ void QgsProjectFileTransform::convertRasterProperties( QDomDocument& doc, QDomNo
617617

618618
//convert renderer specific properties
619619
QString drawingStyle = rasterPropertiesElem.firstChildElement( "mDrawingStyle" ).text();
620+
621+
// While PalettedColor should normaly contain only integer values, usually
622+
// color palette 0-255, it may happen (Tim, issue #7023) that it contains
623+
// colormap classification with double values and text labels
624+
// (which should normaly only appear in SingleBandPseudoColor drawingStyle)
625+
// => we have to check first the values and change drawingStyle if necessary
626+
if ( drawingStyle == "PalettedColor" )
627+
{
628+
QDomElement customColorRampElem = rasterPropertiesElem.firstChildElement( "customColorRamp" );
629+
QDomNodeList colorRampEntryList = customColorRampElem.elementsByTagName( "colorRampEntry" );
630+
631+
for ( int i = 0; i < colorRampEntryList.size(); ++i )
632+
{
633+
QDomElement colorRampEntryElem = colorRampEntryList.at( i ).toElement();
634+
QString strValue = colorRampEntryElem.attribute( "value" );
635+
double value = strValue.toDouble();
636+
if ( value < 0 || value > 10000 || value != ( int )value )
637+
{
638+
QgsDebugMsg( QString( "forcing SingleBandPseudoColor value = %1" ).arg( value ) );
639+
drawingStyle = "SingleBandPseudoColor";
640+
break;
641+
}
642+
}
643+
}
644+
620645
if ( drawingStyle == "SingleBandGray" )
621646
{
622647
rasterRendererElem.setAttribute( "type", "singlebandgray" );

src/core/raster/qgspalettedrasterrenderer.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,36 @@ QgsRasterRenderer* QgsPalettedRasterRenderer::create( const QDomElement& elem, Q
6969
if ( !paletteElem.isNull() )
7070
{
7171
QDomNodeList paletteEntries = paletteElem.elementsByTagName( "paletteEntry" );
72-
nColors = paletteEntries.size();
73-
colors = new QRgb[ nColors ];
7472

75-
int value = 0;
7673
QDomElement entryElem;
74+
int value;
75+
nColors = 0;
76+
77+
// We cannot believe that data are correct, check first max value
78+
for ( int i = 0; i < paletteEntries.size(); ++i )
79+
{
80+
entryElem = paletteEntries.at( i ).toElement();
81+
// Could be written as doubles (with .0000) in old project files
82+
value = ( int )entryElem.attribute( "value", "0" ).toDouble();
83+
if ( value >= nColors && value <= 10000 ) nColors = value + 1;
84+
}
85+
QgsDebugMsg( QString( "nColors = %1" ).arg( nColors ) );
86+
87+
colors = new QRgb[ nColors ];
88+
7789
for ( int i = 0; i < nColors; ++i )
7890
{
7991
entryElem = paletteEntries.at( i ).toElement();
80-
value = entryElem.attribute( "value", "0" ).toInt();
92+
value = ( int )entryElem.attribute( "value", "0" ).toDouble();
8193
QgsDebugMsg( entryElem.attribute( "color", "#000000" ) );
82-
colors[value] = QColor( entryElem.attribute( "color", "#000000" ) ).rgba();
94+
if ( value >= 0 && value < nColors )
95+
{
96+
colors[value] = QColor( entryElem.attribute( "color", "#000000" ) ).rgba();
97+
}
98+
else
99+
{
100+
QgsDebugMsg( QString( "value %1 out of range" ).arg( value ) );
101+
}
83102
}
84103
}
85104
QgsRasterRenderer* r = new QgsPalettedRasterRenderer( input, bandNumber, colors, nColors );
@@ -171,7 +190,7 @@ QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle con
171190
}
172191

173192
//create copy of color table with nodata values replaced by fully transparent color
174-
QVector<QRgb> colorTable(mNColors);
193+
QVector<QRgb> colorTable( mNColors );
175194
for ( int i = 0; i < mNColors; ++i )
176195
{
177196
if ( inputBlock->isNoDataValue( i ) )
@@ -194,7 +213,7 @@ QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle con
194213
int val = ( int ) inputBlock->value( i );
195214
if ( !hasTransparency )
196215
{
197-
outputData[i] = colorTable[ val ];
216+
outputData[i] = colorTable.value( val );
198217
}
199218
else
200219
{
@@ -207,7 +226,7 @@ QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle con
207226
{
208227
currentOpacity *= alphaBlock->value( i ) / 255.0;
209228
}
210-
QColor currentColor = QColor( colorTable[val] );
229+
QColor currentColor = QColor( colorTable.value( val ) );
211230
outputData[i] = qRgba( currentOpacity * currentColor.red(), currentOpacity * currentColor.green(), currentOpacity * currentColor.blue(), currentOpacity * 255 );
212231
}
213232
}

0 commit comments

Comments
 (0)