Skip to content

Commit 3253cdc

Browse files
committed
Unit tests for displacement and cluster renderer
1 parent d27e556 commit 3253cdc

File tree

7 files changed

+359
-0
lines changed

7 files changed

+359
-0
lines changed

tests/src/python/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ ADD_PYTHON_TEST(PyQgsPalLabelingComposer test_qgspallabeling_composer.py)
6969
ADD_PYTHON_TEST(PyQgsPalLabelingPlacement test_qgspallabeling_placement.py)
7070
ADD_PYTHON_TEST(PyQgsPanelWidget test_qgspanelwidget.py)
7171
ADD_PYTHON_TEST(PyQgsPoint test_qgspoint.py)
72+
ADD_PYTHON_TEST(PyQgsPointClusterRenderer test_qgspointclusterrenderer.py)
73+
ADD_PYTHON_TEST(PyQgsPointDisplacementRenderer test_qgspointdisplacementrenderer.py)
7274
ADD_PYTHON_TEST(PyQgsRangeWidgets test_qgsrangewidgets.py)
7375
ADD_PYTHON_TEST(PyQgsRasterFileWriter test_qgsrasterfilewriter.py)
7476
ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
***************************************************************************
5+
test_qgspointclusterrenderer.py
6+
-----------------------------
7+
Date : September 2016
8+
Copyright : (C) 2016 by Nyall Dawson
9+
Email : nyall dot dawson at gmail dot com
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************
18+
"""
19+
20+
__author__ = 'Nyall Dawson'
21+
__date__ = 'September 2016'
22+
__copyright__ = '(C) 2016, Nyall Dawson'
23+
# This will get replaced with a git SHA1 when you do a git archive
24+
__revision__ = '$Format:%H$'
25+
26+
import os
27+
28+
from qgis.PyQt.QtCore import QSize
29+
from qgis.PyQt.QtGui import QColor
30+
from qgis.PyQt.QtXml import (QDomDocument, QDomElement)
31+
32+
from qgis.core import (QgsVectorLayer,
33+
QgsMapLayerRegistry,
34+
QgsRectangle,
35+
QgsMultiRenderChecker,
36+
QgsPointClusterRenderer,
37+
QgsFontUtils,
38+
QgsUnitTypes,
39+
QgsMapUnitScale,
40+
QgsMarkerSymbol,
41+
QgsSingleSymbolRenderer,
42+
QgsPointDisplacementRenderer,
43+
QgsMapSettings
44+
)
45+
from qgis.testing import start_app, unittest
46+
from utilities import (unitTestDataPath)
47+
48+
# Convenience instances in case you may need them
49+
# not used in this test
50+
start_app()
51+
TEST_DATA_DIR = unitTestDataPath()
52+
53+
54+
class TestQgsPointClusterRenderer(unittest.TestCase):
55+
56+
def setUp(self):
57+
myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
58+
self.layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
59+
QgsMapLayerRegistry.instance().addMapLayer(self.layer)
60+
61+
self.renderer = QgsPointClusterRenderer()
62+
sym1 = QgsMarkerSymbol.createSimple({'color': '#ff00ff', 'size': '3', 'outline_style': 'no'})
63+
renderer = QgsSingleSymbolRenderer(sym1)
64+
self.renderer.setEmbeddedRenderer(renderer)
65+
self.renderer.setClusterSymbol(QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'}))
66+
self.layer.setRenderer(self.renderer)
67+
68+
rendered_layers = [self.layer.id()]
69+
self.mapsettings = QgsMapSettings()
70+
self.mapsettings.setOutputSize(QSize(400, 400))
71+
self.mapsettings.setOutputDpi(96)
72+
self.mapsettings.setExtent(QgsRectangle(-123, 18, -70, 52))
73+
self.mapsettings.setLayers(rendered_layers)
74+
75+
def tearDown(self):
76+
QgsMapLayerRegistry.instance().removeAllMapLayers()
77+
78+
def _setProperties(self, r):
79+
""" set properties for a renderer for testing with _checkProperties"""
80+
r.setTolerance(5)
81+
r.setToleranceUnit(QgsUnitTypes.RenderMapUnits)
82+
r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15))
83+
m = QgsMarkerSymbol()
84+
m.setColor(QColor(0, 255, 0))
85+
r.setClusterSymbol(m)
86+
sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'})
87+
renderer = QgsSingleSymbolRenderer(sym1)
88+
r.setEmbeddedRenderer(renderer)
89+
90+
def _checkProperties(self, r):
91+
""" test properties of renderer against expected"""
92+
self.assertEqual(r.tolerance(), 5)
93+
self.assertEqual(r.toleranceUnit(), QgsUnitTypes.RenderMapUnits)
94+
self.assertEqual(r.toleranceMapUnitScale(), QgsMapUnitScale(5, 15))
95+
self.assertEqual(r.clusterSymbol().color(), QColor(0, 255, 0))
96+
self.assertEqual(r.embeddedRenderer().symbol().color().name(), '#fdbf6f')
97+
98+
def testGettersSetters(self):
99+
""" test getters and setters """
100+
r = QgsPointClusterRenderer()
101+
self._setProperties(r)
102+
self._checkProperties(r)
103+
104+
def testClone(self):
105+
""" test cloning renderer """
106+
r = QgsPointClusterRenderer()
107+
self._setProperties(r)
108+
c = r.clone()
109+
self._checkProperties(c)
110+
111+
def testSaveCreate(self):
112+
""" test saving and recreating from XML """
113+
r = QgsPointClusterRenderer()
114+
self._setProperties(r)
115+
doc = QDomDocument("testdoc")
116+
elem = r.save(doc)
117+
c = QgsPointClusterRenderer.create(elem)
118+
self._checkProperties(c)
119+
120+
def testConvert(self):
121+
""" test renderer conversion """
122+
123+
# same type, should clone
124+
r = QgsPointClusterRenderer()
125+
self._setProperties(r)
126+
c = QgsPointClusterRenderer.convertFromRenderer(r)
127+
self._checkProperties(c)
128+
129+
# test conversion from displacement renderer
130+
r = QgsPointDisplacementRenderer()
131+
r.setTolerance(5)
132+
r.setToleranceUnit(QgsUnitTypes.RenderMapUnits)
133+
r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15))
134+
m = QgsMarkerSymbol()
135+
m.setColor(QColor(0, 255, 0))
136+
r.setCenterSymbol(m)
137+
sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'})
138+
renderer = QgsSingleSymbolRenderer(sym1)
139+
r.setEmbeddedRenderer(renderer)
140+
141+
# want to keep as many settings as possible when converting between cluster and displacement renderer
142+
d = QgsPointClusterRenderer.convertFromRenderer(r)
143+
self.assertEqual(d.tolerance(), 5)
144+
self.assertEqual(d.toleranceUnit(), QgsUnitTypes.RenderMapUnits)
145+
self.assertEqual(d.toleranceMapUnitScale(), QgsMapUnitScale(5, 15))
146+
self.assertEqual(d.clusterSymbol().color(), QColor(0, 255, 0))
147+
self.assertEqual(d.embeddedRenderer().symbol().color().name(), '#fdbf6f')
148+
149+
def testRenderNoCluster(self):
150+
self.layer.renderer().setTolerance(1)
151+
renderchecker = QgsMultiRenderChecker()
152+
renderchecker.setMapSettings(self.mapsettings)
153+
renderchecker.setControlPathPrefix('cluster_renderer')
154+
renderchecker.setControlName('expected_cluster_no_cluster')
155+
self.assertTrue(renderchecker.runTest('cluster_no_cluster'))
156+
157+
def testRenderWithin(self):
158+
self.layer.renderer().setTolerance(10)
159+
renderchecker = QgsMultiRenderChecker()
160+
renderchecker.setMapSettings(self.mapsettings)
161+
renderchecker.setControlPathPrefix('cluster_renderer')
162+
renderchecker.setControlName('expected_cluster_cluster')
163+
self.assertTrue(renderchecker.runTest('expected_cluster_cluster'))
164+
165+
166+
if __name__ == '__main__':
167+
unittest.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
***************************************************************************
5+
test_qgspointdisplacementrenderer.py
6+
-----------------------------
7+
Date : September 2016
8+
Copyright : (C) 2016 by Nyall Dawson
9+
Email : nyall dot dawson at gmail dot com
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************
18+
"""
19+
20+
__author__ = 'Nyall Dawson'
21+
__date__ = 'September 2016'
22+
__copyright__ = '(C) 2016, Nyall Dawson'
23+
# This will get replaced with a git SHA1 when you do a git archive
24+
__revision__ = '$Format:%H$'
25+
26+
import qgis # NOQA
27+
28+
import os
29+
30+
from qgis.PyQt.QtGui import QColor
31+
from qgis.PyQt.QtCore import QSize
32+
from qgis.PyQt.QtXml import (QDomDocument, QDomElement)
33+
34+
from qgis.core import (QgsVectorLayer,
35+
QgsMapLayerRegistry,
36+
QgsRectangle,
37+
QgsMultiRenderChecker,
38+
QgsPointDisplacementRenderer,
39+
QgsFontUtils,
40+
QgsUnitTypes,
41+
QgsMapUnitScale,
42+
QgsMarkerSymbol,
43+
QgsSingleSymbolRenderer,
44+
QgsPointClusterRenderer,
45+
QgsMapSettings
46+
)
47+
from qgis.testing import start_app, unittest
48+
from utilities import (unitTestDataPath)
49+
50+
# Convenience instances in case you may need them
51+
# not used in this test
52+
start_app()
53+
TEST_DATA_DIR = unitTestDataPath()
54+
55+
56+
class TestQgsPointDisplacementRenderer(unittest.TestCase):
57+
58+
def setUp(self):
59+
myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
60+
self.layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
61+
QgsMapLayerRegistry.instance().addMapLayer(self.layer)
62+
63+
self.renderer = QgsPointDisplacementRenderer()
64+
sym1 = QgsMarkerSymbol.createSimple({'color': '#ff00ff', 'size': '3', 'outline_style': 'no'})
65+
renderer = QgsSingleSymbolRenderer(sym1)
66+
self.renderer.setEmbeddedRenderer(renderer)
67+
self.renderer.setCircleRadiusAddition(2)
68+
self.renderer.setCircleWidth(1)
69+
self.renderer.setCircleColor(QColor(0, 0, 0))
70+
self.renderer.setCenterSymbol(QgsMarkerSymbol.createSimple({'color': '#ffff00', 'size': '3', 'outline_style': 'no'}))
71+
self.layer.setRenderer(self.renderer)
72+
73+
rendered_layers = [self.layer.id()]
74+
self.mapsettings = QgsMapSettings()
75+
self.mapsettings.setOutputSize(QSize(400, 400))
76+
self.mapsettings.setOutputDpi(96)
77+
self.mapsettings.setExtent(QgsRectangle(-123, 18, -70, 52))
78+
self.mapsettings.setLayers(rendered_layers)
79+
80+
def tearDown(self):
81+
QgsMapLayerRegistry.instance().removeAllMapLayers()
82+
83+
def _setProperties(self, r):
84+
""" set properties for a renderer for testing with _checkProperties"""
85+
r.setLabelAttributeName('name')
86+
f = QgsFontUtils.getStandardTestFont('Bold Oblique', 14)
87+
r.setLabelFont(f)
88+
r.setMaxLabelScaleDenominator(50000)
89+
r.setLabelColor(QColor(255, 0, 0))
90+
r.setTolerance(5)
91+
r.setToleranceUnit(QgsUnitTypes.RenderMapUnits)
92+
r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15))
93+
r.setCircleWidth(15)
94+
r.setCircleColor(QColor(0, 255, 0))
95+
r.setCircleRadiusAddition(2.5)
96+
r.setPlacement(QgsPointDisplacementRenderer.ConcentricRings)
97+
m = QgsMarkerSymbol()
98+
m.setColor(QColor(0, 255, 0))
99+
r.setCenterSymbol(m)
100+
sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'})
101+
renderer = QgsSingleSymbolRenderer(sym1)
102+
r.setEmbeddedRenderer(renderer)
103+
104+
def _checkProperties(self, r):
105+
""" test properties of renderer against expected"""
106+
self.assertEqual(r.labelAttributeName(), 'name')
107+
f = QgsFontUtils.getStandardTestFont('Bold Oblique', 14)
108+
self.assertEqual(r.labelFont().styleName(), f.styleName())
109+
self.assertEqual(r.maxLabelScaleDenominator(), 50000)
110+
self.assertEqual(r.labelColor(), QColor(255, 0, 0))
111+
self.assertEqual(r.tolerance(), 5)
112+
self.assertEqual(r.toleranceUnit(), QgsUnitTypes.RenderMapUnits)
113+
self.assertEqual(r.toleranceMapUnitScale(), QgsMapUnitScale(5, 15))
114+
self.assertEqual(r.circleWidth(), 15)
115+
self.assertEqual(r.circleColor(), QColor(0, 255, 0))
116+
self.assertEqual(r.circleRadiusAddition(), 2.5)
117+
self.assertEqual(r.placement(), QgsPointDisplacementRenderer.ConcentricRings)
118+
self.assertEqual(r.centerSymbol().color(), QColor(0, 255, 0))
119+
self.assertEqual(r.embeddedRenderer().symbol().color().name(), '#fdbf6f')
120+
121+
def testGettersSetters(self):
122+
""" test getters and setters """
123+
r = QgsPointDisplacementRenderer()
124+
self._setProperties(r)
125+
self._checkProperties(r)
126+
127+
def testClone(self):
128+
""" test cloning renderer """
129+
r = QgsPointDisplacementRenderer()
130+
self._setProperties(r)
131+
c = r.clone()
132+
self._checkProperties(c)
133+
134+
def testSaveCreate(self):
135+
""" test saving and recreating from XML """
136+
r = QgsPointDisplacementRenderer()
137+
self._setProperties(r)
138+
doc = QDomDocument("testdoc")
139+
elem = r.save(doc)
140+
c = QgsPointDisplacementRenderer.create(elem)
141+
self._checkProperties(c)
142+
143+
def testConvert(self):
144+
""" test renderer conversion """
145+
146+
# same type, should clone
147+
r = QgsPointDisplacementRenderer()
148+
self._setProperties(r)
149+
c = QgsPointDisplacementRenderer.convertFromRenderer(r)
150+
self._checkProperties(c)
151+
152+
# test conversion from cluster renderer
153+
r = QgsPointClusterRenderer()
154+
r.setTolerance(5)
155+
r.setToleranceUnit(QgsUnitTypes.RenderMapUnits)
156+
r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15))
157+
m = QgsMarkerSymbol()
158+
m.setColor(QColor(0, 255, 0))
159+
r.setClusterSymbol(m)
160+
sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'})
161+
renderer = QgsSingleSymbolRenderer(sym1)
162+
r.setEmbeddedRenderer(renderer)
163+
164+
# want to keep as many settings as possible when converting between cluster and displacement renderer
165+
d = QgsPointDisplacementRenderer.convertFromRenderer(r)
166+
self.assertEqual(d.tolerance(), 5)
167+
self.assertEqual(d.toleranceUnit(), QgsUnitTypes.RenderMapUnits)
168+
self.assertEqual(d.toleranceMapUnitScale(), QgsMapUnitScale(5, 15))
169+
self.assertEqual(d.centerSymbol().color(), QColor(0, 255, 0))
170+
self.assertEqual(d.embeddedRenderer().symbol().color().name(), '#fdbf6f')
171+
172+
def testRenderNoCluster(self):
173+
self.layer.renderer().setTolerance(1)
174+
renderchecker = QgsMultiRenderChecker()
175+
renderchecker.setMapSettings(self.mapsettings)
176+
renderchecker.setControlPathPrefix('displacement_renderer')
177+
renderchecker.setControlName('expected_displacement_no_cluster')
178+
self.assertTrue(renderchecker.runTest('displacement_no_cluster'))
179+
180+
def testRenderWithin(self):
181+
self.layer.renderer().setTolerance(10)
182+
renderchecker = QgsMultiRenderChecker()
183+
renderchecker.setMapSettings(self.mapsettings)
184+
renderchecker.setControlPathPrefix('displacement_renderer')
185+
renderchecker.setControlName('expected_displacement_cluster')
186+
self.assertTrue(renderchecker.runTest('expected_displacement_cluster'))
187+
188+
189+
if __name__ == '__main__':
190+
unittest.main()

0 commit comments

Comments
 (0)