Skip to content

Commit

Permalink
Add QgsSymbol::canCauseArtifactsBetweenAdjacentTiles()
Browse files Browse the repository at this point in the history
Returns True if ANY of the symbol layers contained in the symbol
can cause tile rendering artifacts
  • Loading branch information
nyalldawson committed Feb 12, 2021
1 parent bdf5e4f commit f75c53b
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 2 deletions.
11 changes: 11 additions & 0 deletions python/core/auto_generated/symbology/qgssymbol.sip.in
Expand Up @@ -556,6 +556,17 @@ Sets the symbol's property collection, used for data defined overrides.
Returns whether the symbol utilizes any data defined properties.

.. versionadded:: 2.12
%End

bool canCauseArtifactsBetweenAdjacentTiles() const;
%Docstring
Returns ``True`` if the symbol rendering can cause visible artifacts across a single feature
when the feature is rendered as a series of adjacent map tiles each containing a portion of the feature's geometry.

Internally this calls :py:func:`QgsSymbolLayer.canCauseArtifactsBetweenAdjacentTiles()` for all symbol layers in the symbol
and returns ``True`` if any of the layers returned ``True``.

.. versionadded:: 3.18
%End

void setLayer( const QgsVectorLayer *layer ) /Deprecated/;
Expand Down
13 changes: 11 additions & 2 deletions src/core/symbology/qgssymbol.cpp
Expand Up @@ -813,15 +813,24 @@ bool QgsSymbol::hasDataDefinedProperties() const
if ( mDataDefinedProperties.hasActiveProperties() )
return true;

const auto constMLayers = mLayers;
for ( QgsSymbolLayer *layer : constMLayers )
for ( QgsSymbolLayer *layer : mLayers )
{
if ( layer->hasDataDefinedProperties() )
return true;
}
return false;
}

bool QgsSymbol::canCauseArtifactsBetweenAdjacentTiles() const
{
for ( QgsSymbolLayer *layer : mLayers )
{
if ( layer->canCauseArtifactsBetweenAdjacentTiles() )
return true;
}
return false;
}

void QgsSymbol::setLayer( const QgsVectorLayer *layer )
{
Q_NOWARN_DEPRECATED_PUSH
Expand Down
11 changes: 11 additions & 0 deletions src/core/symbology/qgssymbol.h
Expand Up @@ -588,6 +588,17 @@ class CORE_EXPORT QgsSymbol
*/
bool hasDataDefinedProperties() const;

/**
* Returns TRUE if the symbol rendering can cause visible artifacts across a single feature
* when the feature is rendered as a series of adjacent map tiles each containing a portion of the feature's geometry.
*
* Internally this calls QgsSymbolLayer::canCauseArtifactsBetweenAdjacentTiles() for all symbol layers in the symbol
* and returns TRUE if any of the layers returned TRUE.
*
* \since QGIS 3.18
*/
bool canCauseArtifactsBetweenAdjacentTiles() const;

/**
* \note the layer will be NULLPTR after stopRender
* \deprecated Will be removed in QGIS 4.0
Expand Down
15 changes: 15 additions & 0 deletions tests/src/python/test_qgssymbol.py
Expand Up @@ -54,6 +54,7 @@
QgsReadWriteContext,
QgsSymbolLayerUtils,
QgsMarkerLineSymbolLayer,
QgsArrowSymbolLayer,
QgsSymbol
)

Expand Down Expand Up @@ -148,6 +149,20 @@ def testPythonAdditions(self):
layers = [l.color().name() for l in markerSymbol]
self.assertEqual(layers, ['#ff0000'])

def testCanCauseArtifactsBetweenAdjacentTiles(self):
"""
Test canCauseArtifactsBetweenAdjacentTiles()
"""

# start with a symbol which won't cause artifacts -- a simple line symbol
symbol = QgsLineSymbol.createSimple({})
self.assertFalse(symbol.canCauseArtifactsBetweenAdjacentTiles())
# add a second layer which CAN cause artifacts
symbol.appendSymbolLayer(QgsArrowSymbolLayer())
self.assertTrue(symbol.canCauseArtifactsBetweenAdjacentTiles())
symbol.deleteSymbolLayer(0)
self.assertTrue(symbol.canCauseArtifactsBetweenAdjacentTiles())

def testGeometryRendering(self):
'''Tests rendering a bunch of different geometries, including bad/odd geometries.'''

Expand Down

0 comments on commit f75c53b

Please sign in to comment.