mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
[api] Allow reference scale for vector layer renderer to be set
Gives a means of setting the reference scale for a vector layer renderer, so that symbol sizes in the rendered layer will be scaled accordingly depending on the actual scale of the rendered map.
This commit is contained in:
parent
c8da0c43f9
commit
849819cd0d
@ -337,7 +337,7 @@ for the rendered map, eg 1000.0 for a 1:1000 map render.
|
||||
|
||||
double symbologyReferenceScale() const;
|
||||
%Docstring
|
||||
Returns the symbology reference ``scale``.
|
||||
Returns the symbology reference scale.
|
||||
|
||||
This represents the desired scale denominator for the rendered map, eg 1000.0 for a 1:1000 map render.
|
||||
A value of -1 indicates that symbology scaling by reference scale is disabled.
|
||||
|
@ -421,6 +421,40 @@ Sets whether the renderer should be rendered to a raster destination.
|
||||
.. seealso:: :py:func:`forceRasterRender`
|
||||
|
||||
.. versionadded:: 2.12
|
||||
%End
|
||||
|
||||
double referenceScale() const;
|
||||
%Docstring
|
||||
Returns the symbology reference scale.
|
||||
|
||||
This represents the desired scale denominator for the rendered map, eg 1000.0 for a 1:1000 map render.
|
||||
A value of -1 indicates that symbology scaling by reference scale is disabled.
|
||||
|
||||
The symbology reference scale is an optional property which specifies the reference
|
||||
scale at which symbology in paper units (such a millimeters or points) is fixed
|
||||
to. For instance, if the scale is 1000 then a 2mm thick line will be rendered at
|
||||
exactly 2mm thick when a map is rendered at 1:1000, or 1mm thick when rendered at 1:2000, or 4mm thick at 1:500.
|
||||
|
||||
.. seealso:: :py:func:`setReferenceScale`
|
||||
|
||||
.. versionadded:: 3.22
|
||||
%End
|
||||
|
||||
void setReferenceScale( double scale );
|
||||
%Docstring
|
||||
Sets the symbology reference ``scale``.
|
||||
|
||||
This should match the desired scale denominator for the rendered map, eg 1000.0 for a 1:1000 map render.
|
||||
Set to -1 to disable symbology scaling by reference scale.
|
||||
|
||||
The symbology reference scale is an optional property which specifies the reference
|
||||
scale at which symbology in paper units (such a millimeters or points) is fixed
|
||||
to. For instance, if ``scale`` is set to 1000 then a 2mm thick line will be rendered at
|
||||
exactly 2mm thick when a map is rendered at 1:1000, or 1mm thick when rendered at 1:2000, or 4mm thick at 1:500.
|
||||
|
||||
.. seealso:: :py:func:`referenceScale`
|
||||
|
||||
.. versionadded:: 3.22
|
||||
%End
|
||||
|
||||
QgsFeatureRequest::OrderBy orderBy() const;
|
||||
@ -562,6 +596,7 @@ to store all common base class properties in the DOM ``element``.
|
||||
|
||||
|
||||
|
||||
|
||||
static void convertSymbolSizeScale( QgsSymbol *symbol, Qgis::ScaleMethod method, const QString &field );
|
||||
%Docstring
|
||||
|
||||
|
@ -386,7 +386,7 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
|
||||
|
||||
|
||||
/**
|
||||
* Returns the symbology reference \a scale.
|
||||
* Returns the symbology reference scale.
|
||||
*
|
||||
* This represents the desired scale denominator for the rendered map, eg 1000.0 for a 1:1000 map render.
|
||||
* A value of -1 indicates that symbology scaling by reference scale is disabled.
|
||||
|
@ -59,6 +59,7 @@ void QgsFeatureRenderer::copyRendererData( QgsFeatureRenderer *destRenderer ) co
|
||||
destRenderer->setUsingSymbolLevels( mUsingSymbolLevels );
|
||||
destRenderer->mOrderBy = mOrderBy;
|
||||
destRenderer->mOrderByEnabled = mOrderByEnabled;
|
||||
destRenderer->mReferenceScale = mReferenceScale;
|
||||
}
|
||||
|
||||
QgsFeatureRenderer::QgsFeatureRenderer( const QString &type )
|
||||
@ -171,6 +172,7 @@ QgsFeatureRenderer *QgsFeatureRenderer::load( QDomElement &element, const QgsRea
|
||||
{
|
||||
r->setUsingSymbolLevels( element.attribute( QStringLiteral( "symbollevels" ), QStringLiteral( "0" ) ).toInt() );
|
||||
r->setForceRasterRender( element.attribute( QStringLiteral( "forceraster" ), QStringLiteral( "0" ) ).toInt() );
|
||||
r->setReferenceScale( element.attribute( QStringLiteral( "referencescale" ), QStringLiteral( "-1" ) ).toDouble() );
|
||||
|
||||
//restore layer effect
|
||||
QDomElement effectElem = element.firstChildElement( QStringLiteral( "effect" ) );
|
||||
@ -202,6 +204,7 @@ void QgsFeatureRenderer::saveRendererData( QDomDocument &doc, QDomElement &rende
|
||||
{
|
||||
rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
|
||||
rendererElem.setAttribute( QStringLiteral( "symbollevels" ), ( mUsingSymbolLevels ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
|
||||
rendererElem.setAttribute( QStringLiteral( "referencescale" ), mReferenceScale );
|
||||
|
||||
if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect ) )
|
||||
mPaintEffect->saveProperties( doc, rendererElem );
|
||||
|
@ -434,6 +434,38 @@ class CORE_EXPORT QgsFeatureRenderer
|
||||
*/
|
||||
void setForceRasterRender( bool forceRaster ) { mForceRaster = forceRaster; }
|
||||
|
||||
/**
|
||||
* Returns the symbology reference scale.
|
||||
*
|
||||
* This represents the desired scale denominator for the rendered map, eg 1000.0 for a 1:1000 map render.
|
||||
* A value of -1 indicates that symbology scaling by reference scale is disabled.
|
||||
*
|
||||
* The symbology reference scale is an optional property which specifies the reference
|
||||
* scale at which symbology in paper units (such a millimeters or points) is fixed
|
||||
* to. For instance, if the scale is 1000 then a 2mm thick line will be rendered at
|
||||
* exactly 2mm thick when a map is rendered at 1:1000, or 1mm thick when rendered at 1:2000, or 4mm thick at 1:500.
|
||||
*
|
||||
* \see setReferenceScale()
|
||||
* \since QGIS 3.22
|
||||
*/
|
||||
double referenceScale() const { return mReferenceScale; }
|
||||
|
||||
/**
|
||||
* Sets the symbology reference \a scale.
|
||||
*
|
||||
* This should match the desired scale denominator for the rendered map, eg 1000.0 for a 1:1000 map render.
|
||||
* Set to -1 to disable symbology scaling by reference scale.
|
||||
*
|
||||
* The symbology reference scale is an optional property which specifies the reference
|
||||
* scale at which symbology in paper units (such a millimeters or points) is fixed
|
||||
* to. For instance, if \a scale is set to 1000 then a 2mm thick line will be rendered at
|
||||
* exactly 2mm thick when a map is rendered at 1:1000, or 1mm thick when rendered at 1:2000, or 4mm thick at 1:500.
|
||||
*
|
||||
* \see referenceScale()
|
||||
* \since QGIS 3.22
|
||||
*/
|
||||
void setReferenceScale( double scale ) { mReferenceScale = scale; }
|
||||
|
||||
/**
|
||||
* Gets the order in which features shall be processed by this renderer.
|
||||
* \note this property has no effect if orderByEnabled() is FALSE
|
||||
@ -553,6 +585,8 @@ class CORE_EXPORT QgsFeatureRenderer
|
||||
|
||||
bool mForceRaster = false;
|
||||
|
||||
double mReferenceScale = -1.0;
|
||||
|
||||
/**
|
||||
* \note this function is used to convert old sizeScale expressions to symbol
|
||||
* level DataDefined size
|
||||
|
@ -245,6 +245,7 @@ bool QgsVectorLayerRenderer::renderInternal( QgsFeatureRenderer *renderer )
|
||||
}
|
||||
|
||||
QgsRenderContext &context = *renderContext();
|
||||
context.setSymbologyReferenceScale( renderer->referenceScale() );
|
||||
|
||||
QgsScopedQPainterState painterState( context.painter() );
|
||||
|
||||
|
@ -30,7 +30,8 @@ from qgis.core import (QgsVectorLayer,
|
||||
QgsCategorizedSymbolRenderer,
|
||||
QgsRendererCategory,
|
||||
QgsCentroidFillSymbolLayer,
|
||||
QgsMarkerSymbol
|
||||
QgsMarkerSymbol,
|
||||
QgsLineSymbol
|
||||
)
|
||||
from qgis.testing import start_app, unittest
|
||||
from utilities import (unitTestDataPath)
|
||||
@ -666,6 +667,57 @@ class TestQgsVectorLayerRenderer(unittest.TestCase):
|
||||
self.report += renderchecker.report()
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_reference_scale(self):
|
||||
"""
|
||||
Test rendering a layer with a reference scale set
|
||||
"""
|
||||
layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'lines.shp'), 'Lines', 'ogr')
|
||||
self.assertTrue(layer.isValid())
|
||||
|
||||
sym1 = QgsLineSymbol.createSimple({'line_color': '#4dbf6f', 'line_width': 4, 'line_width_unit': "points"})
|
||||
|
||||
renderer = QgsSingleSymbolRenderer(sym1)
|
||||
layer.setRenderer(renderer)
|
||||
|
||||
mapsettings = QgsMapSettings()
|
||||
mapsettings.setDestinationCrs(layer.crs())
|
||||
mapsettings.setOutputSize(QSize(400, 400))
|
||||
mapsettings.setOutputDpi(96)
|
||||
mapsettings.setExtent(layer.extent())
|
||||
mapsettings.setLayers([layer])
|
||||
self.assertAlmostEqual(mapsettings.scale(), 22738556, -5)
|
||||
|
||||
# Setup rendering check
|
||||
renderchecker = QgsMultiRenderChecker()
|
||||
renderchecker.setMapSettings(mapsettings)
|
||||
renderchecker.setControlPathPrefix('vectorlayerrenderer')
|
||||
renderchecker.setControlName('expected_reference_scale_not_set')
|
||||
result = renderchecker.runTest('expected_reference_scale_not_set')
|
||||
self.report += renderchecker.report()
|
||||
self.assertTrue(result)
|
||||
|
||||
# Set the reference scale as half the map scale -- the lines should be double as wide
|
||||
# as their preset width
|
||||
renderer.setReferenceScale(22738556 * 2)
|
||||
renderchecker = QgsMultiRenderChecker()
|
||||
renderchecker.setMapSettings(mapsettings)
|
||||
renderchecker.setControlPathPrefix('vectorlayerrenderer')
|
||||
renderchecker.setControlName('expected_reference_scale_double')
|
||||
result = renderchecker.runTest('expected_reference_scale_double')
|
||||
self.report += renderchecker.report()
|
||||
self.assertTrue(result)
|
||||
|
||||
# Set the reference scale as double the map scale -- the lines should be half as wide
|
||||
# as their preset width
|
||||
renderer.setReferenceScale(22738556 / 2)
|
||||
renderchecker = QgsMultiRenderChecker()
|
||||
renderchecker.setMapSettings(mapsettings)
|
||||
renderchecker.setControlPathPrefix('vectorlayerrenderer')
|
||||
renderchecker.setControlName('expected_reference_scale_half')
|
||||
result = renderchecker.runTest('expected_reference_scale_half')
|
||||
self.report += renderchecker.report()
|
||||
self.assertTrue(result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 460 KiB |
Binary file not shown.
After Width: | Height: | Size: 460 KiB |
Binary file not shown.
After Width: | Height: | Size: 460 KiB |
Loading…
x
Reference in New Issue
Block a user