yirgacheffe 1.7.0__tar.gz → 1.7.1__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 (56) hide show
  1. {yirgacheffe-1.7.0/yirgacheffe.egg-info → yirgacheffe-1.7.1}/PKG-INFO +1 -1
  2. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/pyproject.toml +1 -1
  3. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_openers.py +22 -0
  4. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_pickle.py +2 -3
  5. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_raster.py +10 -1
  6. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_vectors.py +5 -1
  7. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/_core.py +2 -2
  8. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/layers/base.py +6 -1
  9. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/layers/group.py +8 -8
  10. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/layers/vectors.py +5 -1
  11. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1/yirgacheffe.egg-info}/PKG-INFO +1 -1
  12. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/LICENSE +0 -0
  13. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/MANIFEST.in +0 -0
  14. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/README.md +0 -0
  15. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/setup.cfg +0 -0
  16. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_area.py +0 -0
  17. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_auto_windowing.py +0 -0
  18. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_base.py +0 -0
  19. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_constants.py +0 -0
  20. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_datatypes.py +0 -0
  21. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_group.py +0 -0
  22. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_h3layer.py +0 -0
  23. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_intersection.py +0 -0
  24. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_multiband.py +0 -0
  25. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_nodata.py +0 -0
  26. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_operators.py +0 -0
  27. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_optimisation.py +0 -0
  28. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_parallel_operators.py +0 -0
  29. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_projection.py +0 -0
  30. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_rescaling.py +0 -0
  31. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_rounding.py +0 -0
  32. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_save_with_window.py +0 -0
  33. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_sum_with_window.py +0 -0
  34. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_uniform_area_layer.py +0 -0
  35. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_union.py +0 -0
  36. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/tests/test_window.py +0 -0
  37. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/__init__.py +0 -0
  38. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/_backends/__init__.py +0 -0
  39. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/_backends/enumeration.py +0 -0
  40. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/_backends/mlx.py +0 -0
  41. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/_backends/numpy.py +0 -0
  42. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/constants.py +0 -0
  43. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/layers/__init__.py +0 -0
  44. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/layers/area.py +0 -0
  45. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/layers/constant.py +0 -0
  46. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/layers/h3layer.py +0 -0
  47. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/layers/rasters.py +0 -0
  48. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/layers/rescaled.py +0 -0
  49. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/operators.py +0 -0
  50. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/rounding.py +0 -0
  51. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe/window.py +0 -0
  52. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe.egg-info/SOURCES.txt +0 -0
  53. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe.egg-info/dependency_links.txt +0 -0
  54. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe.egg-info/entry_points.txt +0 -0
  55. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/yirgacheffe.egg-info/requires.txt +0 -0
  56. {yirgacheffe-1.7.0 → yirgacheffe-1.7.1}/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.7.0
3
+ Version: 1.7.1
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.7.0"
9
+ version = "1.7.1"
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" }]
@@ -191,3 +191,25 @@ def test_open_two_raster_areas_side_by_side(tiled):
191
191
  with yg.read_raster(path1) as raster1:
192
192
  with yg.read_raster(path2) as raster2:
193
193
  assert group.sum() == raster1.sum() + raster2.sum()
194
+
195
+ @pytest.mark.parametrize("tiled", [False, True])
196
+ def test_open_two_raster_by_glob(tiled):
197
+ with tempfile.TemporaryDirectory() as tempdir:
198
+ temppath = Path(tempdir)
199
+ path1 = temppath / "test1.tif"
200
+ area1 = Area(-10, 10, 10, -10)
201
+ dataset1 = gdal_dataset_of_region(area1, 0.2, filename=path1)
202
+ dataset1.Close()
203
+
204
+ path2 = temppath / "test2.tif"
205
+ area2 = Area(10, 10, 30, -10)
206
+ dataset2 = gdal_dataset_of_region(area2, 0.2, filename=path2)
207
+ dataset2.Close()
208
+
209
+ with yg.read_rasters(temppath.glob("*.tif"), tiled=tiled) as group:
210
+ assert group.area == Area(-10, 10, 30, -10)
211
+ assert group.window == Window(0, 0, 200, 100)
212
+
213
+ with yg.read_raster(path1) as raster1:
214
+ with yg.read_raster(path2) as raster2:
215
+ assert group.sum() == raster1.sum() + raster2.sum()
@@ -12,7 +12,6 @@ from yirgacheffe.window import Area, MapProjection, 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
16
15
 
17
16
 
18
17
  def test_pickle_raster_layer() -> None:
