25 #include <QDomDocument>
26 #include <QDomElement>
34 , mClassData( classes )
42 if ( mSourceColorRamp )
56 int bandNumber = elem.attribute( QStringLiteral(
"band" ), QStringLiteral(
"-1" ) ).toInt();
59 QDomElement paletteElem = elem.firstChildElement( QStringLiteral(
"colorPalette" ) );
60 if ( !paletteElem.isNull() )
62 QDomNodeList paletteEntries = paletteElem.elementsByTagName( QStringLiteral(
"paletteEntry" ) );
64 QDomElement entryElem;
67 for (
int i = 0; i < paletteEntries.size(); ++i )
71 entryElem = paletteEntries.at( i ).toElement();
72 value =
static_cast<int>( entryElem.attribute( QStringLiteral(
"value" ), QStringLiteral(
"0" ) ).toDouble() );
74 color = QColor( entryElem.attribute( QStringLiteral(
"color" ), QStringLiteral(
"#000000" ) ) );
75 color.setAlpha( entryElem.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"255" ) ).toInt() );
76 label = entryElem.attribute( QStringLiteral(
"label" ) );
85 QDomElement sourceColorRampElem = elem.firstChildElement( QStringLiteral(
"colorramp" ) );
86 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral(
"name" ) ) == QLatin1String(
"[source]" ) )
101 const auto constMClassData = mClassData;
102 for (
const Class &
c : constMClassData )
104 if (
c.value == idx )
113 ClassData::iterator cIt = mClassData.begin();
114 for ( ; cIt != mClassData.end(); ++cIt )
116 if ( cIt->value == idx )
126 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
127 if ( !
mInput || mClassData.isEmpty() )
129 return outputBlock.release();
132 std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mBand,
extent, width, height, feedback ) );
134 if ( !inputBlock || inputBlock->isEmpty() )
136 QgsDebugMsg( QStringLiteral(
"No raster data!" ) );
137 return outputBlock.release();
145 std::shared_ptr< QgsRasterBlock > alphaBlock;
150 if ( !alphaBlock || alphaBlock->isEmpty() )
152 return outputBlock.release();
157 alphaBlock = inputBlock;
162 return outputBlock.release();
169 Q_ASSERT( outputBlock );
170 unsigned int *outputData = (
unsigned int * )( outputBlock->bits() );
173 bool isNoData =
false;
174 for (
qgssize i = 0; i < rasterSize; ++i )
176 const double value = inputBlock->valueAndNoData( i, isNoData );
179 outputData[i] = myDefaultColor;
182 int val =
static_cast< int >( value );
183 if ( !mColors.contains( val ) )
185 outputData[i] = myDefaultColor;
189 if ( !hasTransparency )
191 outputData[i] = mColors.value( val );
202 currentOpacity *= alphaBlock->value( i ) / 255.0;
205 QRgb
c = mColors.value( val );
206 outputData[i] = qRgba( currentOpacity * qRed(
c ), currentOpacity * qGreen(
c ), currentOpacity * qBlue(
c ), currentOpacity * qAlpha(
c ) );
210 return outputBlock.release();
215 if ( parentElem.isNull() )
220 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
223 rasterRendererElem.setAttribute( QStringLiteral(
"band" ), mBand );
224 QDomElement colorPaletteElem = doc.createElement( QStringLiteral(
"colorPalette" ) );
225 ClassData::const_iterator it = mClassData.constBegin();
226 for ( ; it != mClassData.constEnd(); ++it )
228 QColor color = it->color;
229 QDomElement colorElem = doc.createElement( QStringLiteral(
"paletteEntry" ) );
230 colorElem.setAttribute( QStringLiteral(
"value" ), it->value );
231 colorElem.setAttribute( QStringLiteral(
"color" ), color.name() );
232 colorElem.setAttribute( QStringLiteral(
"alpha" ), color.alpha() );
233 if ( !it->label.isEmpty() )
235 colorElem.setAttribute( QStringLiteral(
"label" ), it->label );
237 colorPaletteElem.appendChild( colorElem );
239 rasterRendererElem.appendChild( colorPaletteElem );
242 if ( mSourceColorRamp )
245 rasterRendererElem.appendChild( colorRampElem );
248 parentElem.appendChild( rasterRendererElem );
257 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
258 if ( elements.size() == 0 )
262 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
265 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
266 rasterSymbolizerElem.appendChild( channelSelectionElem );
269 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
270 channelSelectionElem.appendChild( channelElem );
273 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
274 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
band() ) ) );
275 channelElem.appendChild( sourceChannelNameElem );
278 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
279 colorMapElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"values" ) );
280 if ( this->
classes().size() >= 255 )
281 colorMapElem.setAttribute( QStringLiteral(
"extended" ), QStringLiteral(
"true" ) );
282 rasterSymbolizerElem.appendChild( colorMapElem );
286 QList<QgsPalettedRasterRenderer::Class>
classes = this->
classes();
287 QList<QgsPalettedRasterRenderer::Class>::const_iterator classDataIt =
classes.constBegin();
288 for ( ; classDataIt !=
classes.constEnd(); ++classDataIt )
290 QDomElement colorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
291 colorMapElem.appendChild( colorMapEntryElem );
294 colorMapEntryElem.setAttribute( QStringLiteral(
"color" ), classDataIt->color.name() );
295 colorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), QString::number( classDataIt->value ) );
296 colorMapEntryElem.setAttribute( QStringLiteral(
"label" ), classDataIt->label );
297 if ( classDataIt->color.alphaF() != 1.0 )
299 colorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( classDataIt->color.alphaF() ) );
306 if ( mSourceColorRamp )
318 ClassData::const_iterator it = mClassData.constBegin();
319 for ( ; it != mClassData.constEnd(); ++it )
321 QString lab = it->label.isEmpty() ? QString::number( it->value ) : it->label;
322 symbolItems << qMakePair( lab, it->color );
338 mSourceColorRamp.reset( ramp );
343 return mSourceColorRamp.get();
348 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
350 for ( ; colorIt != table.constEnd(); ++colorIt )
352 int idx = ( int )( colorIt->value );
362 QRegularExpression linePartRx( QStringLiteral(
"[\\s,:]+" ) );
364 QStringList parts =
string.split(
'\n', QString::SkipEmptyParts );
365 const auto constParts = parts;
366 for (
const QString &part : constParts )
368 QStringList lineParts = part.split( linePartRx, QString::SkipEmptyParts );
370 switch ( lineParts.count() )
374 int value = lineParts.at( 0 ).toInt( &ok );
384 int value = lineParts.at( 0 ).toInt( &ok );
388 QColor
c( lineParts.at( 1 ) );
396 if ( lineParts.count() < 4 )
399 int value = lineParts.at( 0 ).toInt( &ok );
404 double r = lineParts.at( 1 ).toDouble( &rOk );
406 double g = lineParts.at( 2 ).toDouble( &gOk );
408 double b = lineParts.at( 3 ).toDouble( &bOk );
411 if ( rOk && gOk && bOk )
413 c = QColor( r, g, b );
416 if ( lineParts.count() >= 5 )
418 double alpha = lineParts.at( 4 ).toDouble( &ok );
424 if ( lineParts.count() > 5 )
426 label = lineParts.mid( 5 ).join(
' ' );
440 QFile inputFile( path );
442 if ( inputFile.open( QIODevice::ReadOnly ) )
444 QTextStream in( &inputFile );
445 input = in.readAll();
456 std::sort( cd.begin(), cd.end(), [](
const Class & a,
const Class & b ) ->
bool
458 return a.value < b.value;
461 const auto constCd = cd;
462 for (
const Class &
c : constCd )
464 out << QStringLiteral(
"%1 %2 %3 %4 %5 %6" ).arg(
c.value ).arg(
c.color.red() )
465 .arg(
c.color.green() ).arg(
c.color.blue() ).arg(
c.color.alpha() ).arg(
c.label );
467 return out.join(
'\n' );
483 int bins = std::ceil( max - min ) + 1;
496 double presentValues = 0;
502 data <<
Class( currentValue, QColor(), QString::number( currentValue ) );
505 currentValue += interval;
517 randomRamp->setTotalColorCount( data.count() );
520 if ( presentValues > 1 )
523 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
524 for ( ; cIt != data.end(); ++cIt )
526 cIt->color = ramp->
color( i / presentValues );
533 void QgsPalettedRasterRenderer::updateArrays()
537 ClassData::const_iterator it = mClassData.constBegin();
538 for ( ; it != mClassData.constEnd(); ++it )
540 mColors[it->value] = qPremultiply( it->color.rgba() );