rio-tiler 8.0.4__py3-none-any.whl → 9.0.0a1__py3-none-any.whl
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.
- rio_tiler/__init__.py +1 -1
- rio_tiler/colormap.py +6 -6
- rio_tiler/experimental/vsifile.py +1 -3
- rio_tiler/experimental/zarr.py +29 -28
- rio_tiler/expression.py +4 -4
- rio_tiler/io/base.py +222 -347
- rio_tiler/io/rasterio.py +89 -81
- rio_tiler/io/stac.py +50 -41
- rio_tiler/io/xarray.py +35 -27
- rio_tiler/models.py +70 -53
- rio_tiler/mosaic/backend.py +2 -2
- rio_tiler/mosaic/methods/base.py +3 -4
- rio_tiler/mosaic/methods/defaults.py +18 -19
- rio_tiler/mosaic/reader.py +20 -19
- rio_tiler/reader.py +44 -44
- rio_tiler/tasks.py +9 -8
- rio_tiler/types.py +20 -21
- rio_tiler/utils.py +33 -42
- {rio_tiler-8.0.4.dist-info → rio_tiler-9.0.0a1.dist-info}/METADATA +1 -1
- {rio_tiler-8.0.4.dist-info → rio_tiler-9.0.0a1.dist-info}/RECORD +23 -23
- {rio_tiler-8.0.4.dist-info → rio_tiler-9.0.0a1.dist-info}/WHEEL +0 -0
- {rio_tiler-8.0.4.dist-info → rio_tiler-9.0.0a1.dist-info}/licenses/AUTHORS.txt +0 -0
- {rio_tiler-8.0.4.dist-info → rio_tiler-9.0.0a1.dist-info}/licenses/LICENSE +0 -0
rio_tiler/mosaic/reader.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"""rio_tiler.mosaic: create tile from multiple assets."""
|
|
2
2
|
|
|
3
3
|
import warnings
|
|
4
|
+
from collections.abc import Callable, Sequence
|
|
4
5
|
from inspect import isclass
|
|
5
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, cast
|
|
6
7
|
|
|
7
8
|
import numpy
|
|
8
9
|
from rasterio.crs import CRS
|
|
@@ -26,12 +27,12 @@ def mosaic_reader( # noqa: C901
|
|
|
26
27
|
mosaic_assets: Sequence,
|
|
27
28
|
reader: Callable[..., ImageData],
|
|
28
29
|
*args: Any,
|
|
29
|
-
pixel_selection:
|
|
30
|
-
chunk_size:
|
|
30
|
+
pixel_selection: type[MosaicMethodBase] | MosaicMethodBase = FirstMethod,
|
|
31
|
+
chunk_size: int | None = None,
|
|
31
32
|
threads: int = MAX_THREADS,
|
|
32
|
-
allowed_exceptions:
|
|
33
|
+
allowed_exceptions: tuple = (TileOutsideBounds,),
|
|
33
34
|
**kwargs,
|
|
34
|
-
) ->
|
|
35
|
+
) -> tuple[ImageData, list]:
|
|
35
36
|
"""Merge multiple assets.
|
|
36
37
|
|
|
37
38
|
Args:
|
|
@@ -65,7 +66,7 @@ def mosaic_reader( # noqa: C901
|
|
|
65
66
|
|
|
66
67
|
"""
|
|
67
68
|
if isclass(pixel_selection):
|
|
68
|
-
pixel_selection = cast(
|
|
69
|
+
pixel_selection = cast(type[MosaicMethodBase], pixel_selection)
|
|
69
70
|
|
|
70
71
|
if issubclass(pixel_selection, MosaicMethodBase):
|
|
71
72
|
pixel_selection = pixel_selection()
|
|
@@ -79,10 +80,10 @@ def mosaic_reader( # noqa: C901
|
|
|
79
80
|
if not chunk_size:
|
|
80
81
|
chunk_size = threads if threads > 1 else len(mosaic_assets)
|
|
81
82
|
|
|
82
|
-
assets_used:
|
|
83
|
-
crs:
|
|
84
|
-
bounds:
|
|
85
|
-
band_names:
|
|
83
|
+
assets_used: list = []
|
|
84
|
+
crs: CRS | None
|
|
85
|
+
bounds: BBox | None
|
|
86
|
+
band_names: list[str]
|
|
86
87
|
|
|
87
88
|
for chunks in _chunks(mosaic_assets, chunk_size):
|
|
88
89
|
tasks = create_tasks(reader, chunks, threads, *args, **kwargs)
|
|
@@ -171,12 +172,12 @@ def mosaic_point_reader(
|
|
|
171
172
|
mosaic_assets: Sequence,
|
|
172
173
|
reader: Callable[..., PointData],
|
|
173
174
|
*args: Any,
|
|
174
|
-
pixel_selection:
|
|
175
|
-
chunk_size:
|
|
175
|
+
pixel_selection: type[MosaicMethodBase] | MosaicMethodBase = FirstMethod,
|
|
176
|
+
chunk_size: int | None = None,
|
|
176
177
|
threads: int = MAX_THREADS,
|
|
177
|
-
allowed_exceptions:
|
|
178
|
+
allowed_exceptions: tuple = (PointOutsideBounds,),
|
|
178
179
|
**kwargs,
|
|
179
|
-
) ->
|
|
180
|
+
) -> tuple[PointData, list]:
|
|
180
181
|
"""Merge multiple assets.
|
|
181
182
|
|
|
182
183
|
Args:
|
|
@@ -202,7 +203,7 @@ def mosaic_point_reader(
|
|
|
202
203
|
|
|
203
204
|
"""
|
|
204
205
|
if isclass(pixel_selection):
|
|
205
|
-
pixel_selection = cast(
|
|
206
|
+
pixel_selection = cast(type[MosaicMethodBase], pixel_selection)
|
|
206
207
|
|
|
207
208
|
if issubclass(pixel_selection, MosaicMethodBase):
|
|
208
209
|
pixel_selection = pixel_selection()
|
|
@@ -216,10 +217,10 @@ def mosaic_point_reader(
|
|
|
216
217
|
if not chunk_size:
|
|
217
218
|
chunk_size = threads if threads > 1 else len(mosaic_assets)
|
|
218
219
|
|
|
219
|
-
assets_used:
|
|
220
|
-
crs:
|
|
221
|
-
coordinates:
|
|
222
|
-
band_names:
|
|
220
|
+
assets_used: list = []
|
|
221
|
+
crs: CRS | None
|
|
222
|
+
coordinates: tuple[float, float] | None
|
|
223
|
+
band_names: list[str]
|
|
223
224
|
|
|
224
225
|
for chunks in _chunks(mosaic_assets, chunk_size):
|
|
225
226
|
tasks = create_tasks(reader, chunks, threads, *args, **kwargs)
|
rio_tiler/reader.py
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import contextlib
|
|
4
4
|
import math
|
|
5
5
|
import warnings
|
|
6
|
-
from
|
|
6
|
+
from collections.abc import Callable
|
|
7
|
+
from typing import TypedDict, cast
|
|
7
8
|
|
|
8
9
|
import numpy
|
|
9
10
|
from affine import Affine
|
|
@@ -34,12 +35,12 @@ from rio_tiler.utils import (
|
|
|
34
35
|
class Options(TypedDict, total=False):
|
|
35
36
|
"""Reader Options."""
|
|
36
37
|
|
|
37
|
-
nodata:
|
|
38
|
-
vrt_options:
|
|
39
|
-
resampling_method:
|
|
40
|
-
reproject_method:
|
|
41
|
-
unscale:
|
|
42
|
-
post_process:
|
|
38
|
+
nodata: NoData | None
|
|
39
|
+
vrt_options: dict | None
|
|
40
|
+
resampling_method: RIOResampling | None
|
|
41
|
+
reproject_method: WarpResampling | None
|
|
42
|
+
unscale: bool | None
|
|
43
|
+
post_process: Callable[[numpy.ma.MaskedArray], numpy.ma.MaskedArray] | None
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
def _apply_buffer(
|
|
@@ -47,7 +48,7 @@ def _apply_buffer(
|
|
|
47
48
|
bounds: BBox,
|
|
48
49
|
height: int,
|
|
49
50
|
width: int,
|
|
50
|
-
) ->
|
|
51
|
+
) -> tuple[BBox, int, int]:
|
|
51
52
|
"""Apply buffer on bounds."""
|
|
52
53
|
x_res = (bounds[2] - bounds[0]) / width
|
|
53
54
|
y_res = (bounds[3] - bounds[1]) / height
|
|
@@ -68,20 +69,20 @@ def _apply_buffer(
|
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
def read(
|
|
71
|
-
src_dst:
|
|
72
|
-
dst_crs:
|
|
73
|
-
height:
|
|
74
|
-
width:
|
|
75
|
-
max_size:
|
|
76
|
-
indexes:
|
|
77
|
-
window:
|
|
78
|
-
nodata:
|
|
79
|
-
vrt_options:
|
|
80
|
-
out_dtype:
|
|
72
|
+
src_dst: DatasetReader | DatasetWriter | WarpedVRT,
|
|
73
|
+
dst_crs: CRS | None = None,
|
|
74
|
+
height: int | None = None,
|
|
75
|
+
width: int | None = None,
|
|
76
|
+
max_size: int | None = None,
|
|
77
|
+
indexes: Indexes | None = None,
|
|
78
|
+
window: windows.Window | None = None,
|
|
79
|
+
nodata: NoData | None = None,
|
|
80
|
+
vrt_options: dict | None = None,
|
|
81
|
+
out_dtype: str | numpy.dtype | None = None,
|
|
81
82
|
resampling_method: RIOResampling = "nearest",
|
|
82
83
|
reproject_method: WarpResampling = "nearest",
|
|
83
84
|
unscale: bool = False,
|
|
84
|
-
post_process:
|
|
85
|
+
post_process: Callable[[numpy.ma.MaskedArray], numpy.ma.MaskedArray] | None = None,
|
|
85
86
|
) -> ImageData:
|
|
86
87
|
"""Low level read function.
|
|
87
88
|
|
|
@@ -297,8 +298,9 @@ def read(
|
|
|
297
298
|
data,
|
|
298
299
|
bounds=out_bounds,
|
|
299
300
|
crs=dataset.crs,
|
|
300
|
-
|
|
301
|
-
|
|
301
|
+
band_descriptions=[
|
|
302
|
+
dataset.descriptions[ix - 1] or f"b{idx}" for idx in indexes
|
|
303
|
+
],
|
|
302
304
|
dataset_statistics=dataset_statistics,
|
|
303
305
|
metadata=dataset.tags(),
|
|
304
306
|
nodata=nodata,
|
|
@@ -309,25 +311,25 @@ def read(
|
|
|
309
311
|
|
|
310
312
|
# flake8: noqa: C901
|
|
311
313
|
def part(
|
|
312
|
-
src_dst:
|
|
314
|
+
src_dst: DatasetReader | DatasetWriter | WarpedVRT,
|
|
313
315
|
bounds: BBox,
|
|
314
|
-
height:
|
|
315
|
-
width:
|
|
316
|
-
max_size:
|
|
317
|
-
dst_crs:
|
|
318
|
-
bounds_crs:
|
|
319
|
-
indexes:
|
|
320
|
-
minimum_overlap:
|
|
321
|
-
padding:
|
|
322
|
-
buffer:
|
|
323
|
-
nodata:
|
|
324
|
-
vrt_options:
|
|
325
|
-
out_dtype:
|
|
316
|
+
height: int | None = None,
|
|
317
|
+
width: int | None = None,
|
|
318
|
+
max_size: int | None = None,
|
|
319
|
+
dst_crs: CRS | None = None,
|
|
320
|
+
bounds_crs: CRS | None = None,
|
|
321
|
+
indexes: Indexes | None = None,
|
|
322
|
+
minimum_overlap: float | None = None,
|
|
323
|
+
padding: int | None = None,
|
|
324
|
+
buffer: float | None = None,
|
|
325
|
+
nodata: NoData | None = None,
|
|
326
|
+
vrt_options: dict | None = None,
|
|
327
|
+
out_dtype: str | numpy.dtype | None = None,
|
|
326
328
|
align_bounds_with_dataset: bool = False,
|
|
327
329
|
resampling_method: RIOResampling = "nearest",
|
|
328
330
|
reproject_method: WarpResampling = "nearest",
|
|
329
331
|
unscale: bool = False,
|
|
330
|
-
post_process:
|
|
332
|
+
post_process: Callable[[numpy.ma.MaskedArray], numpy.ma.MaskedArray] | None = None,
|
|
331
333
|
) -> ImageData:
|
|
332
334
|
"""Read part of a dataset.
|
|
333
335
|
|
|
@@ -508,7 +510,6 @@ def part(
|
|
|
508
510
|
img.array[:, padding:-padding, padding:-padding],
|
|
509
511
|
bounds=bounds,
|
|
510
512
|
crs=img.crs,
|
|
511
|
-
band_names=img.band_names,
|
|
512
513
|
band_descriptions=img.band_descriptions,
|
|
513
514
|
nodata=img.nodata,
|
|
514
515
|
scales=img.scales,
|
|
@@ -533,18 +534,18 @@ def part(
|
|
|
533
534
|
|
|
534
535
|
|
|
535
536
|
def point(
|
|
536
|
-
src_dst:
|
|
537
|
-
coordinates:
|
|
538
|
-
indexes:
|
|
537
|
+
src_dst: DatasetReader | DatasetWriter | WarpedVRT,
|
|
538
|
+
coordinates: tuple[float, float],
|
|
539
|
+
indexes: Indexes | None = None,
|
|
539
540
|
coord_crs: CRS = WGS84_CRS,
|
|
540
|
-
nodata:
|
|
541
|
-
vrt_options:
|
|
542
|
-
out_dtype:
|
|
541
|
+
nodata: NoData | None = None,
|
|
542
|
+
vrt_options: dict | None = None,
|
|
543
|
+
out_dtype: str | numpy.dtype | None = None,
|
|
543
544
|
resampling_method: RIOResampling = "nearest",
|
|
544
545
|
reproject_method: WarpResampling = "nearest",
|
|
545
546
|
interpolate: bool = False,
|
|
546
547
|
unscale: bool = False,
|
|
547
|
-
post_process:
|
|
548
|
+
post_process: Callable[[numpy.ma.MaskedArray], numpy.ma.MaskedArray] | None = None,
|
|
548
549
|
) -> PointData:
|
|
549
550
|
"""Read a pixel value for a point.
|
|
550
551
|
|
|
@@ -648,7 +649,6 @@ def point(
|
|
|
648
649
|
|
|
649
650
|
return PointData(
|
|
650
651
|
img.array[:, 0, 0],
|
|
651
|
-
band_names=img.band_names,
|
|
652
652
|
band_descriptions=img.band_descriptions,
|
|
653
653
|
coordinates=coordinates,
|
|
654
654
|
crs=coord_crs,
|
rio_tiler/tasks.py
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
"""rio_tiler.tasks: tools for handling rio-tiler's future tasks."""
|
|
2
2
|
|
|
3
|
+
from collections.abc import Callable, Generator, Sequence
|
|
3
4
|
from concurrent import futures
|
|
4
5
|
from functools import partial
|
|
5
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
6
7
|
|
|
7
8
|
from rio_tiler.constants import MAX_THREADS
|
|
8
9
|
from rio_tiler.logger import logger
|
|
9
10
|
from rio_tiler.models import ImageData, PointData
|
|
10
11
|
|
|
11
|
-
TaskType = Sequence[
|
|
12
|
+
TaskType = Sequence[tuple[futures.Future | Callable, Any]]
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
def filter_tasks(
|
|
15
16
|
tasks: TaskType,
|
|
16
|
-
allowed_exceptions:
|
|
17
|
+
allowed_exceptions: tuple | None = None,
|
|
17
18
|
) -> Generator:
|
|
18
19
|
"""Filter Tasks to remove Exceptions.
|
|
19
20
|
|
|
@@ -60,7 +61,7 @@ def multi_arrays(
|
|
|
60
61
|
reader: Callable[..., ImageData],
|
|
61
62
|
*args: Any,
|
|
62
63
|
threads: int = MAX_THREADS,
|
|
63
|
-
allowed_exceptions:
|
|
64
|
+
allowed_exceptions: tuple | None = None,
|
|
64
65
|
**kwargs: Any,
|
|
65
66
|
) -> ImageData:
|
|
66
67
|
"""Merge arrays returned from tasks."""
|
|
@@ -75,7 +76,7 @@ def multi_points(
|
|
|
75
76
|
reader: Callable[..., PointData],
|
|
76
77
|
*args: Any,
|
|
77
78
|
threads: int = MAX_THREADS,
|
|
78
|
-
allowed_exceptions:
|
|
79
|
+
allowed_exceptions: tuple | None = None,
|
|
79
80
|
**kwargs: Any,
|
|
80
81
|
) -> PointData:
|
|
81
82
|
"""Merge points returned from tasks."""
|
|
@@ -90,9 +91,9 @@ def multi_values(
|
|
|
90
91
|
reader: Callable,
|
|
91
92
|
*args: Any,
|
|
92
93
|
threads: int = MAX_THREADS,
|
|
93
|
-
allowed_exceptions:
|
|
94
|
+
allowed_exceptions: tuple | None = None,
|
|
94
95
|
**kwargs: Any,
|
|
95
|
-
) ->
|
|
96
|
+
) -> dict:
|
|
96
97
|
"""Merge values returned from tasks."""
|
|
97
98
|
tasks = create_tasks(reader, asset_list, threads, *args, **kwargs)
|
|
98
99
|
return {
|
|
@@ -106,7 +107,7 @@ def multi_values_list(
|
|
|
106
107
|
reader: Callable,
|
|
107
108
|
*args: Any,
|
|
108
109
|
threads: int = MAX_THREADS,
|
|
109
|
-
allowed_exceptions:
|
|
110
|
+
allowed_exceptions: tuple | None = None,
|
|
110
111
|
**kwargs: Any,
|
|
111
112
|
) -> list[tuple[Any, Any]]:
|
|
112
113
|
"""Merge values returned from tasks."""
|
rio_tiler/types.py
CHANGED
|
@@ -1,34 +1,31 @@
|
|
|
1
1
|
"""rio-tiler types."""
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import Any, Literal, NotRequired, TypedDict
|
|
4
5
|
|
|
5
6
|
import numpy
|
|
6
7
|
|
|
7
|
-
NumType =
|
|
8
|
+
NumType = float | int
|
|
8
9
|
|
|
9
|
-
BBox =
|
|
10
|
-
NoData =
|
|
11
|
-
Indexes =
|
|
10
|
+
BBox = tuple[float, float, float, float]
|
|
11
|
+
NoData = float | int | str
|
|
12
|
+
Indexes = Sequence[int] | int
|
|
12
13
|
|
|
13
|
-
DataMaskType =
|
|
14
|
+
DataMaskType = tuple[numpy.ndarray, numpy.ndarray]
|
|
14
15
|
|
|
15
|
-
ColorTuple =
|
|
16
|
-
IntervalTuple =
|
|
16
|
+
ColorTuple = tuple[int, int, int, int] # (red, green, blue, alpha)
|
|
17
|
+
IntervalTuple = tuple[NumType, NumType] # (0, 100)
|
|
17
18
|
|
|
18
19
|
# ColorMap Dict: {1: (0, 0, 0, 255), ...}
|
|
19
|
-
GDALColorMapType =
|
|
20
|
+
GDALColorMapType = dict[int, ColorTuple]
|
|
20
21
|
|
|
21
22
|
# Discrete Colormap, like GDALColorMapType but accept Float: {0.1: (0, 0, 0, 255), ...}
|
|
22
|
-
DiscreteColorMapType =
|
|
23
|
+
DiscreteColorMapType = dict[NumType, ColorTuple]
|
|
23
24
|
|
|
24
25
|
# Intervals ColorMap: [((0, 1), (0, 0, 0, 0)), ...]
|
|
25
|
-
IntervalColorMapType = Sequence[
|
|
26
|
+
IntervalColorMapType = Sequence[tuple[IntervalTuple, ColorTuple]]
|
|
26
27
|
|
|
27
|
-
ColorMapType =
|
|
28
|
-
GDALColorMapType,
|
|
29
|
-
DiscreteColorMapType,
|
|
30
|
-
IntervalColorMapType,
|
|
31
|
-
]
|
|
28
|
+
ColorMapType = GDALColorMapType | DiscreteColorMapType | IntervalColorMapType
|
|
32
29
|
|
|
33
30
|
# RasterIO() resampling method.
|
|
34
31
|
# ref: https://gdal.org/api/raster_c_api.html#_CPPv418GDALRIOResampleAlg
|
|
@@ -64,11 +61,13 @@ WarpResampling = Literal[
|
|
|
64
61
|
]
|
|
65
62
|
|
|
66
63
|
|
|
67
|
-
class AssetInfo(TypedDict
|
|
64
|
+
class AssetInfo(TypedDict):
|
|
68
65
|
"""Asset Reader Options."""
|
|
69
66
|
|
|
70
67
|
url: Any
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
name: str
|
|
69
|
+
media_type: str | None
|
|
70
|
+
method_options: dict
|
|
71
|
+
env: NotRequired[dict]
|
|
72
|
+
metadata: NotRequired[dict]
|
|
73
|
+
dataset_statistics: NotRequired[Sequence[tuple[float, float]]]
|
rio_tiler/utils.py
CHANGED
|
@@ -3,18 +3,9 @@
|
|
|
3
3
|
import math
|
|
4
4
|
import time
|
|
5
5
|
import warnings
|
|
6
|
+
from collections.abc import Callable, Generator
|
|
6
7
|
from io import BytesIO
|
|
7
|
-
from typing import
|
|
8
|
-
Any,
|
|
9
|
-
Callable,
|
|
10
|
-
Dict,
|
|
11
|
-
Generator,
|
|
12
|
-
List,
|
|
13
|
-
Optional,
|
|
14
|
-
Sequence,
|
|
15
|
-
Tuple,
|
|
16
|
-
Union,
|
|
17
|
-
)
|
|
8
|
+
from typing import Any, Sequence
|
|
18
9
|
|
|
19
10
|
import numpy
|
|
20
11
|
import rasterio
|
|
@@ -44,7 +35,7 @@ def _chunks(my_list: Sequence, chuck_size: int) -> Generator[Sequence, None, Non
|
|
|
44
35
|
yield my_list[i : i + chuck_size]
|
|
45
36
|
|
|
46
37
|
|
|
47
|
-
def _get_width_height(max_size, dataset_height, dataset_width) ->
|
|
38
|
+
def _get_width_height(max_size, dataset_height, dataset_width) -> tuple[int, int]:
|
|
48
39
|
"""Get Output Width/Height based on a max_size and dataset shape."""
|
|
49
40
|
if max(dataset_height, dataset_width) < max_size:
|
|
50
41
|
return dataset_height, dataset_width
|
|
@@ -60,7 +51,7 @@ def _get_width_height(max_size, dataset_height, dataset_width) -> Tuple[int, int
|
|
|
60
51
|
return height, width
|
|
61
52
|
|
|
62
53
|
|
|
63
|
-
def _missing_size(w:
|
|
54
|
+
def _missing_size(w: int | None = None, h: int | None = None):
|
|
64
55
|
"""Check if one and only one size (width, height) is valid."""
|
|
65
56
|
iterator = iter([w, h])
|
|
66
57
|
return any(iterator) and not any(iterator)
|
|
@@ -90,11 +81,11 @@ def _weighted_stdev(
|
|
|
90
81
|
def get_array_statistics(
|
|
91
82
|
data: numpy.ma.MaskedArray,
|
|
92
83
|
categorical: bool = False,
|
|
93
|
-
categories:
|
|
94
|
-
percentiles:
|
|
95
|
-
coverage:
|
|
84
|
+
categories: list[float] | None = None,
|
|
85
|
+
percentiles: list[int] | None = None,
|
|
86
|
+
coverage: NDArray[numpy.floating] | None = None,
|
|
96
87
|
**kwargs: Any,
|
|
97
|
-
) ->
|
|
88
|
+
) -> list[dict[Any, Any]]:
|
|
98
89
|
"""Calculate per band array statistics.
|
|
99
90
|
|
|
100
91
|
Args:
|
|
@@ -141,7 +132,7 @@ def get_array_statistics(
|
|
|
141
132
|
if len(data.shape) < 3:
|
|
142
133
|
data = numpy.ma.expand_dims(data, axis=0) # type: ignore [assignment]
|
|
143
134
|
|
|
144
|
-
output:
|
|
135
|
+
output: list[dict[Any, Any]] = []
|
|
145
136
|
percentiles_names = [f"percentile_{int(p)}" for p in percentiles]
|
|
146
137
|
|
|
147
138
|
if coverage is not None:
|
|
@@ -274,7 +265,7 @@ def _round_window(window: windows.Window) -> windows.Window:
|
|
|
274
265
|
|
|
275
266
|
|
|
276
267
|
def get_overview_level(
|
|
277
|
-
src_dst:
|
|
268
|
+
src_dst: DatasetReader | DatasetWriter | WarpedVRT,
|
|
278
269
|
bounds: BBox,
|
|
279
270
|
height: int,
|
|
280
271
|
width: int,
|
|
@@ -327,14 +318,14 @@ def get_overview_level(
|
|
|
327
318
|
|
|
328
319
|
|
|
329
320
|
def get_vrt_transform(
|
|
330
|
-
src_dst:
|
|
321
|
+
src_dst: DatasetReader | DatasetWriter | WarpedVRT,
|
|
331
322
|
bounds: BBox,
|
|
332
|
-
height:
|
|
333
|
-
width:
|
|
323
|
+
height: int | None = None,
|
|
324
|
+
width: int | None = None,
|
|
334
325
|
dst_crs: CRS = WEB_MERCATOR_CRS,
|
|
335
326
|
window_precision: int = 6,
|
|
336
327
|
align_bounds_with_dataset: bool = False,
|
|
337
|
-
) ->
|
|
328
|
+
) -> tuple[Affine, int, int]:
|
|
338
329
|
"""Calculate VRT transform.
|
|
339
330
|
|
|
340
331
|
Args:
|
|
@@ -468,7 +459,7 @@ def get_vrt_transform(
|
|
|
468
459
|
return vrt_transform, vrt_width, vrt_height
|
|
469
460
|
|
|
470
461
|
|
|
471
|
-
def has_alpha_band(src_dst:
|
|
462
|
+
def has_alpha_band(src_dst: DatasetReader | DatasetWriter | WarpedVRT) -> bool:
|
|
472
463
|
"""Check for alpha band or mask in source."""
|
|
473
464
|
if (
|
|
474
465
|
any(MaskFlags.alpha in flags for flags in src_dst.mask_flag_enums)
|
|
@@ -478,7 +469,7 @@ def has_alpha_band(src_dst: Union[DatasetReader, DatasetWriter, WarpedVRT]) -> b
|
|
|
478
469
|
return False
|
|
479
470
|
|
|
480
471
|
|
|
481
|
-
def has_mask_band(src_dst:
|
|
472
|
+
def has_mask_band(src_dst: DatasetReader | DatasetWriter | WarpedVRT) -> bool:
|
|
482
473
|
"""Check for mask band in source."""
|
|
483
474
|
if any(
|
|
484
475
|
(MaskFlags.per_dataset in flags and MaskFlags.alpha not in flags)
|
|
@@ -488,7 +479,7 @@ def has_mask_band(src_dst: Union[DatasetReader, DatasetWriter, WarpedVRT]) -> bo
|
|
|
488
479
|
return False
|
|
489
480
|
|
|
490
481
|
|
|
491
|
-
def non_alpha_indexes(src_dst:
|
|
482
|
+
def non_alpha_indexes(src_dst: DatasetReader | DatasetWriter | WarpedVRT) -> tuple:
|
|
492
483
|
"""Return indexes of non-alpha bands."""
|
|
493
484
|
return tuple(
|
|
494
485
|
b
|
|
@@ -524,7 +515,7 @@ def linear_rescale(
|
|
|
524
515
|
|
|
525
516
|
|
|
526
517
|
def _requested_tile_aligned_with_internal_tile(
|
|
527
|
-
src_dst:
|
|
518
|
+
src_dst: DatasetReader | DatasetWriter | WarpedVRT,
|
|
528
519
|
bounds: BBox,
|
|
529
520
|
bounds_crs: CRS = WEB_MERCATOR_CRS,
|
|
530
521
|
) -> bool:
|
|
@@ -553,9 +544,9 @@ def _requested_tile_aligned_with_internal_tile(
|
|
|
553
544
|
|
|
554
545
|
def render(
|
|
555
546
|
data: numpy.ndarray,
|
|
556
|
-
mask:
|
|
547
|
+
mask: numpy.ndarray | None = None,
|
|
557
548
|
img_format: str = "PNG",
|
|
558
|
-
colormap:
|
|
549
|
+
colormap: ColorMapType | None = None,
|
|
559
550
|
**creation_options: Any,
|
|
560
551
|
) -> bytes:
|
|
561
552
|
"""Translate numpy.ndarray to image bytes.
|
|
@@ -705,10 +696,10 @@ def pansharpening_brovey(
|
|
|
705
696
|
|
|
706
697
|
|
|
707
698
|
def _convert_to_raster_space(
|
|
708
|
-
src_dst:
|
|
709
|
-
poly_coordinates:
|
|
710
|
-
op:
|
|
711
|
-
) ->
|
|
699
|
+
src_dst: DatasetReader | DatasetWriter | WarpedVRT,
|
|
700
|
+
poly_coordinates: list,
|
|
701
|
+
op: Callable[[float], Any] | None = None,
|
|
702
|
+
) -> list[str]:
|
|
712
703
|
# NOTE: we could remove this once we have rasterio >= 1.4.2
|
|
713
704
|
op = op or numpy.floor
|
|
714
705
|
polygons = []
|
|
@@ -722,10 +713,10 @@ def _convert_to_raster_space(
|
|
|
722
713
|
|
|
723
714
|
|
|
724
715
|
def create_cutline(
|
|
725
|
-
src_dst:
|
|
726
|
-
geometry:
|
|
716
|
+
src_dst: DatasetReader | DatasetWriter | WarpedVRT,
|
|
717
|
+
geometry: dict,
|
|
727
718
|
geometry_crs: CRS = None,
|
|
728
|
-
op:
|
|
719
|
+
op: Callable[[float], Any] | None = None,
|
|
729
720
|
) -> str:
|
|
730
721
|
"""
|
|
731
722
|
Create WKT Polygon Cutline for GDALWarpOptions.
|
|
@@ -807,7 +798,7 @@ def resize_array(
|
|
|
807
798
|
resampling_method: RIOResampling = "nearest",
|
|
808
799
|
) -> numpy.ndarray:
|
|
809
800
|
"""resize array to a given height and width."""
|
|
810
|
-
out_shape:
|
|
801
|
+
out_shape: int | tuple[int, int] | tuple[int, int, int]
|
|
811
802
|
if len(data.shape) == 2:
|
|
812
803
|
out_shape = (height, width)
|
|
813
804
|
else:
|
|
@@ -841,7 +832,7 @@ def normalize_bounds(bounds: BBox) -> BBox:
|
|
|
841
832
|
)
|
|
842
833
|
|
|
843
834
|
|
|
844
|
-
def _validate_shape_input(shape:
|
|
835
|
+
def _validate_shape_input(shape: dict) -> dict:
|
|
845
836
|
"""Ensure input shape is valid and reduce features to geometry"""
|
|
846
837
|
|
|
847
838
|
if "geometry" in shape:
|
|
@@ -853,7 +844,7 @@ def _validate_shape_input(shape: Dict) -> Dict:
|
|
|
853
844
|
return shape
|
|
854
845
|
|
|
855
846
|
|
|
856
|
-
def cast_to_sequence(val:
|
|
847
|
+
def cast_to_sequence(val: Any | None = None) -> Sequence:
|
|
857
848
|
"""Cast input to sequence if not Tuple of List."""
|
|
858
849
|
if val is not None and not isinstance(val, (list, tuple)):
|
|
859
850
|
val = (val,)
|
|
@@ -861,7 +852,7 @@ def cast_to_sequence(val: Optional[Any] = None) -> Sequence:
|
|
|
861
852
|
return val
|
|
862
853
|
|
|
863
854
|
|
|
864
|
-
def _CRS_authority_info(crs: CRS) ->
|
|
855
|
+
def _CRS_authority_info(crs: CRS) -> tuple[str, str, str] | None:
|
|
865
856
|
"""Convert CRS to URI.
|
|
866
857
|
|
|
867
858
|
Code adapted from https://github.com/developmentseed/morecantile/blob/1829fe12408e4a1feee7493308f3f02257ef4caf/morecantile/models.py#L148-L161
|
|
@@ -879,7 +870,7 @@ def _CRS_authority_info(crs: CRS) -> Optional[Tuple[str, str, str]]:
|
|
|
879
870
|
return None
|
|
880
871
|
|
|
881
872
|
|
|
882
|
-
def CRS_to_uri(crs: CRS) ->
|
|
873
|
+
def CRS_to_uri(crs: CRS) -> str | None:
|
|
883
874
|
"""Convert CRS to URI."""
|
|
884
875
|
if info := _CRS_authority_info(crs):
|
|
885
876
|
authority, version, code = info
|
|
@@ -889,7 +880,7 @@ def CRS_to_uri(crs: CRS) -> Optional[str]:
|
|
|
889
880
|
return None
|
|
890
881
|
|
|
891
882
|
|
|
892
|
-
def CRS_to_urn(crs: CRS) ->
|
|
883
|
+
def CRS_to_urn(crs: CRS) -> str | None:
|
|
893
884
|
"""Convert CRS to URN."""
|
|
894
885
|
if info := _CRS_authority_info(crs):
|
|
895
886
|
authority, version, code = info
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rio-tiler
|
|
3
|
-
Version:
|
|
3
|
+
Version: 9.0.0a1
|
|
4
4
|
Summary: User friendly Rasterio plugin to read raster datasets.
|
|
5
5
|
Project-URL: Homepage, https://cogeotiff.github.io/rio-tiler/
|
|
6
6
|
Project-URL: Documentation, https://cogeotiff.github.io/rio-tiler/
|