yirgacheffe 1.3.4__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 (54) hide show
  1. {yirgacheffe-1.3.4/yirgacheffe.egg-info → yirgacheffe-1.4.0}/PKG-INFO +1 -1
  2. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/pyproject.toml +1 -1
  3. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_auto_windowing.py +1 -1
  4. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_datatypes.py +1 -1
  5. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_h3layer.py +1 -1
  6. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_intersection.py +1 -2
  7. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_operators.py +5 -5
  8. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_optimisation.py +1 -2
  9. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_parallel_operators.py +10 -10
  10. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_pickle.py +1 -1
  11. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_raster.py +0 -10
  12. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_vectors.py +2 -26
  13. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/__init__.py +0 -3
  14. {yirgacheffe-1.3.4/yirgacheffe/backends → yirgacheffe-1.4.0/yirgacheffe/_backends}/__init__.py +1 -1
  15. {yirgacheffe-1.3.4/yirgacheffe/backends → yirgacheffe-1.4.0/yirgacheffe/_backends}/mlx.py +1 -1
  16. yirgacheffe-1.4.0/yirgacheffe/layers/__init__.py +14 -0
  17. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/layers/base.py +20 -7
  18. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/layers/constant.py +1 -1
  19. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/layers/group.py +14 -11
  20. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/layers/h3layer.py +7 -2
  21. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/layers/rasters.py +27 -16
  22. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/layers/rescaled.py +3 -2
  23. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/layers/vectors.py +37 -30
  24. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/operators.py +13 -10
  25. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/window.py +93 -2
  26. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0/yirgacheffe.egg-info}/PKG-INFO +1 -1
  27. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe.egg-info/SOURCES.txt +4 -5
  28. yirgacheffe-1.3.4/yirgacheffe/h3layer.py +0 -2
  29. yirgacheffe-1.3.4/yirgacheffe/layers/__init__.py +0 -43
  30. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/LICENSE +0 -0
  31. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/MANIFEST.in +0 -0
  32. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/README.md +0 -0
  33. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/setup.cfg +0 -0
  34. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_area.py +0 -0
  35. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_base.py +0 -0
  36. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_constants.py +0 -0
  37. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_group.py +0 -0
  38. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_multiband.py +0 -0
  39. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_rescaling.py +0 -0
  40. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_rounding.py +0 -0
  41. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_save_with_window.py +0 -0
  42. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_sum_with_window.py +0 -0
  43. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_uniform_area_layer.py +0 -0
  44. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_union.py +0 -0
  45. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/tests/test_window.py +0 -0
  46. {yirgacheffe-1.3.4/yirgacheffe/backends → yirgacheffe-1.4.0/yirgacheffe/_backends}/enumeration.py +0 -0
  47. {yirgacheffe-1.3.4/yirgacheffe/backends → yirgacheffe-1.4.0/yirgacheffe/_backends}/numpy.py +0 -0
  48. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/constants.py +0 -0
  49. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/layers/area.py +0 -0
  50. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe/rounding.py +0 -0
  51. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe.egg-info/dependency_links.txt +0 -0
  52. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe.egg-info/entry_points.txt +0 -0
  53. {yirgacheffe-1.3.4 → yirgacheffe-1.4.0}/yirgacheffe.egg-info/requires.txt +0 -0
  54. {yirgacheffe-1.3.4 → 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.4
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.4"
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" }]
@@ -251,7 +251,7 @@ def test_vector_layers_multiply() -> None:
251
251
  expected = np.array([[2, 0], [0, 8]])
252
252
  assert (expected == actual).all()
253
253
 
254
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
254
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
255
255
  def test_parallel_save_windows() -> None:
256
256
  data1 = np.array([[1, 2], [3, 4]])
257
257
  data2 = np.array([[10, 20, 30, 40], [50, 60, 70, 80], [90, 100, 110, 120], [130, 140, 150, 160]])
@@ -4,7 +4,7 @@ import pytest
4
4
  from osgeo import gdal
5
5
 
6
6
  from yirgacheffe.operators import DataType
7
- from yirgacheffe.backends import backend, BACKEND
7
+ from yirgacheffe._backends import backend, BACKEND
8
8
  from yirgacheffe.layers import RasterLayer
9
9
 
10
10
  from tests.helpers import gdal_dataset_with_data
@@ -6,7 +6,7 @@ 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.backends import backend
9
+ from yirgacheffe._backends import backend
10
10
 
11
11
  # work around of pylint
12
12
  demote_array = backend.demote_array
@@ -3,8 +3,7 @@ from osgeo import gdal
3
3
 
4
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
 
@@ -9,7 +9,7 @@ import torch
9
9
  import yirgacheffe
10
10
  from yirgacheffe.layers import RasterLayer, ConstantLayer
11
11
  from yirgacheffe.operators import LayerOperation, DataType
12
- from yirgacheffe.backends import backend
12
+ from yirgacheffe._backends import backend
13
13
  from tests.helpers import gdal_dataset_with_data
14
14
 
15
15
  def test_add_byte_layers() -> None:
@@ -584,7 +584,7 @@ def test_direct_layer_save_and_sum() -> None:
584
584
  assert (data1 == actual_data).all()
585
585
  assert expected_sum == actual_sum
586
586
 
587
- @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")
588
588
  def test_add_to_float_layer_by_np_array() -> None:
589
589
  data1 = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]])
