kuva-reader 0.1.3__tar.gz → 1.0.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 kuva-reader might be problematic. Click here for more details.
- kuva_reader-1.0.0/PKG-INFO +118 -0
- kuva_reader-1.0.0/README.md +94 -0
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/__init__.py +10 -8
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/reader/level0.py +12 -0
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/reader/level1.py +34 -1
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/reader/level2.py +24 -0
- kuva_reader-1.0.0/kuva_reader/reader/read.py +55 -0
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/pyproject.toml +10 -11
- kuva_reader-0.1.3/PKG-INFO +0 -24
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/py.typed +0 -0
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/reader/__init__.py +0 -0
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/reader/image.py +0 -0
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/reader/product_base.py +0 -0
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/reader/py.typed +0 -0
- {kuva_reader-0.1.3 → kuva_reader-1.0.0}/kuva_reader/reader/utils.py +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: kuva-reader
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Manipulate the Kuva Space image and metadata formats
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Guillem Ballesteros
|
|
7
|
+
Author-email: guillem@kuvaspace.com
|
|
8
|
+
Requires-Python: >=3.10,<=3.13
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Requires-Dist: kuva-geometry @ file:///home/olli/projects/kuva-repos/kuva-data-processing/kuva-geometry
|
|
15
|
+
Requires-Dist: kuva-metadata @ file:///home/olli/projects/kuva-repos/kuva-data-processing/kuva-metadata
|
|
16
|
+
Requires-Dist: numpy (>=1.26.4,<2.0.0)
|
|
17
|
+
Requires-Dist: numpy-quaternion (>=2022.4.4,<2023.0.0)
|
|
18
|
+
Requires-Dist: pint (>=0.22,<0.23)
|
|
19
|
+
Requires-Dist: rasterio (>=1.4.1,<2.0.0)
|
|
20
|
+
Requires-Dist: rioxarray (>=0.12.4,<0.13.0)
|
|
21
|
+
Requires-Dist: xarray (>=2022.12.0,<2023.0.0)
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
<div align="center">
|
|
25
|
+
<picture>
|
|
26
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/1d8b44f1-1999-4cfb-8744-32871056c253">
|
|
27
|
+
<img alt="kuva-space-logo" src="https://github.com/user-attachments/assets/d8f47cc8-1491-4d0c-a8cf-318ea7e0afdc" width="50%">
|
|
28
|
+
</picture>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
# Reader for Kuva Space images
|
|
32
|
+
|
|
33
|
+
The reader project allows the reading of Kuva Space products from any part of its processing chain.
|
|
34
|
+
|
|
35
|
+
The Kuva Space images are in GeoTIFF format. The products consist of an image or multiple
|
|
36
|
+
images along with its metadata to give all the necessary information to use the products.
|
|
37
|
+
The metadata lives either in a Kuva Space database, or alternatively in a sidecar JSON file.
|
|
38
|
+
|
|
39
|
+
This library allows the reading of the image GeoTIFFs into `xarray.Dataset` objects that
|
|
40
|
+
allow convenient raster manipulations, along with their `kuva-metadata` metadata objects.
|
|
41
|
+
|
|
42
|
+
# Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install kuva-reader
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Requirements
|
|
49
|
+
|
|
50
|
+
`Python 3.10` to `3.13`, preferably within a virtual environment
|
|
51
|
+
|
|
52
|
+
# Code
|
|
53
|
+
|
|
54
|
+
## Minimal example
|
|
55
|
+
|
|
56
|
+
This is a minimal example that allows you to read and print the image shape of a L1 product. \
|
|
57
|
+
The result product is in this case an L1C product (as seen from the folder name).
|
|
58
|
+
The loaded product is stored in a `rioxarray` object, which contains extensive GIS functionalities [(examples for usage)](https://corteva.github.io/rioxarray/stable/examples/examples.html).
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from kuva_reader import read_product
|
|
62
|
+
|
|
63
|
+
l2a_product = read_product("my_data_folder/hyperfield1a_L2A_20250105T092548")
|
|
64
|
+
print(product) # Will show some main information such as image shape and CRS
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This assumes a mostly untouched folder after distributing. Otherwise, you may need to
|
|
68
|
+
read the product manually based on the product processing level:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from kuva_reader import Level2AProduct
|
|
72
|
+
|
|
73
|
+
l2a_product = Level2AProduct("your/l2a/folder")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The actual raster image is stored and can be analysed in `product.image`, while metadata
|
|
77
|
+
information of the product is in `product.metadata`.
|
|
78
|
+
|
|
79
|
+
## Processing levels
|
|
80
|
+
|
|
81
|
+
Currently the reader supports the following processing levels for Kuva products:
|
|
82
|
+
|
|
83
|
+
- **L0**: Radiometrically corrected frames as TOA radiance
|
|
84
|
+
- **L1AB**: Band-aligned product formed from multiple L0 products
|
|
85
|
+
- **L1C**: Georeferences and orthorectified L1 product
|
|
86
|
+
- **L2A**: Atmospherically corrected product as BOA reflectance
|
|
87
|
+
|
|
88
|
+
## Special tags
|
|
89
|
+
|
|
90
|
+
All images generated by Kuva Space should have the following special tags added to the
|
|
91
|
+
geotiff metadata.
|
|
92
|
+
- `_KUVA_PRODUCT_LEVEL`: A string, e.g, `"0"` describing the level of the product.
|
|
93
|
+
- `_KUVA_PRODUCT_ID`: The id on the database for the product associated with the geotiff.
|
|
94
|
+
|
|
95
|
+
This makes it very easy to pinpoint what product we are dealing with and works around
|
|
96
|
+
the issue that our images are not a monolithic entity but rather just folders that can
|
|
97
|
+
be messed with.
|
|
98
|
+
|
|
99
|
+
# Contributing
|
|
100
|
+
|
|
101
|
+
Please follow the guidelines in [CONTRIBUTING.md](https://github.com/KuvaSpace/kuva-data-processing/blob/main/CONTRIBUTING.md).
|
|
102
|
+
|
|
103
|
+
Also, please follow our [Code of Conduct](https://github.com/KuvaSpace/kuva-data-processing/blob/main/CODE_OF_CONDUCT.md)
|
|
104
|
+
while discussing in the issues and pull requests.
|
|
105
|
+
|
|
106
|
+
# Contact information
|
|
107
|
+
|
|
108
|
+
For questions or support, please open an issue. If you have been given a support contact,
|
|
109
|
+
feel free to send them an email explaining your issue.
|
|
110
|
+
|
|
111
|
+
# License
|
|
112
|
+
|
|
113
|
+
The `kuva-reader` project software is under the [MIT license](https://github.com/KuvaSpace/kuva-data-processing/blob/main/LICENSE.md).
|
|
114
|
+
|
|
115
|
+
# Status of unit tests
|
|
116
|
+
|
|
117
|
+
[](https://github.com/KuvaSpace/kuva-data-processing/actions/workflows/test-kuva-reader.yml)
|
|
118
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/1d8b44f1-1999-4cfb-8744-32871056c253">
|
|
4
|
+
<img alt="kuva-space-logo" src="https://github.com/user-attachments/assets/d8f47cc8-1491-4d0c-a8cf-318ea7e0afdc" width="50%">
|
|
5
|
+
</picture>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
# Reader for Kuva Space images
|
|
9
|
+
|
|
10
|
+
The reader project allows the reading of Kuva Space products from any part of its processing chain.
|
|
11
|
+
|
|
12
|
+
The Kuva Space images are in GeoTIFF format. The products consist of an image or multiple
|
|
13
|
+
images along with its metadata to give all the necessary information to use the products.
|
|
14
|
+
The metadata lives either in a Kuva Space database, or alternatively in a sidecar JSON file.
|
|
15
|
+
|
|
16
|
+
This library allows the reading of the image GeoTIFFs into `xarray.Dataset` objects that
|
|
17
|
+
allow convenient raster manipulations, along with their `kuva-metadata` metadata objects.
|
|
18
|
+
|
|
19
|
+
# Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install kuva-reader
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Requirements
|
|
26
|
+
|
|
27
|
+
`Python 3.10` to `3.13`, preferably within a virtual environment
|
|
28
|
+
|
|
29
|
+
# Code
|
|
30
|
+
|
|
31
|
+
## Minimal example
|
|
32
|
+
|
|
33
|
+
This is a minimal example that allows you to read and print the image shape of a L1 product. \
|
|
34
|
+
The result product is in this case an L1C product (as seen from the folder name).
|
|
35
|
+
The loaded product is stored in a `rioxarray` object, which contains extensive GIS functionalities [(examples for usage)](https://corteva.github.io/rioxarray/stable/examples/examples.html).
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from kuva_reader import read_product
|
|
39
|
+
|
|
40
|
+
l2a_product = read_product("my_data_folder/hyperfield1a_L2A_20250105T092548")
|
|
41
|
+
print(product) # Will show some main information such as image shape and CRS
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This assumes a mostly untouched folder after distributing. Otherwise, you may need to
|
|
45
|
+
read the product manually based on the product processing level:
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from kuva_reader import Level2AProduct
|
|
49
|
+
|
|
50
|
+
l2a_product = Level2AProduct("your/l2a/folder")
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The actual raster image is stored and can be analysed in `product.image`, while metadata
|
|
54
|
+
information of the product is in `product.metadata`.
|
|
55
|
+
|
|
56
|
+
## Processing levels
|
|
57
|
+
|
|
58
|
+
Currently the reader supports the following processing levels for Kuva products:
|
|
59
|
+
|
|
60
|
+
- **L0**: Radiometrically corrected frames as TOA radiance
|
|
61
|
+
- **L1AB**: Band-aligned product formed from multiple L0 products
|
|
62
|
+
- **L1C**: Georeferences and orthorectified L1 product
|
|
63
|
+
- **L2A**: Atmospherically corrected product as BOA reflectance
|
|
64
|
+
|
|
65
|
+
## Special tags
|
|
66
|
+
|
|
67
|
+
All images generated by Kuva Space should have the following special tags added to the
|
|
68
|
+
geotiff metadata.
|
|
69
|
+
- `_KUVA_PRODUCT_LEVEL`: A string, e.g, `"0"` describing the level of the product.
|
|
70
|
+
- `_KUVA_PRODUCT_ID`: The id on the database for the product associated with the geotiff.
|
|
71
|
+
|
|
72
|
+
This makes it very easy to pinpoint what product we are dealing with and works around
|
|
73
|
+
the issue that our images are not a monolithic entity but rather just folders that can
|
|
74
|
+
be messed with.
|
|
75
|
+
|
|
76
|
+
# Contributing
|
|
77
|
+
|
|
78
|
+
Please follow the guidelines in [CONTRIBUTING.md](https://github.com/KuvaSpace/kuva-data-processing/blob/main/CONTRIBUTING.md).
|
|
79
|
+
|
|
80
|
+
Also, please follow our [Code of Conduct](https://github.com/KuvaSpace/kuva-data-processing/blob/main/CODE_OF_CONDUCT.md)
|
|
81
|
+
while discussing in the issues and pull requests.
|
|
82
|
+
|
|
83
|
+
# Contact information
|
|
84
|
+
|
|
85
|
+
For questions or support, please open an issue. If you have been given a support contact,
|
|
86
|
+
feel free to send them an email explaining your issue.
|
|
87
|
+
|
|
88
|
+
# License
|
|
89
|
+
|
|
90
|
+
The `kuva-reader` project software is under the [MIT license](https://github.com/KuvaSpace/kuva-data-processing/blob/main/LICENSE.md).
|
|
91
|
+
|
|
92
|
+
# Status of unit tests
|
|
93
|
+
|
|
94
|
+
[](https://github.com/KuvaSpace/kuva-data-processing/actions/workflows/test-kuva-reader.yml)
|
|
@@ -4,20 +4,20 @@ Observation (EO) products. The module handles the reading and parsing of image
|
|
|
4
4
|
data, as well as extracting and structuring the associated metadata to
|
|
5
5
|
facilitate further analysis or visualization.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Key Features
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
various
|
|
11
|
-
-
|
|
9
|
+
- Open EO Products: Load satellite images and corresponding metadata from
|
|
10
|
+
various dataformats.
|
|
11
|
+
- Access Metadata: Retrieve information such as acquisition time, satellite
|
|
12
12
|
name, sensor type, geospatial coordinates, and any custom metadata embedded
|
|
13
13
|
within the product.
|
|
14
|
-
-
|
|
14
|
+
- Image Handling: Manage the loading of image data for efficient use in
|
|
15
15
|
analytical processes.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
-
|
|
17
|
+
Dependencies
|
|
18
|
+
- kuva-metadata: A specialized library that handles the extraction and
|
|
19
19
|
parsing of metadata associated with Kuva Space products.
|
|
20
|
-
-
|
|
20
|
+
- xarray: Used for loading image data as arrays with extra functionality,
|
|
21
21
|
including labeled coordinates and metadata, which is useful for analysis and
|
|
22
22
|
visualization.
|
|
23
23
|
"""
|
|
@@ -32,6 +32,7 @@ from .reader.image import (
|
|
|
32
32
|
from .reader.level0 import Level0Product
|
|
33
33
|
from .reader.level1 import Level1ABProduct, Level1CProduct
|
|
34
34
|
from .reader.level2 import Level2AProduct
|
|
35
|
+
from .reader.read import read_product
|
|
35
36
|
|
|
36
37
|
__all__ = [
|
|
37
38
|
"Level0Product",
|
|
@@ -41,4 +42,5 @@ __all__ = [
|
|
|
41
42
|
"image_to_dtype_range",
|
|
42
43
|
"image_to_original_range",
|
|
43
44
|
"image_to_uint16_range",
|
|
45
|
+
"read_product",
|
|
44
46
|
]
|
|
@@ -101,6 +101,18 @@ class Level0Product(ProductBase[MetadataLevel0]):
|
|
|
101
101
|
self.data_tags[camera]["data_offset"] = offset
|
|
102
102
|
self.data_tags[camera]["data_scale"] = scale
|
|
103
103
|
|
|
104
|
+
def __repr__(self):
|
|
105
|
+
"""Pretty printing of the object with the most important info"""
|
|
106
|
+
if self.images is not None and len(self.images):
|
|
107
|
+
return (
|
|
108
|
+
f"{self.__class__.__name__}"
|
|
109
|
+
f"with {len(self.images)} frames of shape {self.images[0].shape} "
|
|
110
|
+
f"and CRS '{self.images[0].rio.crs}'. "
|
|
111
|
+
f"Loaded from: '{self.image_path}'."
|
|
112
|
+
)
|
|
113
|
+
else:
|
|
114
|
+
return f"{self.__class__.__name__} loaded from '{self.image_path}'."
|
|
115
|
+
|
|
104
116
|
def __getitem__(self, camera: str) -> xarray.DataArray:
|
|
105
117
|
"""Return the datarray for the chosen camera."""
|
|
106
118
|
return self.images[camera]
|
|
@@ -91,7 +91,6 @@ class Level1ABProduct(ProductBase[MetadataLevel1AB]):
|
|
|
91
91
|
self, camera: str | None = None, per_band: bool = False
|
|
92
92
|
) -> xarray.Dataset:
|
|
93
93
|
"""Get the bad pixel mask associated to each camera of the L0 product
|
|
94
|
-
|
|
95
94
|
Returns
|
|
96
95
|
-------
|
|
97
96
|
The bad pixel masks of the cameras
|
|
@@ -107,6 +106,16 @@ class Level1ABProduct(ProductBase[MetadataLevel1AB]):
|
|
|
107
106
|
|
|
108
107
|
return self._read_array(self.image_path / bad_pixel_filename)
|
|
109
108
|
|
|
109
|
+
def release_memory(self):
|
|
110
|
+
"""Explicitely releases the memory of the `image` variable.
|
|
111
|
+
|
|
112
|
+
NOTE: this function is implemented because of a memory leak inside the Rioxarray
|
|
113
|
+
library that doesn't release memory properly. Only use it when the image data is
|
|
114
|
+
not needed anymore.
|
|
115
|
+
"""
|
|
116
|
+
del self.image
|
|
117
|
+
self.image = None
|
|
118
|
+
|
|
110
119
|
|
|
111
120
|
class Level1CProduct(ProductBase[MetadataLevel1C]):
|
|
112
121
|
"""
|
|
@@ -151,6 +160,20 @@ class Level1CProduct(ProductBase[MetadataLevel1C]):
|
|
|
151
160
|
rx.open_rasterio(self.image_path / "L1C.tif"),
|
|
152
161
|
)
|
|
153
162
|
self.data_tags = self.image.attrs
|
|
163
|
+
self.wavelengths = [
|
|
164
|
+
b.wavelength.to("nm").magnitude for b in self.metadata.image.bands
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
def __repr__(self):
|
|
168
|
+
"""Pretty printing of the object with the most important info"""
|
|
169
|
+
if self.image is not None:
|
|
170
|
+
return (
|
|
171
|
+
f"{self.__class__.__name__} with shape {self.image.shape} "
|
|
172
|
+
f"and wavelengths {self.wavelengths} (CRS: '{self.image.rio.crs}'). "
|
|
173
|
+
f"Loaded from: '{self.image_path}'."
|
|
174
|
+
)
|
|
175
|
+
else:
|
|
176
|
+
return f"{self.__class__.__name__} loaded from '{self.image_path}'"
|
|
154
177
|
|
|
155
178
|
def _get_data_from_sidecar(
|
|
156
179
|
self, sidecar_path: Path, target_ureg: UnitRegistry | None = None
|
|
@@ -182,6 +205,16 @@ class Level1CProduct(ProductBase[MetadataLevel1C]):
|
|
|
182
205
|
|
|
183
206
|
return metadata
|
|
184
207
|
|
|
208
|
+
def release_memory(self):
|
|
209
|
+
"""Explicitely releases the memory of the `image` variable.
|
|
210
|
+
|
|
211
|
+
NOTE: this function is implemented because of a memory leak inside the Rioxarray
|
|
212
|
+
library that doesn't release memory properly. Only use it when the image data is
|
|
213
|
+
not needed anymore.
|
|
214
|
+
"""
|
|
215
|
+
del self.image
|
|
216
|
+
self.image = None
|
|
217
|
+
|
|
185
218
|
|
|
186
219
|
def generate_level_1_metafile():
|
|
187
220
|
"""Example function for reading a product and generating a metadata file from the
|
|
@@ -52,6 +52,20 @@ class Level2AProduct(ProductBase[MetadataLevel2A]):
|
|
|
52
52
|
rx.open_rasterio(self.image_path / "L2A.tif"),
|
|
53
53
|
)
|
|
54
54
|
self.data_tags = self.image.attrs
|
|
55
|
+
self.wavelengths = [
|
|
56
|
+
b.wavelength.to("nm").magnitude for b in self.metadata.image.bands
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
def __repr__(self):
|
|
60
|
+
"""Pretty printing of the object with the most important info"""
|
|
61
|
+
if self.image is not None:
|
|
62
|
+
return (
|
|
63
|
+
f"{self.__class__.__name__} with shape {self.image.shape} "
|
|
64
|
+
f"and wavelengths {self.wavelengths} (CRS: '{self.image.rio.crs}'). "
|
|
65
|
+
f"Loaded from: '{self.image_path}'."
|
|
66
|
+
)
|
|
67
|
+
else:
|
|
68
|
+
return f"{self.__class__.__name__} loaded from '{self.image_path}'"
|
|
55
69
|
|
|
56
70
|
def _get_data_from_sidecar(
|
|
57
71
|
self, sidecar_path: Path, target_ureg: UnitRegistry | None = None
|
|
@@ -83,6 +97,16 @@ class Level2AProduct(ProductBase[MetadataLevel2A]):
|
|
|
83
97
|
|
|
84
98
|
return metadata
|
|
85
99
|
|
|
100
|
+
def release_memory(self):
|
|
101
|
+
"""Explicitely releases the memory of the `image` variable.
|
|
102
|
+
|
|
103
|
+
NOTE: this function is implemented because of a memory leak inside the Rioxarray
|
|
104
|
+
library that doesn't release memory properly. Only use it when the image data is
|
|
105
|
+
not needed anymore.
|
|
106
|
+
"""
|
|
107
|
+
del self.image
|
|
108
|
+
self.image = None
|
|
109
|
+
|
|
86
110
|
|
|
87
111
|
def generate_level_2_metafile():
|
|
88
112
|
"""Example function for reading a product and generating a metadata file from the
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from kuva_reader import Level0Product, Level1ABProduct, Level1CProduct, Level2AProduct
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def read_product(
|
|
7
|
+
product_path: Path,
|
|
8
|
+
) -> Level0Product | Level1ABProduct | Level1CProduct | Level2AProduct:
|
|
9
|
+
"""Helper function for reading any product level based on folder name or TIF name.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
product_path
|
|
14
|
+
Path to the product to load
|
|
15
|
+
|
|
16
|
+
Returns
|
|
17
|
+
-------
|
|
18
|
+
The product of the correct processing level
|
|
19
|
+
|
|
20
|
+
Raises
|
|
21
|
+
------
|
|
22
|
+
ValueError
|
|
23
|
+
Folder not existing or files are renamed so that processing level isn't visible
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
product_map = {
|
|
27
|
+
"L0": Level0Product,
|
|
28
|
+
"L1AB": Level1ABProduct,
|
|
29
|
+
"L1C": Level1CProduct,
|
|
30
|
+
"L2A": Level2AProduct,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
product_path = Path(product_path) # Might be a string, typing not enforced
|
|
34
|
+
if not product_path.is_dir():
|
|
35
|
+
e_ = f"Given product path is not a folder: '{product_path}'"
|
|
36
|
+
raise ValueError(e_)
|
|
37
|
+
|
|
38
|
+
# First check if top level filepath matches
|
|
39
|
+
for product_level, product_class in product_map.items():
|
|
40
|
+
if product_level in product_path.name:
|
|
41
|
+
return product_class(product_path)
|
|
42
|
+
|
|
43
|
+
# In case folder is renamed, check if tif file product level matches.
|
|
44
|
+
# Folder should contain one 'LXX.tif' file.
|
|
45
|
+
for tif_path in product_path.glob("L*.tif"):
|
|
46
|
+
if tif_path.stem in product_map:
|
|
47
|
+
return product_map[tif_path.stem](product_path)
|
|
48
|
+
|
|
49
|
+
# Folder and filenames don't match expected format
|
|
50
|
+
e_ = (
|
|
51
|
+
f"Product folder '{product_path}' does not contain the processing level "
|
|
52
|
+
"information. Check that you have a correct folder or consider using the "
|
|
53
|
+
"correct reader (L0, L1AB, L1C, L2A)."
|
|
54
|
+
)
|
|
55
|
+
raise ValueError(e_)
|
|
@@ -4,9 +4,10 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "kuva-reader"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "1.0.0"
|
|
8
8
|
description = "Manipulate the Kuva Space image and metadata formats"
|
|
9
9
|
authors = ["Guillem Ballesteros <guillem@kuvaspace.com>" , "Lennert Antson <lennert.antson@kuvaspace.com>", "Arthur Vandenhoeke <arthur.vandenhoeke@kuvaspace.com>", "Olli Eloranta <olli.eloranta@kuvaspace.com>"]
|
|
10
|
+
readme = "README.md"
|
|
10
11
|
license = "MIT"
|
|
11
12
|
|
|
12
13
|
[tool.ruff]
|
|
@@ -25,23 +26,21 @@ make-l1-meta = "kuva_reader.reader.level1:generate_level_1_metafile"
|
|
|
25
26
|
python = ">=3.10,<=3.13"
|
|
26
27
|
numpy = "^1.26.4"
|
|
27
28
|
numpy-quaternion = "^2022.4.4"
|
|
28
|
-
dask = "^2023.12.1"
|
|
29
29
|
pint = "^0.22"
|
|
30
|
-
psycopg = "^3.2.3"
|
|
31
30
|
rasterio = "^1.4.1"
|
|
32
31
|
xarray = "^2022.12.0"
|
|
33
32
|
rioxarray = "^0.12.4"
|
|
34
|
-
kuva-geometry = "*"
|
|
35
|
-
kuva-metadata = "*"
|
|
33
|
+
# kuva-geometry = "*"
|
|
34
|
+
# kuva-metadata = "*"
|
|
36
35
|
|
|
37
36
|
# Temporarily can replace pypi version with relative dep if doing local development
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
[tool.poetry.dependencies.kuva-geometry]
|
|
38
|
+
path = "../kuva-geometry"
|
|
39
|
+
develop = true
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
[tool.poetry.dependencies.kuva-metadata]
|
|
42
|
+
path = "../kuva-metadata"
|
|
43
|
+
develop = true
|
|
45
44
|
|
|
46
45
|
|
|
47
46
|
[tool.ruff.lint]
|
kuva_reader-0.1.3/PKG-INFO
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: kuva-reader
|
|
3
|
-
Version: 0.1.3
|
|
4
|
-
Summary: Manipulate the Kuva Space image and metadata formats
|
|
5
|
-
License: MIT
|
|
6
|
-
Author: Guillem Ballesteros
|
|
7
|
-
Author-email: guillem@kuvaspace.com
|
|
8
|
-
Requires-Python: >=3.10,<=3.13
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
-
Requires-Dist: dask (>=2023.12.1,<2024.0.0)
|
|
16
|
-
Requires-Dist: kuva-geometry
|
|
17
|
-
Requires-Dist: kuva-metadata
|
|
18
|
-
Requires-Dist: numpy (>=1.26.4,<2.0.0)
|
|
19
|
-
Requires-Dist: numpy-quaternion (>=2022.4.4,<2023.0.0)
|
|
20
|
-
Requires-Dist: pint (>=0.22,<0.23)
|
|
21
|
-
Requires-Dist: psycopg (>=3.2.3,<4.0.0)
|
|
22
|
-
Requires-Dist: rasterio (>=1.4.1,<2.0.0)
|
|
23
|
-
Requires-Dist: rioxarray (>=0.12.4,<0.13.0)
|
|
24
|
-
Requires-Dist: xarray (>=2022.12.0,<2023.0.0)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|