Skip to content
Permalink
Browse files
Safer approach to saving common QgsFeatureRenderer properties
  • Loading branch information
nyalldawson committed Jun 28, 2021
1 parent 54610b2 commit c8da0c43f97e0f9a7637f1acc0a33a20b7d75cb2
@@ -259,7 +259,10 @@ create a renderer from XML element

virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context );
%Docstring
store renderer info to XML element
Stores renderer properties to an XML element.

Subclasses which override this method should call :py:func:`~QgsFeatureRenderer.saveRendererData` as part of their
implementation in order to store all common base class properties in the returned DOM element.
%End

virtual QDomElement writeSld( QDomDocument &doc, const QString &styleName, const QVariantMap &props = QVariantMap() ) const;
@@ -544,6 +547,16 @@ Currently clones
:param destRenderer: destination renderer for copied effect
%End

void saveRendererData( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context );
%Docstring
Saves generic renderer data into the specified ``element``.

This method should be called in a subclass' :py:func:`~QgsFeatureRenderer.save` implementation in order
to store all common base class properties in the DOM ``element``.

.. versionadded:: 3.22
%End




@@ -122,6 +122,8 @@ QDomElement Qgs25DRenderer::save( QDomDocument &doc, const QgsReadWriteContext &

QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "symbol" ), mSymbol.get(), doc, context );

saveRendererData( doc, rendererElem, context );

rendererElem.appendChild( symbolElem );

return rendererElem;
@@ -776,8 +776,6 @@ QDomElement QgsCategorizedSymbolRenderer::save( QDomDocument &doc, const QgsRead
// clazy:skip
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "categorizedSymbol" ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "attr" ), mAttrName );

// categories
@@ -819,7 +817,6 @@ QDomElement QgsCategorizedSymbolRenderer::save( QDomDocument &doc, const QgsRead
// save symbols
QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context );
rendererElem.appendChild( symbolsElem );

}

// save source symbol
@@ -844,24 +841,15 @@ QDomElement QgsCategorizedSymbolRenderer::save( QDomDocument &doc, const QgsRead
QDomElement sizeScaleElem = doc.createElement( QStringLiteral( "sizescale" ) );
rendererElem.appendChild( sizeScaleElem );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mDataDefinedSizeLegend )
{
QDomElement ddsLegendElem = doc.createElement( QStringLiteral( "data-defined-size-legend" ) );
mDataDefinedSizeLegend->writeXml( ddsLegendElem, context );
rendererElem.appendChild( ddsLegendElem );
}

saveRendererData( doc, rendererElem, context );

return rendererElem;
}

@@ -137,24 +137,13 @@ QDomElement QgsEmbeddedSymbolRenderer::save( QDomDocument &doc, const QgsReadWri
{
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "embeddedSymbol" ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

QgsSymbolMap symbols;
symbols[QStringLiteral( "0" )] = mDefaultSymbol.get();
QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context );
rendererElem.appendChild( symbolsElem );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}
@@ -627,8 +627,6 @@ QDomElement QgsGraduatedSymbolRenderer::save( QDomDocument &doc, const QgsReadWr
{
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "graduatedSymbol" ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "attr" ), mAttrName );
rendererElem.setAttribute( QStringLiteral( "graduatedMethod" ), graduatedMethodStr( mGraduatedMethod ) );

@@ -685,24 +683,15 @@ QDomElement QgsGraduatedSymbolRenderer::save( QDomDocument &doc, const QgsReadWr
QDomElement sizeScaleElem = doc.createElement( QStringLiteral( "sizescale" ) );
rendererElem.appendChild( sizeScaleElem );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mDataDefinedSizeLegend )
{
QDomElement ddsLegendElem = doc.createElement( QStringLiteral( "data-defined-size-legend" ) );
mDataDefinedSizeLegend->writeXml( ddsLegendElem, context );
rendererElem.appendChild( ddsLegendElem );
}

saveRendererData( doc, rendererElem, context );

return rendererElem;
}

@@ -335,23 +335,14 @@ QDomElement QgsHeatmapRenderer::save( QDomDocument &doc, const QgsReadWriteConte
rendererElem.setAttribute( QStringLiteral( "max_value" ), QString::number( mExplicitMax ) );
rendererElem.setAttribute( QStringLiteral( "quality" ), QString::number( mRenderQuality ) );
rendererElem.setAttribute( QStringLiteral( "weight_expression" ), mWeightExpressionString );

if ( mGradientRamp )
{
QDomElement colorRampElem = QgsSymbolLayerUtils::saveColorRamp( QStringLiteral( "[source]" ), mGradientRamp, doc );
rendererElem.appendChild( colorRampElem );
}
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}
@@ -86,24 +86,14 @@ QDomElement QgsInvertedPolygonRenderer::save( QDomDocument &doc, const QgsReadWr
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "invertedPolygonRenderer" ) );
rendererElem.setAttribute( QStringLiteral( "preprocessing" ), preprocessingEnabled() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mSubRenderer )
{
QDomElement embeddedRendererElem = mSubRenderer->save( doc, context );
rendererElem.appendChild( embeddedRendererElem );
}

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}
@@ -442,24 +442,14 @@ QDomElement QgsMergedFeatureRenderer::save( QDomDocument &doc, const QgsReadWrit

QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "mergedFeatureRenderer" ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mSubRenderer )
{
QDomElement embeddedRendererElem = mSubRenderer->save( doc, context );
rendererElem.appendChild( embeddedRendererElem );
}

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}
@@ -112,6 +112,9 @@ QDomElement QgsNullSymbolRenderer::save( QDomDocument &doc, const QgsReadWriteCo
Q_UNUSED( context )
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "nullSymbol" ) );