590
590
  layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
@@ -619,7 +619,7 @@ def test_write_mulitband_raster() -> None:
619
619
 
620
620
  assert (expected == actual).all()
621
621
 
622
- @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")
623
623
  def test_save_and_sum_float32(monkeypatch) -> None:
624
624
  random.seed(42)
625
625
  data = []
@@ -643,7 +643,7 @@ def test_save_and_sum_float32(monkeypatch) -> None:
643
643
  actual = layer1.save(store, and_sum=True)
644
644
  assert expected == actual
645
645
 
646
- @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")
647
647
  def test_parallel_save_and_sum_float32(monkeypatch) -> None:
648
648
  random.seed(42)
649
649
  data = []
@@ -671,7 +671,7 @@ def test_parallel_save_and_sum_float32(monkeypatch) -> None:
671
671
  actual = layer1.parallel_save(store, and_sum=True)
672
672
  assert expected == actual
673
673
 
674
- @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")
675
675
  def test_sum_float32(monkeypatch) -> None:
676
676
  random.seed(42)
677
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, 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
 
@@ -43,7 +43,7 @@ def test_add_byte_layers_with_one_thread_uses_regular_save(monkeypatch) -> None:
43
43
  comp.parallel_save(result)
44
44
 
45
45
 
46
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
46
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
47
47
  def test_add_byte_layers(monkeypatch) -> None:
48
48
  with monkeypatch.context() as m:
49
49
  m.setattr(yirgacheffe.constants, "YSTEP", 1)
@@ -71,7 +71,7 @@ def test_add_byte_layers(monkeypatch) -> None:
71
71
 
72
72
  assert (expected == actual).all()
73
73
 
74
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
74
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
75
75
  def test_add_byte_layers_and_sum(monkeypatch) -> None:
76
76
  with monkeypatch.context() as m:
77
77
  m.setattr(yirgacheffe.constants, "YSTEP", 1)
@@ -100,7 +100,7 @@ def test_add_byte_layers_and_sum(monkeypatch) -> None:
100
100
  assert (expected == actual).all()
101
101
  assert sum_total == expected.sum()
102
102
 
103
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
103
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
104
104
  def test_parallel_sum(monkeypatch) -> None:
105
105
  with monkeypatch.context() as m:
106
106
  m.setattr(yirgacheffe.constants, "YSTEP", 1)
@@ -125,7 +125,7 @@ def test_parallel_sum(monkeypatch) -> None:
125
125
  expected = data1 + data2
126
126
  assert sum_total == expected.sum()
127
127
 
