yirgacheffe 1.3.3__tar.gz → 1.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of yirgacheffe might be problematic. Click here for more details.

Files changed (57) hide show
  1. {yirgacheffe-1.3.3/yirgacheffe.egg-info → yirgacheffe-1.4.0}/PKG-INFO +1 -1
  2. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/pyproject.toml +1 -1
  3. yirgacheffe-1.4.0/tests/test_area.py +21 -0
  4. yirgacheffe-1.4.0/tests/test_auto_windowing.py +284 -0
  5. yirgacheffe-1.4.0/tests/test_constants.py +32 -0
  6. yirgacheffe-1.4.0/tests/test_datatypes.py +67 -0
  7. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_group.py +4 -4
  8. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_h3layer.py +10 -8
  9. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_intersection.py +2 -3
  10. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_multiband.py +2 -2
  11. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_operators.py +7 -8
  12. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_optimisation.py +2 -3
  13. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_parallel_operators.py +13 -13
  14. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_pickle.py +4 -3
  15. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_raster.py +2 -12
  16. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_rescaling.py +1 -1
  17. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_save_with_window.py +1 -1
  18. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_sum_with_window.py +1 -1
  19. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_uniform_area_layer.py +1 -1
  20. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_union.py +1 -1
  21. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_vectors.py +16 -30
  22. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/__init__.py +0 -3
  23. {yirgacheffe-1.3.3/yirgacheffe/backends → yirgacheffe-1.4.0/yirgacheffe/_backends}/__init__.py +1 -1
  24. {yirgacheffe-1.3.3/yirgacheffe/backends → yirgacheffe-1.4.0/yirgacheffe/_backends}/mlx.py +1 -1
  25. yirgacheffe-1.4.0/yirgacheffe/layers/__init__.py +14 -0
  26. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/layers/base.py +20 -7
  27. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/layers/constant.py +1 -1
  28. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/layers/group.py +14 -11
  29. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/layers/h3layer.py +7 -2
  30. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/layers/rasters.py +27 -16
  31. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/layers/rescaled.py +3 -2
  32. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/layers/vectors.py +37 -30
  33. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/operators.py +35 -13
  34. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/window.py +93 -2
  35. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0/yirgacheffe.egg-info}/PKG-INFO +1 -1
  36. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe.egg-info/SOURCES.txt +5 -5
  37. yirgacheffe-1.3.3/tests/test_area.py +0 -21
  38. yirgacheffe-1.3.3/tests/test_auto_windowing.py +0 -284
  39. yirgacheffe-1.3.3/tests/test_datatypes.py +0 -67
  40. yirgacheffe-1.3.3/yirgacheffe/h3layer.py +0 -2
  41. yirgacheffe-1.3.3/yirgacheffe/layers/__init__.py +0 -43
  42. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/LICENSE +0 -0
  43. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/MANIFEST.in +0 -0
  44. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/README.md +0 -0
  45. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/setup.cfg +0 -0
  46. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_base.py +0 -0
  47. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_rounding.py +0 -0
  48. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/tests/test_window.py +0 -0
  49. {yirgacheffe-1.3.3/yirgacheffe/backends → yirgacheffe-1.4.0/yirgacheffe/_backends}/enumeration.py +0 -0
  50. {yirgacheffe-1.3.3/yirgacheffe/backends → yirgacheffe-1.4.0/yirgacheffe/_backends}/numpy.py +0 -0
  51. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/constants.py +0 -0
  52. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/layers/area.py +0 -0
  53. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe/rounding.py +0 -0
  54. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe.egg-info/dependency_links.txt +0 -0
  55. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe.egg-info/entry_points.txt +0 -0
  56. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe.egg-info/requires.txt +0 -0
  57. {yirgacheffe-1.3.3 → yirgacheffe-1.4.0}/yirgacheffe.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yirgacheffe
3
- Version: 1.3.3
3
+ Version: 1.4.0
4
4
  Summary: Abstraction of gdal datasets for doing basic math operations
5
5
  Author-email: Michael Dales <mwd24@cam.ac.uk>