@@ -97,7 +96,7 @@ def test_pickle_group_layer() -> None:
97
96
 
98
97
  group = GroupLayer.layer_from_directory(tempdir)
99
98
  expected = group.read_array(0, 0, 100, 100)
100
- assert backend.sum_op(expected) != 0 # just check there is meaningful data
99
+ assert expected.sum() != 0 # just check there is meaningful data
101
100
 
102
101
  p = pickle.dumps(group)
103
102
  restore = pickle.loads(p)
@@ -192,4 +191,4 @@ def test_pickle_rescaled_raster_layer() -> None:
192
191
  assert restore.window == Window(0, 0, 2000, 2000)
193
192
 
194
193
  expected = restore.read_array(0, 0, 100, 100)
195
- assert backend.sum_op(expected) != 0 # just check there is meaningful data
194
+ assert expected.sum() != 0 # just check there is meaningful data
@@ -5,7 +5,7 @@ import numpy as np
5
5
  import pytest
6
6
  from osgeo import gdal
7
7
 
8
- from tests.helpers import gdal_dataset_of_region, gdal_multiband_dataset_with_data
8
+ from tests.helpers import gdal_dataset_of_region, gdal_multiband_dataset_with_data, gdal_dataset_with_data
9
9
  from yirgacheffe.window import Area, PixelScale, Window
10
10
  from yirgacheffe.layers import RasterLayer, InvalidRasterBand
11
11
  from yirgacheffe.rounding import round_up_pixels
@@ -260,3 +260,12 @@ def test_multiband_raster() -> None:
260
260
  layer = layers[i]
261
261
  actual = layer.read_array(0, 0, 4, 2)
262
262
  assert (data == actual).all()
263
+
264
+ def test_read_array_is_numpy():
265
+ # This test will fail if we use say the MLX backend without casting it back to numpy
266
+ data = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]])
267
+ dataset = gdal_dataset_with_data((0.0, 0.0), 0.02, data)
268
+ with RasterLayer(dataset) as layer1:
269
+ actual = layer1.read_array(0, 0, 4, 2).astype(int)
270
+ expected = data.astype(int)
271
+ assert (actual == expected).all
@@ -19,7 +19,7 @@ def test_basic_vector_layer_no_filter_match() -> None:
19
19
  with RasteredVectorLayer.layer_from_file(path, "id_no = 123", PixelScale(1.0, -1.0), "WGS 84") as _layer:
20
20
  pass
21
21
 
22
- def test_basic_dyanamic_vector_layer() -> None:
22
+ def test_basic_dynamic_vector_layer() -> None:
23
23
  with tempfile.TemporaryDirectory() as tempdir:
24
24
  path = os.path.join(tempdir, "test.gpkg")
25
25
  area = Area(-10.0, 10.0, 10.0, 0.0)
@@ -31,6 +31,10 @@ 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
+ # The astype here is to catch escaping MLX types...
35
+ res = layer.read_array(0, 0, 20, 20).astype(int)
36
+ assert res.sum() > 0
37
+
34
38
  def test_rastered_vector_layer() -> None:
35
39
  with tempfile.TemporaryDirectory() as tempdir:
36
40
  path = os.path.join(tempdir, "test.gpkg")
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
- from typing import List, Optional, Tuple, Union
2
+ from typing import Optional, Sequence, Tuple, Union
3
3
 
4
4
  from .layers.base import YirgacheffeLayer
5
5
  from .layers.group import GroupLayer, TiledGroupLayer
@@ -32,7 +32,7 @@ def read_raster(
32
32
  return RasterLayer.layer_from_file(filename, band, ignore_nodata)
33
33
 
34
34
  def read_rasters(
35
- filenames : Union[List[Path],List[str]],
35
+ filenames : Sequence[Union[Path,str]],
36
36
  tiled: bool=False
37
37
  ) -> GroupLayer:
38
38
  """Open a set of raster files (e.g., GeoTIFFs) as a single layer.
@@ -7,6 +7,7 @@ from .. import __version__
7
7
  from ..operators import DataType, LayerMathMixin
8
8
  from ..rounding import almost_equal, round_up_pixels, round_down_pixels
9
9
  from ..window import Area, MapProjection, PixelScale, Window
10
+ from .._backends import backend
10
11
 
11
12
  class YirgacheffeLayer(LayerMathMixin):
12
13
  """The common base class for the different layer types. Most still inherit from RasterLayer as deep down
@@ -310,6 +311,9 @@ class YirgacheffeLayer(LayerMathMixin):
310
311
  )
