Skip to content

Commit 50dd2d6

Browse files
committed
Unit tests for hashed line symbols
1 parent 714a4ac commit 50dd2d6

File tree

14 files changed

+170
-61
lines changed

14 files changed

+170
-61
lines changed

tests/src/python/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ ADD_PYTHON_TEST(PyQgsGeometryGeneratorSymbolLayer test_qgsgeometrygeneratorsymbo
7575
ADD_PYTHON_TEST(PyQgsGeometryTest test_qgsgeometry.py)
7676
ADD_PYTHON_TEST(PyQgsGeometryValidator test_qgsgeometryvalidator.py)
7777
ADD_PYTHON_TEST(PyQgsGraduatedSymbolRenderer test_qgsgraduatedsymbolrenderer.py)
78+
ADD_PYTHON_TEST(PyQgsHashLineSymbolLayer test_qgshashlinesymbollayer.py)
7879
ADD_PYTHON_TEST(PyQgsHighlight test_qgshighlight.py)
7980
ADD_PYTHON_TEST(PyQgsImageCache test_qgsimagecache.py)
8081
ADD_PYTHON_TEST(PyQgsImageSourceLineEdit test_qgsimagesourcelineedit.py)

tests/src/python/test_qgshashlinesymbollayer.py

+143-61
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
"""
44
***************************************************************************
5-
test_qgsmarkerlinesymbollayer.py
5+
test_qgshashlinesymbollayer.py
66
---------------------
7-
Date : November 2018
8-
Copyright : (C) 2018 by Nyall Dawson
7+
Date : March 2019
8+
Copyright : (C) 2019 by Nyall Dawson
99
Email : nyall dot dawson at gmail dot com
1010
***************************************************************************
1111
* *
@@ -18,8 +18,8 @@
1818
"""
1919

2020
__author__ = 'Nyall Dawson'
21-
__date__ = 'November 2018'
22-
__copyright__ = '(C) 2018, Nyall Dawson'
21+
__date__ = 'March 2019'
22+
__copyright__ = '(C) 2019, Nyall Dawson'
2323
# This will get replaced with a git SHA1 when you do a git archive
2424
__revision__ = '$Format:%H$'
2525

@@ -51,7 +51,10 @@
5151
QgsSymbolLayer,
5252
QgsProperty,
5353
QgsRectangle,
54-
QgsUnitTypes
54+
QgsUnitTypes,
55+
QgsSimpleLineSymbolLayer,
56+
QgsTemplatedLineSymbolLayerBase,
57+
QgsHashedLineSymbolLayer
5558
)
5659

5760
from qgis.testing import unittest, start_app
@@ -60,10 +63,10 @@
6063
TEST_DATA_DIR = unitTestDataPath()
6164

6265

63-
class TestQgsMarkerLineSymbolLayer(unittest.TestCase):
66+
class TestQgsHashedLineSymbolLayer(unittest.TestCase):
6467

6568
def setUp(self):
66-
self.report = "<h1>Python QgsMarkerLineSymbolLayer Tests</h1>\n"
69+
self.report = "<h1>Python QgsHashedLineSymbolLayer Tests</h1>\n"
6770

6871
def tearDown(self):
6972
report_file_path = "%s/qgistest.html" % QDir.tempPath()
@@ -85,38 +88,100 @@ def testWidth(self):
8588
s = QgsFillSymbol()
8689
s.deleteSymbolLayer(0)
8790