6
6
  License-Expression: ISC
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "yirgacheffe"
9
- version = "1.3.3"
9
+ version = "1.4.0"
10
10
  description = "Abstraction of gdal datasets for doing basic math operations"
11
11
  readme = "README.md"
12
12
  authors = [{ name = "Michael Dales", email = "mwd24@cam.ac.uk" }]
@@ -0,0 +1,21 @@
1
+ import pytest
2
+
3
+ # I've no idea why pylint dislikes this particular import but accepts
4
+ # other entries in the module.
5
+ from yirgacheffe.window import Area # pylint: disable=E0401, E0611
6
+
7
+ @pytest.mark.parametrize(
8
+ "lhs,rhs,is_equal,overlaps",
9
+ [
10
+ # Obvious equality
11
+ (Area(-10.0, 10.0, 10.0, -10.0), Area(-10.0, 10.0, 10.0, -10.0), True, True),
12
+ (Area(-9.0, 9.0, 9.0, -9.0), Area(-10.0, 10.0, 10.0, -10.0), False, True), # subset
13
+ (Area(-9.0, 9.0, -1.0, 1.0), Area(1.0, -1.0, 9.0, -9.0), False, False),
14
+ (Area(-10.0, 10.0, 1.0, -10.0), Area(-1.0, 10.0, 10.0, -10.0), False, True),
15
+ ]
16
+ )
17
+ def test_area_operators(lhs: Area, rhs: Area, is_equal: bool, overlaps: bool) -> None:
18
+ assert (lhs == rhs) == is_equal
19
+ assert (lhs != rhs) == (not is_equal)
20
+ assert (lhs.overlaps(rhs)) == overlaps
21
+ assert (rhs.overlaps(lhs)) == overlaps
@@ -0,0 +1,284 @@
1
+ import os
2
+ import tempfile
3
+
4
+ import numpy as np
5
+ import pytest
6
+
7
+ import yirgacheffe
8
+ from tests.helpers import gdal_dataset_with_data, make_vectors_with_mutlile_ids
9
+ from yirgacheffe.layers import ConstantLayer, RasterLayer, VectorLayer
10
+ from yirgacheffe.window import Area
11
+
12
+ def test_add_windows() -> None:
13
+ data1 = np.array([[1, 2], [3, 4]])
14
+ data2 = np.array([[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
15
+
16
+ layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
17
+ layer2 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data2))
18
+
19
+ assert layer1.area != layer2.area
20
+ assert layer1.window != layer2.window
21
+
22
+ calc = layer1 + layer2
23
+
24
+ assert calc.area == layer2.area
25
+ assert calc.window == layer2.window
26
+
27
+ result = RasterLayer.empty_raster_layer_like(calc)
28
+ calc.save(result)
29
+
30
+ expected = np.array([[11, 22, 30, 40], [53, 64, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
31
+ actual = result.read_array(0, 0, 4, 4)
32
+ assert (expected == actual).all()
33
+
34
+ def test_multiply_windows() -> None:
35
+ data1 = np.array([[1, 2], [3, 4]])
36
+ data2 = np.array([[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
37
+
38
+ layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
39
+ layer2 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data2))
40
+
41
+ assert layer1.area != layer2.area
42
+ assert layer1.window != layer2.window
43
+
44
+ calc = layer1 * layer2
45
+
46
+ assert calc.area == layer1.area
47
+ assert calc.window == layer1.window
48
+
49
+ result = RasterLayer.empty_raster_layer_like(calc)
50
+ calc.save(result)
51
+
52
+ expected = np.array([[10, 40], [150, 240]])
53
+ actual = result.read_array(0, 0, 2, 2)
54
+ assert (expected == actual).all()
55
+
56
+ def test_add_windows_offset() -> None:
57
+ data1 = np.array([[1, 2], [3, 4]])
58
+ data2 = np.array([[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
59
+
60
+ layer1 = RasterLayer(gdal_dataset_with_data((-0.02, 0.02), 0.02, data1))
61
+ layer2 = RasterLayer(gdal_dataset_with_data((-0.04, 0.04), 0.02, data2))
62
+
63
+ assert layer1.area != layer2.area
64
+ assert layer1.window != layer2.window
65
+
66
+ calc = layer1 + layer2
67
+
68
+ assert calc.area == layer2.area
69
+
70
+ result = RasterLayer.empty_raster_layer_like(calc)
71
+ calc.save(result)
72
+
73
+ expected = np.array([[10, 20, 30, 40], [50, 61, 72, 80], [90, 103, 114, 120], [130, 140, 150, 160]])
74
+ actual = result.read_array(0, 0, 4, 4)
75
+ assert (expected == actual).all()
76
+
77
+ def test_multiply_windows_offset() -> None:
78
+ data1 = np.array([[1, 2], [3, 4]])
79
+ data2 = np.array([[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
80
+
81
+ layer1 = RasterLayer(gdal_dataset_with_data((-0.02, 0.02), 0.02, data1))
82
+ layer2 = RasterLayer(gdal_dataset_with_data((-0.04, 0.04), 0.02, data2))
83
+
84
+ assert layer1.area != layer2.area
85
+ assert layer1.window != layer2.window
86
+
87
+ calc = layer1 * layer2
88
+
89
+ assert calc.area == layer1.area
90
+
91
+ result = RasterLayer.empty_raster_layer_like(calc)
92
+ calc.save(result)
93
+
94
+ expected = np.array([[60, 140], [300, 440]])
95
+ actual = result.read_array(0, 0, 2, 2)
96
+ assert (expected == actual).all()
97
+
98
+ def test_add_windows_sum() -> None:
99
+ data1 = np.array([[1, 2], [3, 4]])
100
+ data2 = np.array([[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
101
+
102
+ layer1 = RasterLayer(gdal_dataset_with_data((-0.02, 0.02), 0.02, data1))
103
+ layer2 = RasterLayer(gdal_dataset_with_data((-0.04, 0.04), 0.02, data2))
104
+
105
+ calc = layer1 + layer2
106
+ total = calc.sum()
107
+
108
+ expected = np.array([[10, 20, 30, 40], [50, 61, 72, 80], [90, 103, 114, 120], [130, 140, 150, 160]])
109
+ assert total == np.sum(expected)
110
+
111
+ def test_multiply_windows_sum() -> None:
112
+ data1 = np.array([[1, 2], [3, 4]])
113
+ data2 = np.array([[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
114
+
115
+ layer1 = RasterLayer(gdal_dataset_with_data((-0.02, 0.02), 0.02, data1))
116
+ layer2 = RasterLayer(gdal_dataset_with_data((-0.04, 0.04), 0.02, data2))
117
+
118
+ calc = layer1 * layer2
119
+ total = calc.sum()
120
+
121
+ expected = np.array([[60, 140], [300, 440]])
122
+ assert total == np.sum(expected)
123
+
124
+ def test_constant_layer_result_rhs_add() -> None:
125
+ data1 = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]])
126
+ layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
127
+ const_layer = ConstantLayer(1.0)
128
+
129
+ calc = layer1 + const_layer
130
+
131
+ assert calc.area == layer1.area
132
+
133
+ result = RasterLayer.empty_raster_layer_like(calc)
134
+ calc.save(result)
135
+ actual = result.read_array(0, 0, 4, 2)
136
+
137
+ expected = 1.0 + data1
138
+
139
+ assert (expected == actual).all()
140
+
141
+ def test_constant_layer_result_lhs_add() -> None:
142
+ data1 = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]])
143
+ layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
144
+ const_layer = ConstantLayer(1.0)
145
+ result = RasterLayer.empty_raster_layer_like(layer1)
146
+
147
+ intersection = RasterLayer.find_intersection([layer1, const_layer])
148
+ const_layer.set_window_for_intersection(intersection)
149
+ layer1.set_window_for_intersection(intersection)
150
+
151
+ calc = const_layer + layer1
152
+
153
+ assert calc.area == layer1.area
154
+
155
+ result = RasterLayer.empty_raster_layer_like(calc)
156
+ calc.save(result)
157
+ actual = result.read_array(0, 0, 4, 2)
158
+
159
+ expected = 1.0 + data1
160
+
161
+ assert (expected == actual).all()
162
+
163
+ def test_constant_layer_result_rhs_multiply() -> None:
164
+ data1 = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]])
165
+ layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
166
+ const_layer = ConstantLayer(2.0)
167
+
168
+ calc = layer1 * const_layer
169
+
170
+ assert calc.area == layer1.area
171
+
172
+ result = RasterLayer.empty_raster_layer_like(calc)
173
+ calc.save(result)
174
+ actual = result.read_array(0, 0, 4, 2)
175
+
176
+ expected = data1 * 2.0
177
+
178
+ assert (expected == actual).all()
179
+
180
+ def test_constant_layer_result_lhs_multiply() -> None:
181
+ data1 = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]])
182
+ layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
183
+ const_layer = ConstantLayer(2.0)
184
+ result = RasterLayer.empty_raster_layer_like(layer1)
185
+
186
+ intersection = RasterLayer.find_intersection([layer1, const_layer])
187
+ const_layer.set_window_for_intersection(intersection)
188
+ layer1.set_window_for_intersection(intersection)
189
+
190
+ calc = const_layer * layer1
191
+
192
+ assert calc.area == layer1.area
193
+
194
+ result = RasterLayer.empty_raster_layer_like(calc)
195
+ calc.save(result)
196
+ actual = result.read_array(0, 0, 4, 2)
197
+
198
+ expected = 2.0 * data1
199
+
200
+ assert (expected == actual).all()
201
+
202
+ def test_vector_layers_add() -> None:
203
+ data1 = np.array([[1, 2], [3, 4]])
204
+ layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 1.0, data1))
205
+
206
+ with tempfile.TemporaryDirectory() as tempdir:
207
+ path = os.path.join(tempdir, "test.gpkg")
208
+ areas = {
209
+ (Area(-10.0, 10.0, 0.0, 0.0), 42),
210
+ (Area(0.0, 0.0, 10, -10), 43)
211
+ }
212
+ make_vectors_with_mutlile_ids(areas, path)
213
+
214
+ burn_value = 2
215
+ layer2 = VectorLayer.layer_from_file(path, None, layer1.pixel_scale, layer1.projection, burn_value=burn_value)
216
+ layer2_total = layer2.sum()
217
+ assert layer2_total == ((layer2.window.xsize * layer2.window.ysize) / 2) * burn_value
218
+
219
+ calc = layer1 + layer2
220
+
221
+ assert calc.area == layer2.area
222
+
223
+ total = calc.sum()
224
+ assert total == layer2_total + np.sum(data1)
225
+
226
+ def test_vector_layers_multiply() -> None:
227
+ data1 = np.array([[1, 2], [3, 4]])
228
+ layer1 = RasterLayer(gdal_dataset_with_data((-1.0, 1.0), 1.0, data1))
229
+
230
+ with tempfile.TemporaryDirectory() as tempdir:
231
+ path = os.path.join(tempdir, "test.gpkg")
232
+ areas = {
233
+ (Area(-10.0, 10.0, 0.0, 0.0), 42),
234
+ (Area(0.0, 0.0, 10, -10), 43)
235
+ }
236
+ make_vectors_with_mutlile_ids(areas, path)
237
+
238
+ burn_value = 2
239
+ layer2 = VectorLayer.layer_from_file(path, None, layer1.pixel_scale, layer1.projection, burn_value=burn_value)
240
+ layer2_total = layer2.sum()
241
+ assert layer2_total == ((layer2.window.xsize * layer2.window.ysize) / 2) * burn_value
242
+
243
+ calc = layer1 * layer2
244
+
245
+ assert calc.area == layer1.area
246
+
247
+ result = RasterLayer.empty_raster_layer_like(calc)
248
+ calc.save(result)
249
+ actual = result.read_array(0, 0, 2, 2)
250
+
251
+ expected = np.array([[2, 0], [0, 8]])
252
+ assert (expected == actual).all()
253
+
254
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
255
+ def test_parallel_save_windows() -> None:
256
+ data1 = np.array([[1, 2], [3, 4]])
257
+ data2 = np.array([[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
258
+
259
+ with tempfile.TemporaryDirectory() as tempdir:
260
+ layer1_filename = os.path.join(tempdir, "layer1.tif")
261
+ layer1_dataset = gdal_dataset_with_data((0.0, 0.0), 0.02, data1, filename=layer1_filename)
262
+ layer1_dataset.Close()
263
+
264
+ layer2_filename = os.path.join(tempdir, "layer2.tif")
265
+ layer2_dataset = gdal_dataset_with_data((0.0, 0.0), 0.02, data2, filename=layer2_filename)
266
+ layer2_dataset.Close()
267
+
268
+ layer1 = RasterLayer.layer_from_file(layer1_filename)
269
+ layer2 = RasterLayer.layer_from_file(layer2_filename)
270
+
271
+ assert layer1.area != layer2.area
272
+ assert layer1.window != layer2.window
273
+
274
+ calc = layer1 + layer2
275
+
276
+ assert calc.area == layer2.area
277
+ assert calc.window == layer2.window
278
+
279
+ result = RasterLayer.empty_raster_layer_like(calc)
280
+ calc.parallel_save(result)
281
+
282
+ expected = np.array([[11, 22, 30, 40], [53, 64, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
283
+ actual = result.read_array(0, 0, 4, 4)
284
+ assert (expected == actual).all()
@@ -0,0 +1,32 @@
1
+
2
+ import numpy as np
3
+ import yirgacheffe
4
+ from yirgacheffe.layers import RasterLayer, ConstantLayer
5
+ from yirgacheffe.operators import DataType
6
+ from yirgacheffe.window import Area, PixelScale
7
+
8
+ def test_constant_save() -> None:
9
+ area = Area(left=-1.0, right=1.0, top=1.0, bottom=-1.0)
10
+ scale = PixelScale(0.1, -0.1)
11
+ with RasterLayer.empty_raster_layer(area, scale, DataType.Float32) as result:
12
+ with ConstantLayer(42.0) as c:
13
+ c.save(result)
14
+
15
+ expected = np.full((20, 20), 42.0)
16
+ actual = result.read_array(0, 0, 20, 20)
17
+
18
+ assert (expected == actual).all()
19
+
20
+ def test_constant_parallel_save(monkeypatch) -> None:
21
+ area = Area(left=-1.0, right=1.0, top=1.0, bottom=-1.0)
22
+ scale = PixelScale(0.1, -0.1)
23
+ with RasterLayer.empty_raster_layer(area, scale, DataType.Float32) as result:
24
+ with ConstantLayer(42.0) as c:
25
+ with monkeypatch.context() as m:
26
+ m.setattr(yirgacheffe.constants, "YSTEP", 1)
27
+ c.parallel_save(result)
28
+
29
+ expected = np.full((20, 20), 42.0)
30
+ actual = result.read_array(0, 0, 20, 20)
31
+
32
+ assert (expected == actual).all()
@@ -0,0 +1,67 @@
1
+
2
+ import numpy as np
3
+ import pytest
4
+ from osgeo import gdal
5
+
6
+ from yirgacheffe.operators import DataType
7
+ from yirgacheffe._backends import backend, BACKEND
8
+ from yirgacheffe.layers import RasterLayer
9
+
10
+ from tests.helpers import gdal_dataset_with_data
11
+
12
+ @pytest.mark.parametrize("gtype", [
13
+ gdal.GDT_Int8,
14
+ gdal.GDT_Int16,
15
+ gdal.GDT_Int32,
16
+ gdal.GDT_Int64,
17
+ gdal.GDT_Byte,
18
+ gdal.GDT_UInt16,
19
+ gdal.GDT_UInt32,
20
+ gdal.GDT_UInt64,
21
+ gdal.GDT_Float32,
22
+ ])
23
+ def test_round_trip(gtype) -> None:
24
+ ytype = DataType.of_gdal(gtype)
25
+ backend_type = backend.dtype_to_backed(ytype)
26
+ assert backend.backend_to_dtype(backend_type) == ytype
27
+
28
+ @pytest.mark.parametrize("ytype", [
29
+ DataType.Int8,
30
+ DataType.Int16,
31
+ DataType.Int32,
32
+ DataType.Int64,
33
+ DataType.UInt8,
34
+ DataType.UInt16,
35
+ DataType.UInt32,
36
+ DataType.UInt64,
37
+ DataType.Float32,
38
+ DataType.Float64,
39
+ ])
40
+ def test_round_trip_from_gdal(ytype) -> None:
41
+ gtype = ytype.to_gdal()
42
+ assert DataType.of_gdal(gtype) == ytype
43
+
44
+ def test_round_trip_float64() -> None:
45
+ backend_type = backend.dtype_to_backed(DataType.Float64)
46
+ ytype = backend.backend_to_dtype(backend_type)
47
+ print(BACKEND, "sad")
48
+ match BACKEND:
49
+ case "NUMPY":
50
+ assert ytype == DataType.Float64
51
+ case "MLX":
52
+ assert ytype == DataType.Float32
53
+
54
+ def test_float_to_int() -> None:
55
+ data1 = np.array([[1.0, 2.0, 3.0, 4.0], [5.5, 6.5, 7.5, 8.5]])
56
+
57
+ layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
58
+ # Note the float 32 here is to rule out that writing the result to the
59
+ # new dataset was what caused the truncation
60
+ result = RasterLayer.empty_raster_layer_like(layer1, datatype=DataType.Float32)
61
+
62
+ comp = layer1.astype(DataType.UInt8)
63
+ comp.save(result)
64
+
65
+ expected = backend.promote(np.array([[1, 2, 3, 4], [5, 6, 7, 8]]))
66
+ actual = backend.demote_array(result.read_array(0, 0, 4, 2))
67
+ assert (expected == actual).all()
@@ -5,7 +5,7 @@ import tempfile
5
5
  import numpy as np
6
6
  import pytest
7
7
 
8
- from helpers import gdal_dataset_of_region, gdal_dataset_with_data, make_vectors_with_id, generate_child_tile
8
+ from tests.helpers import gdal_dataset_of_region, gdal_dataset_with_data, make_vectors_with_id, generate_child_tile
9
9
  from yirgacheffe import WGS_84_PROJECTION
10
10
  from yirgacheffe.layers import GroupLayer, RasterLayer, TiledGroupLayer, VectorLayer
11
11
  from yirgacheffe.window import Area, PixelScale, Window
@@ -35,7 +35,7 @@ def test_valid_file_list():
35
35
  assert group.area == area
36
36
  assert group.window == Window(0, 0, 100, 100)
37
37
 
38
- def test_valid_file_list():
38
+ def test_valid_file_list_from_dir():
39
39
  with tempfile.TemporaryDirectory() as tempdir:
40
40
  path = os.path.join(tempdir, "test.tif")
41
41
  area = Area(-10, 10, 10, -10)
@@ -221,8 +221,8 @@ def test_with_window_adjust(klass):
221
221
 
222
222
  # Test before we apply a window
223
223
  row = group.read_array(0, 0, 100, 1)[0]
224
- for idx in range(len(row)):
225
- assert row[idx] == math.ceil((idx + 1) / 10.0)
224
+ for idx, val in enumerate(row):
225
+ assert val == math.ceil((idx + 1) / 10.0)
226
226
 
227
227
  # Test also for manual offsets that we get expected result
228
228
  for idx in range(0, 10):
@@ -6,8 +6,10 @@ from osgeo import gdal
6
6
  from yirgacheffe import WGS_84_PROJECTION
7
7
  from yirgacheffe.layers import RasterLayer, H3CellLayer
8
8
  from yirgacheffe.window import Area, PixelScale
9
- from yirgacheffe.operators import ShaderStyleOperation
10
- from yirgacheffe.backends import backend
9
+ from yirgacheffe._backends import backend
10
+
11
+ # work around of pylint
12
+ demote_array = backend.demote_array
11
13
 
12
14
 
13
15
  @pytest.mark.parametrize(
@@ -135,10 +137,10 @@ def test_h3_layer_clipped(lat: float, lng: float) -> None:
135
137
 
136
138
  # whilst we're here, check that we do have an filled border (i.e., does window for
137
139
  # intersection do the right thing)
138
- assert np.sum(backend.demote_array(h3_layer.read_array(0, 0, h3_layer.window.xsize, 5))) > 0.0
139
- assert np.sum(backend.demote_array(h3_layer.read_array(0, h3_layer.window.ysize - 5, h3_layer.window.xsize, 5))) > 0.0
140
- assert np.sum(backend.demote_array(h3_layer.read_array(0, 0, 5, h3_layer.window.ysize))) > 0.0
141
- assert np.sum(backend.demote_array(h3_layer.read_array(h3_layer.window.xsize - 5, 0, 5, h3_layer.window.ysize))) > 0.0
140
+ assert np.sum(demote_array(h3_layer.read_array(0, 0, h3_layer.window.xsize, 5))) > 0.0
141
+ assert np.sum(demote_array(h3_layer.read_array(0, h3_layer.window.ysize - 5, h3_layer.window.xsize, 5))) > 0.0
142
+ assert np.sum(demote_array(h3_layer.read_array(0, 0, 5, h3_layer.window.ysize))) > 0.0
143
+ assert np.sum(demote_array(h3_layer.read_array(h3_layer.window.xsize - 5, 0, 5, h3_layer.window.ysize))) > 0.0
142
144
 
143
145
  @pytest.mark.parametrize(
144
146
  "lat,lng",
@@ -189,8 +191,8 @@ def test_h3_layer_wrapped_on_projection(lat: float, lng: float) -> None:
189
191
  assert expanded_area == area
190
192
 
191
193
  # whilst we're here, check that we do have an empty border (i.e., does window for union do the right thing)
192
- assert np.sum(backend.demote_array(h3_layer.read_array(0, 0, h3_layer.window.xsize, 2))) == 0.0
193
- assert np.sum(backend.demote_array(h3_layer.read_array(0, h3_layer.window.ysize - 2, h3_layer.window.xsize, 2))) == 0.0
194
+ assert np.sum(demote_array(h3_layer.read_array(0, 0, h3_layer.window.xsize, 2))) == 0.0
195
+ assert np.sum(demote_array(h3_layer.read_array(0, h3_layer.window.ysize - 2, h3_layer.window.xsize, 2))) == 0.0
194
196
 
195
197
  def test_h3_layer_overlapped():
196
198
  # This is based on a regression, where somehow I made tiles not tesselate properly
@@ -1,10 +1,9 @@
1
1
  import pytest
2
2
  from osgeo import gdal
3
3
 
4
- from helpers import gdal_dataset_of_region, gdal_empty_dataset_of_region
4
+ from tests.helpers import gdal_dataset_of_region, gdal_empty_dataset_of_region
5
5
  from yirgacheffe.window import Area, PixelScale, Window
6
- from yirgacheffe.layers import RasterLayer, ConstantLayer
7
- from yirgacheffe.h3layer import H3CellLayer
6
+ from yirgacheffe.layers import RasterLayer, ConstantLayer, H3CellLayer
8
7
  from yirgacheffe import WGS_84_PROJECTION
9
8
 
10
9
 
@@ -4,7 +4,7 @@ import tempfile
4
4
  import numpy as np
5
5
  from osgeo import gdal
6
6
 
7
- from helpers import gdal_dataset_with_data
7
+ from tests.helpers import gdal_dataset_with_data
8
8
  from yirgacheffe.layers import RasterLayer
9
9
  from yirgacheffe.window import Area, PixelScale
10
10
 
@@ -52,7 +52,7 @@ def test_stack_tifs_with_area_match() -> None:
52
52
  for layer in source_layers:
53
53
  layer.set_window_for_intersection(intersection)
54
54
 
55
- # Note we're abusing that layer is the last of the source_layers here from the above loop
55
+ layer = source_layers[-1]
56
56
  assert layer.window.xsize == 100 - (bands - 1)
57
57
  assert layer.window.ysize == 100 - (bands - 1)
58
58
 
@@ -5,13 +5,12 @@ import tempfile
5
5
  import numpy as np
6
6
  import pytest
7
7
  import torch
8
- from osgeo import gdal
9
8
 
10
- from helpers import gdal_dataset_with_data
11
9
  import yirgacheffe
12
10
  from yirgacheffe.layers import RasterLayer, ConstantLayer
13
11
  from yirgacheffe.operators import LayerOperation, DataType
14
- from yirgacheffe.backends import backend
12
+ from yirgacheffe._backends import backend
13
+ from tests.helpers import gdal_dataset_with_data
15
14
 
16
15
  def test_add_byte_layers() -> None:
17
16
  data1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]).astype(np.uint8)
@@ -71,7 +70,7 @@ def test_add_byte_layers_with_callback(skip, expected_steps) -> None:
71
70
 
72
71
  comp = layer1 + layer2
73
72
  comp.ystep = skip
74
- comp.save(result, callback=lambda x: callback_possitions.append(x))
73
+ comp.save(result, callback=callback_possitions.append)
75
74
 
76
75
  expected = data1 + data2
77
76
  actual = result.read_array(0, 0, 4, 2)
@@ -585,7 +584,7 @@ def test_direct_layer_save_and_sum() -> None:
585
584
  assert (data1 == actual_data).all()
586
585
  assert expected_sum == actual_sum
587
586
 
588
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
587
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
589
588
  def test_add_to_float_layer_by_np_array() -> None:
590
589
  data1 = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]])
591
590
  layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
@@ -620,7 +619,7 @@ def test_write_mulitband_raster() -> None:
620
619
 
621
620
  assert (expected == actual).all()
622
621
 
623
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
622
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
624
623
  def test_save_and_sum_float32(monkeypatch) -> None:
625
624
  random.seed(42)
626
625
  data = []
@@ -644,7 +643,7 @@ def test_save_and_sum_float32(monkeypatch) -> None:
644
643
  actual = layer1.save(store, and_sum=True)
645
644
  assert expected == actual
646
645
 
647
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
646
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
648
647
  def test_parallel_save_and_sum_float32(monkeypatch) -> None:
649
648
  random.seed(42)
650
649
  data = []
@@ -672,7 +671,7 @@ def test_parallel_save_and_sum_float32(monkeypatch) -> None:
672
671
  actual = layer1.parallel_save(store, and_sum=True)
673
672
  assert expected == actual
674
673
 
675
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
674
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
676
675
  def test_sum_float32(monkeypatch) -> None:
677
676
  random.seed(42)
678
677
  data = []
@@ -4,8 +4,7 @@ import numpy as np
4
4
  import pytest
5
5
 
6
6
  from yirgacheffe import WGS_84_PROJECTION
7
- from yirgacheffe.h3layer import H3CellLayer
8
- from yirgacheffe.layers import PixelScale, ConstantLayer, RasterLayer
7
+ from yirgacheffe.layers import PixelScale, RasterLayer, H3CellLayer
9
8
  from yirgacheffe.window import Area
10
9
  import yirgacheffe.operators as yo
11
10
 
@@ -14,7 +13,7 @@ class NaiveH3CellLayer(H3CellLayer):
14
13
  so the H3CellLayer has a bunch of tricks to try reduce the work done. This is a naive
15
14
  version that checks for every cell."""
16
15
 
17
- def read_array(self, xoffset, yoffset, xsize, ysize):
16
+ def read_array(self, xoffset, yoffset, xsize, ysize): # pylint: disable=W0237
18
17
  res = np.zeros((ysize, xsize), dtype=float)
19
18
  start_x = self._active_area.left + (xoffset * self._pixel_scale.xstep)
20
19
  start_y = self._active_area.top + (yoffset * self._pixel_scale.ystep)