311
312
  return self._read_array_with_window(x, y, width, height, target_window)
312
313
 
314
+ def _read_array(self, x: int, y: int, width: int, height: int) -> Any:
315
+ return self._read_array_with_window(x, y, width, height, self.window)
316
+
313
317
  def read_array(self, x: int, y: int, width: int, height: int) -> Any:
314
318
  """Reads data from the layer based on the current reference window.
315
319
 
@@ -329,7 +333,8 @@ class YirgacheffeLayer(LayerMathMixin):
329
333
  Any
330
334
  An array of values from the layer.
331
335
  """
332
- return self._read_array_with_window(x, y, width, height, self.window)
336
+ res = self._read_array(x, y, width, height)
337
+ return backend.demote_array(res)
333
338
 
334
339
  def latlng_for_pixel(self, x_coord: int, y_coord: int) -> Tuple[float,float]:
335
340
  """Get geo coords for pixel. This is relative to the set view window."""
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
  import copy
3
3
  from pathlib import Path
4
- from typing import Any, List, Optional, Union
4
+ from typing import Any, List, Optional, Sequence, Union
5
5
 
6
6
  import numpy as np
7
7
  from numpy import ma
@@ -39,14 +39,14 @@ class GroupLayer(YirgacheffeLayer):
39
39
  @classmethod
40
40
  def layer_from_files(
41
41
  cls,
42
- filenames: Union[List[Path],List[str]],
42
+ filenames: Sequence[Union[Path,str]],
43
43
  name: Optional[str] = None
44
44
  ) -> GroupLayer:
45
45
  if filenames is None:
46
46
  raise ValueError("filenames argument is None")
47
- if len(filenames) < 1:
48
- raise GroupLayerEmpty("No files found")
49
47
  rasters: List[YirgacheffeLayer] = [RasterLayer.layer_from_file(x) for x in filenames]
48
+ if len(rasters) < 1:
49
+ raise GroupLayerEmpty("No files found")
50
50
  return cls(rasters, name)
51
51
 
52
52
  def __init__(
@@ -144,7 +144,7 @@ class GroupLayer(YirgacheffeLayer):
144
144
  if len(contributing_layers) == 1:
145
145
  layer, adjusted_layer_window, intersection = contributing_layers[0]
146
146
  if target_window == intersection:
147
- data = layer.read_array(
147
+ data = layer._read_array(
148
148
  intersection.xoff - adjusted_layer_window.xoff,
149
149
  intersection.yoff - adjusted_layer_window.yoff,
150
150
  intersection.xsize,
@@ -156,11 +156,11 @@ class GroupLayer(YirgacheffeLayer):
156
156
 
157
157
  result = np.zeros((ysize, xsize), dtype=float)
158
158
  for layer, adjusted_layer_window, intersection in contributing_layers:
159
- data = layer.read_array(
159
+ data = layer._read_array(
160
160
  intersection.xoff - adjusted_layer_window.xoff,
161
161
  intersection.yoff - adjusted_layer_window.yoff,
162
162
  intersection.xsize,
163
- intersection.ysize,
163
+ intersection.ysize
164
164
  )
165
165
  result_x_offset = (intersection.xoff - xoffset) - window.xoff
166
166
  result_y_offset = (intersection.yoff - yoffset) - window.yoff
@@ -269,7 +269,7 @@ class TiledGroupLayer(GroupLayer):
269
269
  intersection = Window.find_intersection_no_throw([target_window, adjusted_layer_window])
270
270
  if intersection is None:
271
271
  continue
272
- data = layer.read_array(
272
+ data = layer._read_array(
273
273
  intersection.xoff - adjusted_layer_window.xoff,
274
274
  intersection.yoff - adjusted_layer_window.yoff,
275
275
  intersection.xsize,
@@ -490,5 +490,9 @@ class VectorLayer(YirgacheffeLayer):
490
490
  def _read_array_with_window(self, _x, _y, _width, _height, _window) -> Any:
491
491
  assert NotRequired
492
492
 
493
- def read_array(self, x: int, y: int, width: int, height: int) -> Any:
493
+ def _read_array(self, x: int, y: int, width: int, height: int) -> Any:
494
494
  return self._read_array_for_area(self.area, None, x, y, width, height)
495
+
496
+ def read_array(self, x: int, y: int, width: int, height: int) -> Any:
497
+ res = self._read_array(x, y, width, height)
498
+ return backend.demote_array(res)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yirgacheffe
3
- Version: 1.7.0
3
+ Version: 1.7.1
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
File without changes
File without changes
File without changes
File without changes