88-
marker_line = QgsMarkerLineSymbolLayer(True)
89-
marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex)
90-
marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 10)
91-
marker.setColor(QColor(255, 0, 0))
92-
marker.setStrokeStyle(Qt.NoPen)
93-
marker_symbol = QgsMarkerSymbol()
94-
marker_symbol.changeSymbolLayer(0, marker)
95-
marker_line.setSubSymbol(marker_symbol)
91+
hash_line = QgsHashedLineSymbolLayer(True)
92+
hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.FirstVertex)
93+
simple_line = QgsSimpleLineSymbolLayer()
94+
line_symbol = QgsLineSymbol()
95+
line_symbol.changeSymbolLayer(0, simple_line)
96+
hash_line.setSubSymbol(line_symbol)
97+
hash_line.setHashLength(10)
98+
99+
self.assertEqual(hash_line.width(), 10)
100+
self.assertAlmostEqual(hash_line.width(context), 37.795275590551185, 3)
101+
self.assertAlmostEqual(hash_line.width(context2), 118.11023622047244, 3)
102+
103+
hash_line.setHashLengthUnit(QgsUnitTypes.RenderPixels)
104+
self.assertAlmostEqual(hash_line.width(context), 10.0, 3)
105+
self.assertAlmostEqual(hash_line.width(context2), 10.0, 3)
106+
107+
def testHashAngle(self):
108+
s = QgsLineSymbol()
109+
s.deleteSymbolLayer(0)
110+
111+
hash_line = QgsHashedLineSymbolLayer(True)
112+
hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.Interval)
113+
hash_line.setInterval(6)
114+
simple_line = QgsSimpleLineSymbolLayer()
115+
simple_line.setColor(QColor(0, 255, 0))
116+
simple_line.setWidth(1)
117+
line_symbol = QgsLineSymbol()
118+
line_symbol.changeSymbolLayer(0, simple_line)
119+
hash_line.setSubSymbol(line_symbol)
120+
hash_line.setHashLength(7)
121+
hash_line.setHashAngle(45)
122+
123+
s.appendSymbolLayer(hash_line.clone())
124+
125+
g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)')
126+
rendered_image = self.renderGeometry(s, g)
127+
assert self.imageCheck('line_hash_angle', 'line_hash_angle', rendered_image)
128+
129+
s.symbolLayer(0).setRotateSymbols(False)
130+
131+
g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)')
132+
rendered_image = self.renderGeometry(s, g)
133+
assert self.imageCheck('line_hash_no_rotate', 'line_hash_no_rotate', rendered_image)
134+
135+
def testHashPlacement(self):
136+
s = QgsLineSymbol()
137+
s.deleteSymbolLayer(0)
138+
139+
hash_line = QgsHashedLineSymbolLayer(True)
140+
hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.Vertex)
141+
hash_line.setInterval(6)
142+
simple_line = QgsSimpleLineSymbolLayer()
143+
simple_line.setColor(QColor(0, 255, 0))
144+
simple_line.setWidth(1)
145+
line_symbol = QgsLineSymbol()
146+
line_symbol.changeSymbolLayer(0, simple_line)
147+
hash_line.setSubSymbol(line_symbol)
148+
hash_line.setHashLength(7)
149+
150+
s.appendSymbolLayer(hash_line.clone())
151+
152+
g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)')
153+
rendered_image = self.renderGeometry(s, g)
154+
assert self.imageCheck('line_hash_vertex', 'line_hash_vertex', rendered_image)
155+
156+
s.symbolLayer(0).setPlacement(QgsTemplatedLineSymbolLayerBase.FirstVertex)
96157

97-
self.assertEqual(marker_line.width(), 10)
98-
self.assertAlmostEqual(marker_line.width(context), 37.795275590551185, 3)
99-
self.assertAlmostEqual(marker_line.width(context2), 118.11023622047244, 3)
158+
g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)')
159+
rendered_image = self.renderGeometry(s, g)
160+
assert self.imageCheck('line_hash_first', 'line_hash_first', rendered_image)
100161

101-
marker_line.subSymbol().setSizeUnit(QgsUnitTypes.RenderPixels)
102-
self.assertAlmostEqual(marker_line.width(context), 10.0, 3)
103-
self.assertAlmostEqual(marker_line.width(context2), 10.0, 3)
162+
s.symbolLayer(0).setPlacement(QgsTemplatedLineSymbolLayerBase.LastVertex)
163+
164+
g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)')
165+
rendered_image = self.renderGeometry(s, g)
166+
assert self.imageCheck('line_hash_last', 'line_hash_last', rendered_image)
104167

105168
def testRingFilter(self):
106169
# test filtering rings during rendering
107170
s = QgsFillSymbol()
108171
s.deleteSymbolLayer(0)
109172