128
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
128
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
129
129
  @pytest.mark.parametrize("skip,expected_steps", [
130
130
  (1, [0.0, 0.25, 0.5, 0.75, 1.0]),
131
131
  (2, [0.0, 0.5, 1.0]),
@@ -162,7 +162,7 @@ def test_parallel_with_different_skip(monkeypatch, skip, expected_steps) -> None
162
162
 
163
163
  assert callback_possitions == expected_steps
164
164
 
165
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
165
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
166
166
  def test_parallel_equality(monkeypatch) -> None:
167
167
  with monkeypatch.context() as m:
168
168
  m.setattr(yirgacheffe.constants, "YSTEP", 1)
@@ -182,7 +182,7 @@ def test_parallel_equality(monkeypatch) -> None:
182
182
 
183
183
  assert (expected == actual).all()
184
184
 
185
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
185
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
186
186
  def test_parallel_equality_to_file(monkeypatch) -> None:
187
187
  with monkeypatch.context() as m:
188
188
  m.setattr(yirgacheffe.constants, "YSTEP", 1)
@@ -202,7 +202,7 @@ def test_parallel_equality_to_file(monkeypatch) -> None:
202
202
  actual = actual_result.read_array(0, 0, 4, 2)
203
203
  assert (expected == actual).all()
204
204
 
205
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
205
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
206
206
  def test_parallel_unary_numpy_apply_with_function(monkeypatch) -> None:
207
207
  with monkeypatch.context() as m:
208
208
  m.setattr(yirgacheffe.constants, "YSTEP", 1)
@@ -228,7 +228,7 @@ def test_parallel_unary_numpy_apply_with_function(monkeypatch) -> None:
228
228
 
229
229
  assert (expected == actual).all()
230
230
 
231
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
231
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
232
232
  def test_parallel_unary_numpy_apply_with_lambda(monkeypatch) -> None:
233
233
  with monkeypatch.context() as m:
234
234
  m.setattr(yirgacheffe.constants, "YSTEP", 1)
@@ -251,7 +251,7 @@ def test_parallel_unary_numpy_apply_with_lambda(monkeypatch) -> None:
251
251
 
252
252
  assert (expected == actual).all()
253
253
 
254
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
254
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
255
255
  def test_parallel_where_simple(monkeypatch) -> None:
256
256
  with monkeypatch.context() as m:
257
257
  m.setattr(yirgacheffe.constants, "YSTEP", 1)
@@ -273,7 +273,7 @@ def test_parallel_where_simple(monkeypatch) -> None:
273
273
  actual = result.read_array(0, 0, 4, 2)
274
274
  assert (expected == actual).all()
275
275
 
276
- @pytest.mark.skipif(yirgacheffe.backends.BACKEND != "NUMPY", reason="Only applies for numpy")
276
+ @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
277
277
  def test_parallel_conv2d() -> None:
278
278
  with tempfile.TemporaryDirectory() as tempdir:
279
279
 
@@ -12,7 +12,7 @@ from yirgacheffe.window import Area, PixelScale, Window
12
12
  from yirgacheffe.layers import ConstantLayer, GroupLayer, RasterLayer, RescaledRasterLayer, \
13
13
  UniformAreaLayer, VectorLayer
14
14
  from yirgacheffe import WGS_84_PROJECTION
15
- from yirgacheffe.backends import backend
15
+ from yirgacheffe._backends import backend
16
16
 
17
17
 
18
18
  def test_pickle_raster_layer() -> None:
@@ -38,16 +38,6 @@ def test_make_basic_layer() -> None:
38
38
 
39
39
  assert close_called
40
40
 
41
- def test_make_basic_layer_old_name() -> None:
42
- from yirgacheffe.layers import Layer # pylint: disable=C0415
43
-
44
- area = Area(-10, 10, 10, -10)
45
- with Layer(gdal_dataset_of_region(area, 0.02)) as layer:
46
- assert layer.area == area
47
- assert layer.pixel_scale == (0.02, -0.02)
48
- assert layer.geo_transform == (-10, 0.02, 0.0, 10, 0.0, -0.02)
49
- assert layer.window == Window(0, 0, 1000, 1000)
50
-
51
41
  def test_layer_from_null() -> None:
52
42
  # Seems a petty test, but gdal doesn't throw exceptions
53
43
  # so you often get None datasets if you're not careful
@@ -5,7 +5,7 @@ import pytest
5
5
 
6
6
  from tests.helpers import make_vectors_with_mutlile_ids, make_vectors_with_id, make_vectors_with_empty_feature
7
7
  from yirgacheffe import WGS_84_PROJECTION
8
- from yirgacheffe.layers import RasterLayer, RasteredVectorLayer, VectorLayer, VectorRangeLayer, DynamicVectorRangeLayer
8
+ from yirgacheffe.layers import RasterLayer, RasteredVectorLayer, VectorLayer
9
9
  from yirgacheffe.window import Area, PixelScale, Window
10
10
  from yirgacheffe.operators import DataType
11
11
 
@@ -31,18 +31,6 @@ def test_basic_dyanamic_vector_layer() -> None:
31
31
  assert layer.window == Window(0, 0, 20, 10)
32
32
  assert layer.projection == WGS_84_PROJECTION
33
33
 
34
- def test_old_dyanamic_vector_layer() -> None:
35
- with tempfile.TemporaryDirectory() as tempdir:
36
- path = os.path.join(tempdir, "test.gpkg")
37
- area = Area(-10.0, 10.0, 10.0, 0.0)
38
- make_vectors_with_id(42, {area}, path)
39
-
40
- with DynamicVectorRangeLayer(path, "id_no = 42", PixelScale(1.0, -1.0), WGS_84_PROJECTION) as layer:
41
- assert layer.area == area
42
- assert layer.geo_transform == (area.left, 1.0, 0.0, area.top, 0.0, -1.0)
43
- assert layer.window == Window(0, 0, 20, 10)
44
- assert layer.projection == WGS_84_PROJECTION
45
-
46
34
  def test_rastered_vector_layer() -> None:
47
35
  with tempfile.TemporaryDirectory() as tempdir:
48
36
  path = os.path.join(tempdir, "test.gpkg")
@@ -55,18 +43,6 @@ def test_rastered_vector_layer() -> None:
55
43
  assert layer.window == Window(0, 0, 20, 10)
56
44
  assert layer.projection == WGS_84_PROJECTION
57
45
 
58
- def test_old_rastered_vector_layer() -> None:
59
- with tempfile.TemporaryDirectory() as tempdir:
60
- path = os.path.join(tempdir, "test.gpkg")
61
- area = Area(-10.0, 10.0, 10.0, 0.0)
62
- make_vectors_with_id(42, {area}, path)
63
-
64
- with VectorRangeLayer(path, "id_no = 42", PixelScale(1.0, -1.0), WGS_84_PROJECTION) as layer:
65
- assert layer.area == area
66
- assert layer.geo_transform == (area.left, 1.0, 0.0, area.top, 0.0, -1.0)
67
- assert layer.window == Window(0, 0, 20, 10)
68
- assert layer.projection == WGS_84_PROJECTION
69
-
70
46
  def test_basic_dynamic_vector_layer_no_filter_match() -> None:
71
47
  with tempfile.TemporaryDirectory() as tempdir:
72
48
  path = os.path.join(tempdir, "test.gpkg")
@@ -385,7 +361,7 @@ def test_read_array_size(size, expect_success):
385
361
  area = Area(-10.0, 10.0, 10.0, 0.0)
386
362
  make_vectors_with_id(42, {area}, path)
387
363
 
388
- source = VectorRangeLayer(path, "id_no = 42", PixelScale(1.0, -1.0), WGS_84_PROJECTION)
364
+ source = RasteredVectorLayer.layer_from_file(path, "id_no = 42", PixelScale(1.0, -1.0), WGS_84_PROJECTION)
389
365
 
390
366
  if expect_success:
391
367
  data = source.read_array(0, 0, size[0], size[1])
@@ -12,6 +12,3 @@ WGS_84_PROJECTION = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,
12
12
  'AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],'\
13
13
  'UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],'\
14
14
  'AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]'
15
-
16
- # For legacy reasons [facepalm]
17
- WSG_84_PROJECTION = WGS_84_PROJECTION
@@ -8,6 +8,6 @@ match BACKEND:
8
8
  backend = mlx
9
9
  case "NUMPY":
10
10
  from . import numpy
11
- backend = numpy
11
+ backend = numpy # type: ignore[misc]
12
12
  case _:
13
13
  raise NotImplementedError("Only NUMPY and MLX backends supported")
@@ -1,6 +1,6 @@
1
1
 
2
2
  import numpy as np
3
- import mlx.core as mx # pylint: disable=E0001,E0611,E0401
3
+ import mlx.core as mx # type: ignore
4
4
  import mlx.nn
5
5
 
6
6
  from .enumeration import operators as op
@@ -0,0 +1,14 @@
1
+ from osgeo import ogr
2
+
3
+ from ..window import PixelScale
4
+ from .base import YirgacheffeLayer
5
+ from .rasters import RasterLayer, InvalidRasterBand
6
+ from .rescaled import RescaledRasterLayer
7
+ from .vectors import RasteredVectorLayer, VectorLayer
8
+ from .area import UniformAreaLayer
9
+ from .constant import ConstantLayer
10
+ from .group import GroupLayer, TiledGroupLayer
11
+ try:
12
+ from .h3layer import H3CellLayer
13
+ except ModuleNotFoundError:
14
+ pass
@@ -25,7 +25,7 @@ class YirgacheffeLayer(LayerMathMixin):
25
25
 
26
26
  self.reset_window()
27
27
 
28
- def close(self):
28
+ def close(self) -> None:
29
29
  pass
30
30
 
31
31
  def __enter__(self):
@@ -34,6 +34,16 @@ class YirgacheffeLayer(LayerMathMixin):
34
34
  def __exit__(self, exc_type, exc_val, exc_tb):
35
35
  self.close()
36
36
 
37
+ def _park(self) -> None:
38
+ pass
39
+
40
+ def _unpark(self) -> None:
41
+ pass
42
+
43
+ @property
44
+ def _raster_dimensions(self) -> Tuple[int,int]:
45
+ raise AttributeError("Does not have raster")
46
+
37
47
  @property
38
48
  def datatype(self) -> DataType:
39
49
  raise NotImplementedError("Must be overridden by subclass")
@@ -131,9 +141,10 @@ class YirgacheffeLayer(LayerMathMixin):
131
141
  raise ValueError('Window has negative offset')
132
142
  # If there is an underlying raster for this layer, do a sanity check
133
143
  try:
134
- if ((new_window.xoff + new_window.xsize) > self._raster_xsize) or \
135
- ((new_window.yoff + new_window.ysize) > self._raster_ysize):
136
- raise ValueError(f'Window is bigger than dataset: raster is {self._raster_xsize}x{self._raster_ysize}'\
144
+ raster_xsize, raster_ysize = self._raster_dimensions
145
+ if ((new_window.xoff + new_window.xsize) > raster_xsize) or \
146
+ ((new_window.yoff + new_window.ysize) > raster_ysize):
147
+ raise ValueError(f'Window is bigger than dataset: raster is {raster_xsize}x{raster_ysize}'\
137
148
  f', new window is {new_window.xsize - new_window.xoff}x{new_window.ysize - new_window.yoff}')
138
149
  except AttributeError:
139
150
  pass
@@ -162,9 +173,10 @@ class YirgacheffeLayer(LayerMathMixin):
162
173
  raise ValueError('Window has positive offset')
163
174
  # If there is an underlying raster for this layer, do a sanity check
164
175
  try:
165
- if ((new_window.xsize - new_window.xoff) < self._raster_xsize) or \
166
- ((new_window.ysize - new_window.yoff) < self._raster_ysize):
167
- raise ValueError(f'Window is smaller than dataset: raster is {self._raster_xsize}x{self._raster_ysize}'\
176
+ raster_xsize, raster_ysize = self._raster_dimensions
177
+ if ((new_window.xsize - new_window.xoff) < raster_xsize) or \
178
+ ((new_window.ysize - new_window.yoff) <raster_ysize):
179
+ raise ValueError(f'Window is smaller than dataset: raster is {raster_xsize}x{raster_ysize}'\
168
180
  f', new window is {new_window.xsize - new_window.xoff}x{new_window.ysize - new_window.yoff}')
169
181
  except AttributeError:
170
182
  pass
@@ -219,6 +231,7 @@ class YirgacheffeLayer(LayerMathMixin):
219
231
  raise NotImplementedError("Must be overridden by subclass")
220
232
 
221
233
  def read_array_for_area(self, target_area: Area, x: int, y: int, width: int, height: int) -> Any:
234
+ assert self._pixel_scale is not None
222
235
 
223
236
  target_window = Window(
224
237
  xoff=round_down_pixels((target_area.left - self._underlying_area.left) / self._pixel_scale.xstep,
@@ -3,7 +3,7 @@ from typing import Any, Union
3
3
  from ..operators import DataType
4
4
  from ..window import Area, PixelScale, Window
5
5
  from .base import YirgacheffeLayer
6
- from ..backends import backend
6
+ from .._backends import backend
7
7
  from .. import WGS_84_PROJECTION
8
8
 
9
9
 
@@ -1,7 +1,8 @@
1
+ from __future__ import annotations
1
2
  import copy
2
3
  import glob
3
4
  import os
4
- from typing import Any, List, Optional, TypeVar
5
+ from typing import Any, List, Optional
5
6
 
6
7
  import numpy as np
7
8
  from yirgacheffe.operators import DataType
@@ -10,9 +11,8 @@ from ..rounding import are_pixel_scales_equal_enough, round_down_pixels
10
11
  from ..window import Area, Window
11
12
  from .base import YirgacheffeLayer
12
13
  from .rasters import RasterLayer
13
- from ..backends import backend
14
+ from .._backends import backend
14
15
 
15
- GroupLayerT = TypeVar("GroupLayerT", bound="GroupLayer")
16
16
 
17
17
  class GroupLayerEmpty(ValueError):
18
18
  def __init__(self, msg):
@@ -26,7 +26,7 @@ class GroupLayer(YirgacheffeLayer):
26
26
  directory_path: str,
27
27
  name: Optional[str] = None,
28
28
  matching: str = "*.tif"
29
- ) -> GroupLayerT:
29
+ ) -> GroupLayer:
30
30
  if directory_path is None:
31
31
  raise ValueError("Directory path is None")
32
32
  files = [os.path.join(directory_path, x) for x in glob.glob(matching, root_dir=directory_path)]
@@ -35,12 +35,12 @@ class GroupLayer(YirgacheffeLayer):
35
35
  return cls.layer_from_files(files, name)
36
36
 
37
37
  @classmethod
38
- def layer_from_files(cls, filenames: List[str], name: Optional[str] = None) -> GroupLayerT:
38
+ def layer_from_files(cls, filenames: List[str], name: Optional[str] = None) -> GroupLayer:
39
39
  if filenames is None:
40
40
  raise ValueError("filenames argument is None")
41
41
  if len(filenames) < 1:
42
42
  raise GroupLayerEmpty("No files found")
43
- rasters = [RasterLayer.layer_from_file(x) for x in filenames]
43
+ rasters: List[YirgacheffeLayer] = [RasterLayer.layer_from_file(x) for x in filenames]
44
44
  return cls(rasters, name)
45
45
 
46
46
  def __init__(self, layers: List[YirgacheffeLayer], name: Optional[str] = None) -> None:
@@ -65,7 +65,7 @@ class GroupLayer(YirgacheffeLayer):
65
65
  self._underlying_layers.reverse()
66
66
  self.layers = self._underlying_layers
67
67
 
68
- def _park(self):
68
+ def _park(self) -> None:
69
69
  for layer in self.layers:
70
70
  try:
71
71
  layer._park()
@@ -157,7 +157,7 @@ class GroupLayer(YirgacheffeLayer):
157
157
  class TileData:
158
158
  """This class exists just to let me sort the tiles into the correct order for processing."""
159
159
 
160
- def __init__(self, data, x, y):
160
+ def __init__(self, data: Any, x: int, y: int):
161
161
  self.data = data
162
162
  self.x = x
163
163
  self.y = y
@@ -219,7 +219,7 @@ class TiledGroupLayer(GroupLayer):
219
219
  ysize
220
220
  )
221
221
 
222
- partials = []
222
+ partials: List[TileData] = []
223
223
  for layer in self.layers:
224
224
  # Normally this is hidden with set_window_for_...
225
225
  adjusted_layer_window = Window(
@@ -251,7 +251,7 @@ class TiledGroupLayer(GroupLayer):
251
251
  # the "obvious" tile. In which case, we should reject the smaller section. If we have
252
252
  # two tiles at the same offset and one is not a perfect subset of the other then the
253
253
  # tile set we were given is not regularly shaped, and so we should give up.
254
- combed_partials = []
254
+ combed_partials: List[TileData] = []
255
255
  previous_tile = None
256
256
  for tile in sorted_partials:
257
257
  if previous_tile is None:
@@ -276,7 +276,7 @@ class TiledGroupLayer(GroupLayer):
276
276
  expected_next_x = 0
277
277
  expected_next_y = 0
278
278
  data = None
279
- row_chunk = None
279
+ row_chunk: Optional[np.ndarray] = None
280
280
 
281
281
  # Allow for reading off top
282
282
  if combed_partials:
@@ -337,6 +337,7 @@ class TiledGroupLayer(GroupLayer):
337
337
  data = np.vstack((data, row_chunk))
338
338
  expected_next_y += last_y_height
339
339
  else:
340
+ assert last_y_offset is not None
340
341
  diff = expected_next_y - last_y_offset
341
342
  assert diff > 0, f"{expected_next_y} - {last_y_offset} <= 0 (aka {diff})"
342
343
  subdata = np.delete(row_chunk, np.s_[0:diff], 0)
@@ -351,8 +352,10 @@ class TiledGroupLayer(GroupLayer):
351
352
  last_y_height = tile.data.shape[0]
352
353
  expected_next_x = tile.data.shape[1] + tile.x
353
354
 
355
+ assert last_y_offset is not None
354
356
  if (last_y_offset + last_y_height) < ysize:
355
357
  data = np.vstack((data, np.zeros((ysize - (last_y_offset + last_y_height), xsize))))
356
358
 
359
+ assert data is not None
357
360
  assert data.shape == (ysize, xsize)
358
361
  return backend.promote(data)
@@ -1,5 +1,5 @@
1
1
  from math import ceil, floor
2
- from typing import Any
2
+ from typing import Any, Tuple
3
3
 
4
4
  import h3
5
5
  import numpy as np
@@ -8,7 +8,7 @@ from yirgacheffe.operators import DataType
8
8
  from ..rounding import round_up_pixels
9
9
  from ..window import Area, PixelScale, Window
10
10
  from .base import YirgacheffeLayer
11
- from ..backends import backend
11
+ from .._backends import backend
12
12
 
13
13
  class H3CellLayer(YirgacheffeLayer):
14
14
 
@@ -74,12 +74,17 @@ class H3CellLayer(YirgacheffeLayer):
74
74
  (sorted_lats[1] / abs_ystep) * abs_ystep,
75
75
  )
76
76
 
77
+ @property
78
+ def _raster_dimensions(self) -> Tuple[int,int]:
79
+ return (self._raster_xsize, self._raster_ysize)
77
80
 
78
81
  @property
79
82
  def datatype(self) -> DataType:
80
83
  return DataType.Float64
81
84
 
82
85
  def read_array_with_window(self, xoffset: int, yoffset: int, xsize: int, ysize: int, window: Window) -> Any:
86
+ assert self._pixel_scale is not None
87
+
83
88
  if (xsize <= 0) or (ysize <= 0):
84
89
  raise ValueError("Request dimensions must be positive and non-zero")
85
90