saveRendererData( doc, rendererElem, context );

return rendererElem;
}

@@ -127,7 +127,6 @@ QgsMarkerSymbol *QgsPointClusterRenderer::clusterSymbol()
QDomElement QgsPointClusterRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
{
QDomElement rendererElement = doc.createElement( RENDERER_TAG_NAME );
rendererElement.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "pointCluster" ) );
rendererElement.setAttribute( QStringLiteral( "tolerance" ), QString::number( mTolerance ) );
rendererElement.setAttribute( QStringLiteral( "toleranceUnit" ), QgsUnitTypes::encodeUnit( mToleranceUnit ) );
@@ -144,16 +143,7 @@ QDomElement QgsPointClusterRenderer::save( QDomDocument &doc, const QgsReadWrite
rendererElement.appendChild( centerSymbolElem );
}

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElement );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElement.appendChild( orderBy );
}
rendererElement.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElement, context );

return rendererElement;
}
@@ -194,7 +194,6 @@ QgsMarkerSymbol *QgsPointDisplacementRenderer::centerSymbol()
QDomElement QgsPointDisplacementRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
{
QDomElement rendererElement = doc.createElement( RENDERER_TAG_NAME );
rendererElement.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "pointDisplacement" ) );
rendererElement.setAttribute( QStringLiteral( "labelAttributeName" ), mLabelAttributeName );
rendererElement.appendChild( QgsFontUtils::toXmlElement( mLabelFont, doc, QStringLiteral( "labelFontProperties" ) ) );
@@ -220,16 +219,7 @@ QDomElement QgsPointDisplacementRenderer::save( QDomDocument &doc, const QgsRead
rendererElement.appendChild( centerSymbolElem );
}

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElement );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElement.appendChild( orderBy );
}
rendererElement.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElement, context );

return rendererElement;
}
@@ -192,7 +192,16 @@ QDomElement QgsFeatureRenderer::save( QDomDocument &doc, const QgsReadWriteConte
Q_UNUSED( context )
// create empty renderer element
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );

saveRendererData( doc, rendererElem, context );

return rendererElem;
}

void QgsFeatureRenderer::saveRendererData( QDomDocument &doc, QDomElement &rendererElem, const QgsReadWriteContext & )
{
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );
@@ -204,7 +213,6 @@ QDomElement QgsFeatureRenderer::save( QDomDocument &doc, const QgsReadWriteConte
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
return rendererElem;
}

QgsFeatureRenderer *QgsFeatureRenderer::loadSld( const QDomNode &node, QgsWkbTypes::GeometryType geomType, QString &errorMessage )
@@ -294,7 +294,12 @@ class CORE_EXPORT QgsFeatureRenderer
//! create a renderer from XML element
static QgsFeatureRenderer *load( QDomElement &symbologyElem, const QgsReadWriteContext &context ) SIP_FACTORY;

//! store renderer info to XML element
/**
* Stores renderer properties to an XML element.
*
* Subclasses which override this method should call saveRendererData() as part of their
* implementation in order to store all common base class properties in the returned DOM element.
*/
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context );

/**
@@ -525,6 +530,16 @@ class CORE_EXPORT QgsFeatureRenderer
*/
void copyRendererData( QgsFeatureRenderer *destRenderer ) const;

/**
* Saves generic renderer data into the specified \a element.
*
* This method should be called in a subclass' save() implementation in order
* to store all common base class properties in the DOM \a element.
*
* \since QGIS 3.22
*/
void saveRendererData( QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context );

QString mType;

bool mUsingSymbolLevels = false;
@@ -1080,8 +1080,6 @@ QDomElement QgsRuleBasedRenderer::save( QDomDocument &doc, const QgsReadWriteCon
{
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "RuleRenderer" ) );
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );

QgsSymbolMap symbols;

@@ -1092,16 +1090,7 @@ QDomElement QgsRuleBasedRenderer::save( QDomDocument &doc, const QgsReadWriteCon
QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( symbols, QStringLiteral( "symbols" ), doc, context );
rendererElem.appendChild( symbolsElem );

if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
mPaintEffect->saveProperties( doc, rendererElem );

if ( !mOrderBy.isEmpty() )
{
QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
mOrderBy.save( orderBy );
rendererElem.appendChild( orderBy );
}
rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
saveRendererData( doc, rendererElem, context );

return rendererElem;
}

0 comments on commit c8da0c4

Please sign in to comment.