110-
marker_line = QgsMarkerLineSymbolLayer(True)
111-
marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex)
112-
marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 4)
113-
marker.setColor(QColor(255, 0, 0))
114-
marker.setStrokeStyle(Qt.NoPen)
115-
marker_symbol = QgsMarkerSymbol()
116-
marker_symbol.changeSymbolLayer(0, marker)
117-
marker_line.setSubSymbol(marker_symbol)
173+
hash_line = QgsHashedLineSymbolLayer(True)
174+
hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.Interval)
175+
hash_line.setInterval(6)
176+
simple_line = QgsSimpleLineSymbolLayer()
177+
simple_line.setColor(QColor(0, 255, 0))
178+
simple_line.setWidth(1)
179+
line_symbol = QgsLineSymbol()
180+
line_symbol.changeSymbolLayer(0, simple_line)
181+
hash_line.setSubSymbol(line_symbol)
182+
hash_line.setHashLength(10)
118183

119-
s.appendSymbolLayer(marker_line.clone())
184+
s.appendSymbolLayer(hash_line.clone())
120185
self.assertEqual(s.symbolLayer(0).ringFilter(), QgsLineSymbolLayer.AllRings)
121186
s.symbolLayer(0).setRingFilter(QgsLineSymbolLayer.ExteriorRingOnly)
122187
self.assertEqual(s.symbolLayer(0).ringFilter(), QgsLineSymbolLayer.ExteriorRingOnly)
@@ -135,51 +200,68 @@ def testRingFilter(self):
135200
s3 = QgsFillSymbol()
136201
s3.deleteSymbolLayer(0)
137202
s3.appendSymbolLayer(
138-
QgsMarkerLineSymbolLayer())
203+
hash_line.clone())
139204
s3.symbolLayer(0).setRingFilter(QgsLineSymbolLayer.ExteriorRingOnly)
140205

141206
g = QgsGeometry.fromWkt('Polygon((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1),(8 8, 9 8, 9 9, 8 9, 8 8))')
142207
rendered_image = self.renderGeometry(s3, g)
143-
assert self.imageCheck('markerline_exterioronly', 'markerline_exterioronly', rendered_image)
208+
assert self.imageCheck('hashline_exterioronly', 'hashline_exterioronly', rendered_image)
144209

145210
s3.symbolLayer(0).setRingFilter(QgsLineSymbolLayer.InteriorRingsOnly)
146211
g = QgsGeometry.fromWkt('Polygon((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1),(8 8, 9 8, 9 9, 8 9, 8 8))')
147212
rendered_image = self.renderGeometry(s3, g)
148-
assert self.imageCheck('markerline_interioronly', 'markerline_interioronly', rendered_image)
213+
assert self.imageCheck('hashline_interioronly', 'hashline_interioronly', rendered_image)
149214

150-
def testPartNum(self):
151-
# test geometry_part_num variable
215+
def testLineOffset(self):
152216
s = QgsLineSymbol()
153217
s.deleteSymbolLayer(0)
154218

155-
sym_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'segments_to_lines($geometry)'})
156-
sym_layer.setSymbolType(QgsSymbol.Line)
157-
s.appendSymbolLayer(sym_layer)
158-
159-
marker_line = QgsMarkerLineSymbolLayer(False)
160-
marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex)
161-
f = QgsFontUtils.getStandardTestFont('Bold', 24)
162-
marker = QgsFontMarkerSymbolLayer(f.family(), 'x', 24, QColor(255, 255, 0))
163-
marker.setDataDefinedProperty(QgsSymbolLayer.PropertyCharacter, QgsProperty.fromExpression('@geometry_part_num'))
164-
marker_symbol = QgsMarkerSymbol()
165-
marker_symbol.changeSymbolLayer(0, marker)
166-
marker_line.setSubSymbol(marker_symbol)
219+
hash_line = QgsHashedLineSymbolLayer(True)
220+
hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.Interval)
221+
hash_line.setInterval(6)
222+
simple_line = QgsSimpleLineSymbolLayer()
223+
simple_line.setColor(QColor(0, 255, 0))
224+
simple_line.setWidth(1)
167225
line_symbol = QgsLineSymbol()
168-
line_symbol.changeSymbolLayer(0, marker_line)
169-
sym_layer.setSubSymbol(line_symbol)
226+
line_symbol.changeSymbolLayer(0, simple_line)
227+
hash_line.setSubSymbol(line_symbol)
228+
hash_line.setHashLength(10)
170229

