Skip to content

Commit dc38706

Browse files
committed
Add tests for Create Atlas Coverage algorithm
1 parent b1496df commit dc38706

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
/***************************************************************************
5+
GeovitaProcessingPlugin - Tests
6+
-------------------
7+
begin : 2024-06-07
8+
9+
***************************************************************************/
10+
11+
/***************************************************************************
12+
* *
13+
* This program is free software; you can redistribute it and/or modify *
14+
* it under the terms of the GNU General Public License as published by *
15+
* the Free Software Foundation; either version 2 of the License, or *
16+
* (at your option) any later version. *
17+
* *
18+
***************************************************************************/
19+
"""
20+
21+
from pathlib import Path
22+
23+
from qgis import processing
24+
from qgis.testing import unittest
25+
from qgis.core import (
26+
QgsApplication,
27+
QgsProcessingContext,
28+
QgsProcessingException,
29+
QgsProcessingFeedback,
30+
QgsVectorLayer,
31+
QgsFeature,
32+
QgsGeometry,
33+
QgsPointXY,
34+
)
35+
36+
from geovita_processing_plugin.algorithms.CreateAtlasCoverageAlgorithm import (
37+
CreateAtlasCoverageAlgorithm,
38+
)
39+
from geovita_processing_plugin.geovita_processing_plugin_provider import (
40+
GeovitaProcessingPluginProvider,
41+
)
42+
43+
44+
class TestCreateAtlasCoverageAlgorithm(unittest.TestCase):
45+
def setUp(self):
46+
registry = QgsApplication.processingRegistry()
47+
if not registry.providerById("geovita"):
48+
self.provider = GeovitaProcessingPluginProvider()
49+
registry.addProvider(self.provider)
50+
51+
base_dir = Path(__file__).parent
52+
self.data_dir = base_dir / "data"
53+
self.centerline_path = self.data_dir / "centerline.shp"
54+
self.assertTrue(
55+
self.centerline_path.is_file(),
56+
"Centerline shape source file does not exist.",
57+
)
58+
59+
self.centerline_layer = QgsVectorLayer(
60+
str(self.centerline_path), "test_centerline", "ogr"
61+
)
62+
self.assertTrue(
63+
self.centerline_layer.isValid(),
64+
"Centerline layer failed to load.",
65+
)
66+
67+
self.default_params = {
68+
CreateAtlasCoverageAlgorithm.INPUT_LINE: self.centerline_layer,
69+
CreateAtlasCoverageAlgorithm.INPUT_SCALE: 1000,
70+
CreateAtlasCoverageAlgorithm.INPUT_PAPER_LONG_MM: 410.0,
71+
CreateAtlasCoverageAlgorithm.INPUT_PAPER_SHORT_MM: 287.0,
72+
CreateAtlasCoverageAlgorithm.INPUT_OVERLAP: 50.0,
73+
}
74+
75+
def test_algorithm_discoverable(self):
76+
algorithm = QgsApplication.processingRegistry().algorithmById(
77+
"geovita:create_atlas_coverage"
78+
)
79+
self.assertIsNotNone(
80+
algorithm,
81+
"geovita:create_atlas_coverage was not discovered in the processing registry.",
82+
)
83+
84+
def test_happy_path_geometry_generation(self):
85+
params = dict(self.default_params)
86+
context = QgsProcessingContext()
87+
feedback = QgsProcessingFeedback()
88+
89+
results = processing.run(
90+
"geovita:create_atlas_coverage",
91+
params,
92+
context=context,
93+
feedback=feedback,
94+
)
95+
96+
points_result = results.get(CreateAtlasCoverageAlgorithm.OUTPUT_POINTS)
97+
polygons_result = results.get(CreateAtlasCoverageAlgorithm.OUTPUT_POLYGONS)
98+
99+
points_layer = context.getMapLayer(points_result) if points_result else None
100+
polygons_layer = (
101+
context.getMapLayer(polygons_result) if polygons_result else None
102+
)
103+
104+
self.assertIsNotNone(points_layer, "Points layer was not returned.")
105+
self.assertIsNotNone(polygons_layer, "Polygons layer was not returned.")
106+
107+
self.assertTrue(points_layer.isValid(), "Points layer is not valid.")
108+
self.assertTrue(polygons_layer.isValid(), "Polygons layer is not valid.")
109+
110+
points_count = points_layer.featureCount()
111+
polygons_count = polygons_layer.featureCount()
112+
113+
self.assertGreater(points_count, 0, "Points layer contains no features.")
114+
self.assertGreater(polygons_count, 0, "Polygons layer contains no features.")
115+
self.assertEqual(
116+
points_count,
117+
polygons_count,
118+
"Points and polygons feature counts do not match.",
119+
)
120+
121+
point_field_names = [field.name() for field in points_layer.fields()]
122+
self.assertIn("angle", point_field_names, "Angle field missing in points layer.")
123+
124+
real_long_m = (
125+
self.default_params[CreateAtlasCoverageAlgorithm.INPUT_PAPER_LONG_MM]
126+
* self.default_params[CreateAtlasCoverageAlgorithm.INPUT_SCALE]
127+
/ 1000.0
128+
)
129+
real_short_m = (
130+
self.default_params[CreateAtlasCoverageAlgorithm.INPUT_PAPER_SHORT_MM]
131+
* self.default_params[CreateAtlasCoverageAlgorithm.INPUT_SCALE]
132+
/ 1000.0
133+
)
134+
expected_area = real_long_m * real_short_m
135+
136+
first_polygon = next(polygons_layer.getFeatures())
137+
self.assertAlmostEqual(
138+
first_polygon.geometry().area(),
139+
expected_area,
140+
places=3,
141+
msg="Output polygon area does not match the expected atlas coverage area.",
142+
)
143+
144+
def test_edge_case_overlap_too_large(self):
145+
params = dict(self.default_params)
146+
params[CreateAtlasCoverageAlgorithm.INPUT_OVERLAP] = 500.0
147+
148+
with self.assertRaises(QgsProcessingException):
149+
processing.run(
150+
"geovita:create_atlas_coverage",
151+
params,
152+
context=QgsProcessingContext(),
153+
feedback=QgsProcessingFeedback(),
154+
)
155+
156+
def test_edge_case_line_too_short(self):
157+
short_line_layer = QgsVectorLayer("LineString?crs=EPSG:25833", "short_line", "memory")
158+
provider = short_line_layer.dataProvider()
159+
160+
feature = QgsFeature()
161+
feature.setGeometry(
162+
QgsGeometry.fromPolylineXY(
163+
[QgsPointXY(0, 0), QgsPointXY(10, 0)]
164+
)
165+
)
166+
provider.addFeature(feature)
167+
short_line_layer.updateExtents()
168+
169+
params = dict(self.default_params)
170+
params[CreateAtlasCoverageAlgorithm.INPUT_LINE] = short_line_layer
171+
172+
results = processing.run(
173+
"geovita:create_atlas_coverage",
174+
params,
175+
context=QgsProcessingContext(),
176+
feedback=QgsProcessingFeedback(),
177+
)
178+
179+
self.assertEqual(
180+
results,
181+
{
182+
CreateAtlasCoverageAlgorithm.OUTPUT_POINTS: None,
183+
CreateAtlasCoverageAlgorithm.OUTPUT_POLYGONS: None,
184+
},
185+
"Algorithm should return None outputs when the line is too short.",
186+
)
187+
188+
189+
if __name__ == "__main__":
190+
unittest.main()

0 commit comments

Comments
 (0)