171-
# rendering test
172-
g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)')
173-
rendered_image = self.renderGeometry(s, g, buffer=4)
174-
assert self.imageCheck('part_num_variable', 'part_num_variable', rendered_image)
230+
s.appendSymbolLayer(hash_line.clone())
175231

176-
marker.setDataDefinedProperty(QgsSymbolLayer.PropertyCharacter,
177-
QgsProperty.fromExpression('@geometry_part_count'))
232+
s.symbolLayer(0).setOffset(3)
233+
g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)')
234+
rendered_image = self.renderGeometry(s, g)
235+
assert self.imageCheck('line_offset_positive', 'line_offset_positive', rendered_image)
178236

179-
# rendering test
180-
g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)')
181-
rendered_image = self.renderGeometry(s, g, buffer=4)
182-
assert self.imageCheck('part_count_variable', 'part_count_variable', rendered_image)
237+
s.symbolLayer(0).setOffset(-3)
238+
g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)')
239+
rendered_image = self.renderGeometry(s, g)
240+
assert self.imageCheck('line_offset_negative', 'line_offset_negative', rendered_image)
241+
242+
def testPointNumInterval(self):
243+
s = QgsLineSymbol()
244+
s.deleteSymbolLayer(0)
245+
246+
hash_line = QgsHashedLineSymbolLayer(True)
247+
hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.Interval)
248+
hash_line.setInterval(6)
249+
simple_line = QgsSimpleLineSymbolLayer()
250+
simple_line.setColor(QColor(0, 255, 0))
251+
simple_line.setWidth(1)
252+
line_symbol = QgsLineSymbol()
253+
line_symbol.changeSymbolLayer(0, simple_line)
254+
hash_line.setSubSymbol(line_symbol)
255+
hash_line.setHashLength(10)
256+
257+
s.appendSymbolLayer(hash_line.clone())
258+
259+
s.symbolLayer(0).setDataDefinedProperty(QgsSymbolLayer.PropertyLineDistance, QgsProperty.fromExpression(
260+
"@geometry_point_num * 2"))
261+
262+
g = QgsGeometry.fromWkt('LineString(0 0, 10 10, 10 0)')
263+
rendered_image = self.renderGeometry(s, g)
264+
assert self.imageCheck('line_dd_size', 'line_dd_size', rendered_image)
183265

184266
def renderGeometry(self, symbol, geom, buffer=20):
185267
f = QgsFeature()
@@ -220,7 +302,7 @@ def imageCheck(self, name, reference_image, image):
220302
file_name = temp_dir + 'symbol_' + name + ".png"
221303
image.save(file_name, "PNG")
222304
checker = QgsRenderChecker()
223-
checker.setControlPathPrefix("symbol_markerline")
305+
checker.setControlPathPrefix("symbol_hashline")
224306
checker.setControlName("expected_" + reference_image)
225307
checker.setRenderedImage(file_name)
226308
checker.setColorTolerance(2)
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<PAMDataset>
2+
<Metadata>
3+
<MDI key="DataType">Elevation</MDI>
4+
</Metadata>
5+
<PAMRasterBand band="1">
6+
<Description>Band_1</Description>
7+
<Metadata>
8+
<MDI key="BandName">Band_1</MDI>
9+
<MDI key="RepresentationType">ATHEMATIC</MDI>
10+
<MDI key="STATISTICS_MAXIMUM">3213.7951660156</MDI>
11+
<MDI key="STATISTICS_MEAN">2335.8976949608</MDI>
12+
<MDI key="STATISTICS_MINIMUM">1586.3486328125</MDI>
13+
<MDI key="STATISTICS_STDDEV">323.62312867371</MDI>
14+
</Metadata>
15+
</PAMRasterBand>
16+
</PAMDataset>
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<PAMDataset>
2+
<PAMRasterBand band="1">
3+
<Metadata>
4+
<MDI key="STATISTICS_MAXIMUM">71.871116638184</MDI>
5+
<MDI key="STATISTICS_MEAN">28.050672685235</MDI>
6+
<MDI key="STATISTICS_MINIMUM">0.10726764053106</MDI>
7+
<MDI key="STATISTICS_STDDEV">10.367817429681</MDI>
8+
</Metadata>
9+
</PAMRasterBand>
10+
</PAMDataset>
Loading

0 commit comments

Comments
 (0)