diff --git a/stubs/rasterio/@tests/stubtest_allowlist.txt b/stubs/rasterio/@tests/stubtest_allowlist.txt new file mode 100644 index 000000000000..c7d3d9998e40 --- /dev/null +++ b/stubs/rasterio/@tests/stubtest_allowlist.txt @@ -0,0 +1,11 @@ +rasterio\._typing +rasterio\._affine_types +rasterio\.features\.Geometry +rasterio\.merge\.MethodFunction + +rasterio\._base.* +rasterio\._io.* +rasterio\._env.* +rasterio\._err.* +rasterio\._features.* +rasterio\._transform.* diff --git a/stubs/rasterio/@tests/test_cases/check_crs.py b/stubs/rasterio/@tests/test_cases/check_crs.py new file mode 100644 index 000000000000..450f73736a5e --- /dev/null +++ b/stubs/rasterio/@tests/test_cases/check_crs.py @@ -0,0 +1,17 @@ +"""Verify `rasterio.crs.CRS` factory return types and arg validation.""" + +from __future__ import annotations + +from typing_extensions import assert_type + +from rasterio.crs import CRS + +# All factory staticmethods return `CRS`. +assert_type(CRS.from_epsg(4326), CRS) +assert_type(CRS.from_string("EPSG:4326"), CRS) +assert_type(CRS.from_wkt("..."), CRS) +assert_type(CRS.from_authority("EPSG", 4326), CRS) +assert_type(CRS.from_user_input(4326), CRS) + +# from_epsg expects int | str, not float. +CRS.from_epsg(4326.0) # type: ignore[arg-type] diff --git a/stubs/rasterio/@tests/test_cases/check_dataset.py b/stubs/rasterio/@tests/test_cases/check_dataset.py new file mode 100644 index 000000000000..712be030d4e7 --- /dev/null +++ b/stubs/rasterio/@tests/test_cases/check_dataset.py @@ -0,0 +1,28 @@ +"""Verify the inferred property types on a `DatasetReader`.""" + +from __future__ import annotations + +from typing import Any +from typing_extensions import assert_type + +from numpy.typing import NDArray +from rasterio.coords import BoundingBox +from rasterio.crs import CRS +from rasterio.io import DatasetReader +from rasterio.profiles import Profile + + +def check_props(reader: DatasetReader) -> None: + assert_type(reader.crs, CRS) + assert_type(reader.bounds, BoundingBox) + assert_type(reader.profile, Profile) + assert_type(reader.count, int) + assert_type(reader.width, int) + assert_type(reader.height, int) + assert_type(reader.shape, tuple[int, int]) + assert_type(reader.dtypes, tuple[str, ...]) + assert_type(reader.indexes, tuple[int, ...]) + assert_type(reader.nodata, float | None) + assert_type(reader.read(1), NDArray[Any]) + assert_type(reader.read_crs(), CRS | None) + assert_type(reader.tags(), dict[str, str]) diff --git a/stubs/rasterio/@tests/test_cases/check_open.py b/stubs/rasterio/@tests/test_cases/check_open.py new file mode 100644 index 000000000000..dba7cd7123d5 --- /dev/null +++ b/stubs/rasterio/@tests/test_cases/check_open.py @@ -0,0 +1,24 @@ +"""Verify `rasterio.open` overloads route to the right return type.""" + +from __future__ import annotations + +from typing_extensions import assert_type + +import rasterio +from rasterio.io import DatasetReader, DatasetWriter + +# Default mode is "r" → DatasetReader +assert_type(rasterio.open("foo.tif"), DatasetReader) +assert_type(rasterio.open("foo.tif", "r"), DatasetReader) + +# Write/update modes → DatasetWriter +assert_type(rasterio.open("foo.tif", "w", driver="GTiff"), DatasetWriter) +assert_type(rasterio.open("foo.tif", "r+"), DatasetWriter) +assert_type(rasterio.open("foo.tif", "w+"), DatasetWriter) + + +def check_opaque_mode(mode: str) -> None: + assert_type(rasterio.open("foo.tif", mode), DatasetReader | DatasetWriter) + + +rasterio.open(123) # type: ignore[call-overload] diff --git a/stubs/rasterio/@tests/test_cases/check_transform_geom.py b/stubs/rasterio/@tests/test_cases/check_transform_geom.py new file mode 100644 index 000000000000..c93dc592ced6 --- /dev/null +++ b/stubs/rasterio/@tests/test_cases/check_transform_geom.py @@ -0,0 +1,16 @@ +"""Verify the deprecated-overload routing on `rasterio.warp.transform_geom`.""" + +from __future__ import annotations + +from rasterio.crs import CRS +from rasterio.warp import transform_geom + +src = CRS.from_epsg(4326) +dst = CRS.from_epsg(3857) +geom: dict[str, object] = {"type": "Point", "coordinates": [0.0, 0.0]} + +transform_geom(src, dst, geom) +transform_geom(src, dst, geom, precision=2) + +transform_geom(src, dst, geom, antimeridian_cutting=True) # pyright: ignore[reportDeprecated] +transform_geom(src, dst, geom, antimeridian_offset=10.0) # pyright: ignore[reportDeprecated] diff --git a/stubs/rasterio/@tests/test_cases/check_windows.py b/stubs/rasterio/@tests/test_cases/check_windows.py new file mode 100644 index 000000000000..17374562f746 --- /dev/null +++ b/stubs/rasterio/@tests/test_cases/check_windows.py @@ -0,0 +1,22 @@ +"""Verify `rasterio.windows.Window` constructors and the from_bounds overload.""" + +from __future__ import annotations + +from typing_extensions import assert_type + +from rasterio.transform import from_origin +from rasterio.windows import Window, from_bounds + +# Constructors. +w = Window(0, 0, 10, 10) +assert_type(w, Window) +assert_type(Window.from_slices(slice(0, 5), slice(0, 5)), Window) +assert_type(w.intersection(w), Window) +assert_type(w.todict(), dict[str, float]) + +# from_bounds — modern overload (no deprecated kwargs). +t = from_origin(0.0, 0.0, 1.0, 1.0) +assert_type(from_bounds(0, 0, 1, 1, t), Window) + +# Negative widths are accepted at the type level; runtime validates. +assert_type(Window(0, 0, -1, -1), Window) diff --git a/stubs/rasterio/METADATA.toml b/stubs/rasterio/METADATA.toml new file mode 100644 index 000000000000..70670512707c --- /dev/null +++ b/stubs/rasterio/METADATA.toml @@ -0,0 +1,9 @@ +version = "1.5.*" +upstream-repository = "https://github.com/rasterio/rasterio" +requires-python = ">=3.12" +dependencies = ["numpy>=2", "click>=8"] +partial-stub = true + +[tool.stubtest] +ignore-missing-stub = true +stubtest-dependencies = ["rasterio==1.5.*"] diff --git a/stubs/rasterio/rasterio/__init__.pyi b/stubs/rasterio/rasterio/__init__.pyi new file mode 100644 index 000000000000..9f68a8618ceb --- /dev/null +++ b/stubs/rasterio/rasterio/__init__.pyi @@ -0,0 +1,130 @@ +import logging +import os +from collections.abc import Callable, Sequence +from typing import Any, Final, Literal, NamedTuple, TypeAlias, overload + +from numpy.typing import DTypeLike, NDArray +from rasterio._base import DatasetBase as DatasetBase +from rasterio._io import Statistics as Statistics +from rasterio._path import _parse_path as _parse_path, _UnparsedPath as _UnparsedPath +from rasterio._show_versions import show_versions as show_versions +from rasterio._typing import AnyDataset, CRSInput +from rasterio._version import ( + gdal_version as gdal_version, + get_geos_version as get_geos_version, + get_proj_version as get_proj_version, +) +from rasterio._vsiopener import _opener_registration as _opener_registration +from rasterio.crs import CRS as CRS +from rasterio.drivers import driver_from_extension as driver_from_extension, is_blacklisted as is_blacklisted +from rasterio.dtypes import ( + bool_ as bool_, + check_dtype as check_dtype, + complex_ as complex_, + complex_int16 as complex_int16, + float16 as float16, + float32 as float32, + float64 as float64, + int8 as int8, + int16 as int16, + int32 as int32, + int64 as int64, + sbyte as sbyte, + ubyte as ubyte, + uint8 as uint8, + uint16 as uint16, + uint32 as uint32, + uint64 as uint64, +) +from rasterio.env import Env as Env, ensure_env_with_credentials as ensure_env_with_credentials +from rasterio.errors import ( + DriverCapabilityError as DriverCapabilityError, + RasterioDeprecationWarning as RasterioDeprecationWarning, + RasterioIOError as RasterioIOError, +) +from rasterio.io import ( + BufferedDatasetWriter as BufferedDatasetWriter, + DatasetReader as DatasetReader, + DatasetWriter as DatasetWriter, + FilePath as FilePath, + MemoryFile as MemoryFile, + get_writer_for_driver as get_writer_for_driver, + get_writer_for_path as get_writer_for_path, +) +from rasterio.profiles import default_gtiff_profile as default_gtiff_profile +from rasterio.transform import Affine as Affine, guard_transform as guard_transform + +__all__ = ["CRS", "Band", "Env", "band", "open", "pad"] + +__version__: Final[str] +__gdal_version__: Final[str] +__proj_version__: Final[str] +__geos_version__: Final[str] + +have_vsi_plugin: Final[bool] +log: logging.Logger + +_Fp: TypeAlias = str | os.PathLike[str] | MemoryFile | FilePath + +@overload +def open( + fp: _Fp, + mode: Literal["r"] = "r", + driver: str | Sequence[str] | None = None, + width: int | None = None, + height: int | None = None, + count: int | None = None, + crs: CRSInput | None = None, + transform: Affine | None = None, + dtype: DTypeLike | None = None, + nodata: float | None = None, + sharing: bool = False, + thread_safe: bool = False, + opener: Callable[..., Any] | None = None, + **kwargs: Any, +) -> DatasetReader: ... +@overload +def open( + fp: _Fp, + mode: Literal["r+", "w", "w+"], + driver: str | Sequence[str] | None = None, + width: int | None = None, + height: int | None = None, + count: int | None = None, + crs: CRSInput | None = None, + transform: Affine | None = None, + dtype: DTypeLike | None = None, + nodata: float | None = None, + sharing: bool = False, + thread_safe: bool = False, + opener: Callable[..., Any] | None = None, + **kwargs: Any, +) -> DatasetWriter: ... +@overload +def open( + fp: _Fp, + mode: str = "r", + driver: str | Sequence[str] | None = None, + width: int | None = None, + height: int | None = None, + count: int | None = None, + crs: CRSInput | None = None, + transform: Affine | None = None, + dtype: DTypeLike | None = None, + nodata: float | None = None, + sharing: bool = False, + thread_safe: bool = False, + opener: Callable[..., Any] | None = None, + **kwargs: Any, +) -> DatasetReader | DatasetWriter: ... + +class Band(NamedTuple): + ds: AnyDataset + bidx: int | Sequence[int] + dtype: str + shape: tuple[int, ...] + +def band(ds: AnyDataset, bidx: int | Sequence[int]) -> Band: ... +def pad( + array: NDArray[Any], transform: Affine, pad_width: int, mode: str | Callable[..., Any] | None = None, **kwargs: Any +) -> tuple[NDArray[Any], Affine]: ... diff --git a/stubs/rasterio/rasterio/_affine_types.pyi b/stubs/rasterio/rasterio/_affine_types.pyi new file mode 100644 index 000000000000..bf462c70813f --- /dev/null +++ b/stubs/rasterio/rasterio/_affine_types.pyi @@ -0,0 +1,4 @@ +# Swap to `from affine import Affine as Affine` once affine ships `py.typed` (v3). +from typing import Any, TypeAlias + +Affine: TypeAlias = Any diff --git a/stubs/rasterio/rasterio/_base.pyi b/stubs/rasterio/rasterio/_base.pyi new file mode 100644 index 000000000000..b3a76d4e3cf2 --- /dev/null +++ b/stubs/rasterio/rasterio/_base.pyi @@ -0,0 +1,172 @@ +import logging +import os +from collections.abc import Iterable, Sequence +from types import TracebackType +from typing import Any, Final, Self +from typing_extensions import deprecated + +from rasterio._affine_types import Affine +from rasterio._path import _ParsedPath, _UnparsedPath +from rasterio._typing import Colormap, CRSInput +from rasterio.control import GroundControlPoint +from rasterio.coords import BoundingBox +from rasterio.crs import CRS +from rasterio.enums import ColorInterp, Compression, Interleaving, MaskFlags, PhotometricInterp +from rasterio.profiles import Profile +from rasterio.rpc import RPC +from rasterio.windows import Window + +log: Final[logging.Logger] + +def get_dataset_driver(path: str) -> str: ... +def driver_supports_mode(drivername: str, creation_mode: str) -> bool: ... +def driver_can_create(drivername: str) -> bool: ... +def driver_can_create_copy(drivername: str) -> bool: ... +def tastes_like_gdal(seq: Affine | Sequence[float]) -> bool: ... +def _raster_driver_extensions() -> dict[str, str]: ... +def _can_create_osr(crs: CRSInput) -> bool: ... +def _transform( + src_crs: CRSInput, dst_crs: CRSInput, xs: Sequence[float], ys: Sequence[float], zs: Sequence[float] | None +) -> tuple[list[float], list[float], list[float]]: ... + +class DatasetBase: + name: str + mode: str + options: dict[str, Any] + width: int + height: int + shape: tuple[int, int] + driver: str + + def __init__( + self, + path: str | os.PathLike[str] | _ParsedPath | _UnparsedPath | None = None, + driver: str | Sequence[str] | None = None, + sharing: bool = False, + thread_safe: bool = False, + **kwargs: Any, + ) -> None: ... + def __enter__(self) -> Self: ... + def __exit__( + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None + ) -> None: ... + def read_crs(self) -> CRS | None: ... + def read_transform(self) -> list[float]: ... + def start(self) -> None: ... + def stop(self) -> None: ... + def close(self) -> None: ... + @property + def closed(self) -> bool: ... + @property + def count(self) -> int: ... + @property + def indexes(self) -> tuple[int, ...]: ... + @property + def dtypes(self) -> tuple[str, ...]: ... + @property + def block_shapes(self) -> tuple[tuple[int, int], ...]: ... + def get_nodatavals(self) -> tuple[float | None, ...]: ... + @property + def nodatavals(self) -> tuple[float | None, ...]: ... + + @property + def nodata(self) -> float | None: ... + @nodata.setter + def nodata(self, value: float | None) -> None: ... + + @property + def mask_flag_enums(self) -> tuple[list[MaskFlags], ...]: ... + + @property + def crs(self) -> CRS: ... + @crs.setter + def crs(self, value: CRSInput) -> None: ... + + @property + def descriptions(self) -> tuple[str | None, ...]: ... + @descriptions.setter + def descriptions(self, value: Sequence[str | None]) -> None: ... + + def write_transform(self, transform: Sequence[float]) -> None: ... + + @property + def transform(self) -> Affine: ... + @transform.setter + def transform(self, value: Affine) -> None: ... + + @property + def offsets(self) -> tuple[float, ...]: ... + @offsets.setter + def offsets(self, value: Sequence[float]) -> None: ... + + @property + def scales(self) -> tuple[float, ...]: ... + @scales.setter + def scales(self, value: Sequence[float]) -> None: ... + + @property + def units(self) -> tuple[str | None, ...]: ... + @units.setter + def units(self, value: Sequence[str | None]) -> None: ... + + def block_window(self, bidx: int, i: int, j: int) -> Window: ... + def block_size(self, bidx: int, i: int, j: int) -> int: ... + def block_windows(self, bidx: int = 0) -> Iterable[tuple[tuple[int, int], Window]]: ... + @property + def bounds(self) -> BoundingBox: ... + @property + def res(self) -> tuple[float, float]: ... + @property + def meta(self) -> dict[str, Any]: ... + @property + def compression(self) -> Compression | None: ... + @property + def interleaving(self) -> Interleaving | None: ... + @property + def photometric(self) -> PhotometricInterp | None: ... + @property + @deprecated("DatasetBase.is_tiled will be removed in a future rasterio release; inspect block_shapes / profile directly.") + def is_tiled(self) -> bool: ... + @property + def profile(self) -> Profile: ... + def lnglat(self) -> tuple[float, float]: ... + def get_transform(self) -> list[float]: ... + @property + def subdatasets(self) -> list[str]: ... + def tag_namespaces(self, bidx: int = 0) -> list[str]: ... + def tags(self, bidx: int = 0, ns: str | None = None) -> dict[str, str]: ... + def get_tag_item(self, ns: str, dm: str | None = None, bidx: int = 0, ovr: int | None = None) -> str | None: ... + + @property + def colorinterp(self) -> tuple[ColorInterp, ...]: ... + @colorinterp.setter + def colorinterp(self, value: Sequence[ColorInterp]) -> None: ... + + def colormap(self, bidx: int) -> Colormap: ... + def overviews(self, bidx: int) -> list[int]: ... + def checksum(self, bidx: int, window: Window | None = None) -> int: ... + def get_gcps(self) -> tuple[list[GroundControlPoint], CRS]: ... + + @property + def gcps(self) -> tuple[list[GroundControlPoint], CRS]: ... + @gcps.setter + def gcps(self, value: tuple[Sequence[GroundControlPoint], CRSInput]) -> None: ... + + @property + def rpcs(self) -> RPC | None: ... + @rpcs.setter + def rpcs(self, value: RPC | None) -> None: ... + + @property + def files(self) -> list[str]: ... + +_GDAL_AT_LEAST_3_10: Final[bool] + +complex64: Final[str] +complex128: Final[str] +complex_int16: Final[str] +float32: Final[str] +float64: Final[str] +int16: Final[str] + +def _parse_path(path: str) -> _ParsedPath | _UnparsedPath: ... diff --git a/stubs/rasterio/rasterio/_env.pyi b/stubs/rasterio/rasterio/_env.pyi new file mode 100644 index 000000000000..4d5592bebbfe --- /dev/null +++ b/stubs/rasterio/rasterio/_env.pyi @@ -0,0 +1,41 @@ +from contextlib import AbstractContextManager +from typing import Any, Final + +ca_bundle: Final[str] +code_map: Final[dict[int, int]] +level_map: Final[dict[int, int]] + +def gdal_version() -> str: ... +def get_gdal_config(key: str, normalize: bool = True) -> Any: ... +def set_gdal_config(key: str, val: Any, normalize: bool = True) -> None: ... +def del_gdal_config(key: str) -> None: ... +def get_gdal_data() -> str | None: ... +def get_proj_data_search_paths() -> list[str]: ... +def set_proj_data_search_path(path: str) -> None: ... +def driver_count() -> int: ... +def catch_errors() -> AbstractContextManager[None]: ... + +class ConfigEnv: + options: dict[str, Any] + def __init__(self, **options: Any) -> None: ... + def update_config_options(self, **kwargs: Any) -> None: ... + def clear_config_options(self) -> None: ... + def get_config_options(self) -> dict[str, Any]: ... + +class GDALEnv(ConfigEnv): + def __init__(self, **options: Any) -> None: ... + def start(self) -> None: ... + def stop(self) -> None: ... + +class GDALDataFinder: + def find_file(self, basename: str) -> str | None: ... + def search(self, prefix: str | None = None) -> str | None: ... + def search_wheel(self, prefix: str | None = None) -> str | None: ... + def search_prefix(self, prefix: str) -> str | None: ... + def search_debian(self, prefix: str) -> str | None: ... + +class PROJDataFinder: + def has_data(self) -> bool: ... + def search(self, prefix: str | None = None) -> str | None: ... + def search_wheel(self, prefix: str | None = None) -> str | None: ... + def search_prefix(self, prefix: str) -> str | None: ... diff --git a/stubs/rasterio/rasterio/_err.pyi b/stubs/rasterio/rasterio/_err.pyi new file mode 100644 index 000000000000..84e6be115d76 --- /dev/null +++ b/stubs/rasterio/rasterio/_err.pyi @@ -0,0 +1,41 @@ +from contextlib import AbstractContextManager +from enum import IntEnum +from typing import Final + +class GDALError(IntEnum): + none = 0 + debug = 1 + warning = 2 + failure = 3 + fatal = 4 + +class CPLE_BaseError(Exception): + error: int + errno: int + errmsg: str + def __init__(self, error: int, errno: int, errmsg: str) -> None: ... + +class CPLE_AppDefinedError(CPLE_BaseError): ... +class CPLE_AssertionFailedError(CPLE_BaseError): ... +class CPLE_FileIOError(CPLE_BaseError): ... +class CPLE_HttpResponseError(CPLE_BaseError): ... +class CPLE_IllegalArgError(CPLE_BaseError): ... +class CPLE_NoWriteAccessError(CPLE_BaseError): ... +class CPLE_NotSupportedError(CPLE_BaseError): ... +class CPLE_OpenFailedError(CPLE_BaseError): ... +class CPLE_OutOfMemoryError(CPLE_BaseError): ... +class CPLE_UserInterruptError(CPLE_BaseError): ... +class CPLE_AWSAccessDeniedError(CPLE_BaseError): ... +class CPLE_AWSBucketNotFoundError(CPLE_BaseError): ... +class CPLE_AWSError(CPLE_BaseError): ... +class CPLE_AWSInvalidCredentialsError(CPLE_BaseError): ... +class CPLE_AWSObjectNotFoundError(CPLE_BaseError): ... +class CPLE_AWSSignatureDoesNotMatchError(CPLE_BaseError): ... +class ObjectNullError(CPLE_BaseError): ... + +exception_map: Final[dict[int, type[CPLE_BaseError]]] + +class StackChecker: + def __init__(self) -> None: ... + +def stack_errors() -> AbstractContextManager[StackChecker]: ... diff --git a/stubs/rasterio/rasterio/_features.pyi b/stubs/rasterio/rasterio/_features.pyi new file mode 100644 index 000000000000..990dd3f6c79d --- /dev/null +++ b/stubs/rasterio/rasterio/_features.pyi @@ -0,0 +1,30 @@ +from collections.abc import Iterator +from typing import Any, Final + +from rasterio.enums import MergeAlg as MergeAlg + +GEOMETRY_TYPES: Final[dict[int, str]] +GEOJSON2OGR_GEOMETRY_TYPES: Final[dict[str, int]] + +bool_: Final[str] +int8: Final[str] +int16: Final[str] +int32: Final[str] +int64: Final[str] +uint8: Final[str] +uint16: Final[str] +uint32: Final[str] +uint64: Final[str] +float16: Final[str] +float32: Final[str] +float64: Final[str] + +class GeomBuilder: + def build(self, geom: Any) -> dict[str, Any]: ... + +class OGRGeomBuilder: + def build(self, geom: dict[str, Any]) -> Any: ... + +class ShapeIterator: + def __iter__(self) -> Iterator[tuple[dict[str, Any], float]]: ... + def __next__(self) -> tuple[dict[str, Any], float]: ... diff --git a/stubs/rasterio/rasterio/_filepath.pyi b/stubs/rasterio/rasterio/_filepath.pyi new file mode 100644 index 000000000000..ea460c19d72c --- /dev/null +++ b/stubs/rasterio/rasterio/_filepath.pyi @@ -0,0 +1,6 @@ +from typing import Any + +class FilePathBase: + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + +def clone_file_obj(fobj: Any) -> Any: ... diff --git a/stubs/rasterio/rasterio/_io.pyi b/stubs/rasterio/rasterio/_io.pyi new file mode 100644 index 000000000000..25d5392fd9e7 --- /dev/null +++ b/stubs/rasterio/rasterio/_io.pyi @@ -0,0 +1,176 @@ +import os +from collections.abc import Iterator, Sequence +from typing import Any, BinaryIO, Final, Self +from typing_extensions import deprecated + +from numpy.typing import DTypeLike, NDArray +from rasterio._affine_types import Affine +from rasterio._base import DatasetBase +from rasterio._path import _ParsedPath, _UnparsedPath +from rasterio._typing import Colormap, CRSInput, Indexes, NumType, ShapeND, WindowInput +from rasterio.control import GroundControlPoint +from rasterio.enums import Resampling +from rasterio.rpc import RPC + +def validate_resampling(resampling: Resampling) -> None: ... +def virtual_file_to_buffer(filename: str) -> bytes: ... +def _is_complex_int(dtype: Any) -> bool: ... +def _getnpdtype(dtype: Any) -> Any: ... +def _gdal_typename(dt: Any) -> str: ... +def _get_gdal_dtype(type_name: Any) -> int: ... +def _boundless_vrt_doc( + src_dataset: DatasetBase, + nodata: float | None = None, + background: float | None = None, + hidenodata: bool = False, + width: int | None = None, + height: int | None = None, + transform: Affine | None = None, + masked: bool = False, + resampling: Resampling = ..., +) -> str: ... +def sample_gen( + dataset: DatasetBase, xy: Sequence[tuple[float, float]], indexes: Indexes | None = None, masked: bool = False +) -> Iterator[NDArray[Any]]: ... + +class Statistics: + min: float + max: float + mean: float + std: float + def __init__(self, min: float, max: float, mean: float, std: float) -> None: ... + +class DatasetReaderBase(DatasetBase): + def read( + self, + indexes: Indexes | None = None, + out: NDArray[Any] | None = None, + window: WindowInput | None = None, + masked: bool = False, + out_shape: ShapeND | None = None, + boundless: bool = False, + resampling: Resampling = ..., + fill_value: NumType | None = None, + out_dtype: DTypeLike | None = None, + ) -> NDArray[Any]: ... + def read_masks( + self, + indexes: Indexes | None = None, + out: NDArray[Any] | None = None, + out_shape: ShapeND | None = None, + window: WindowInput | None = None, + boundless: bool = False, + resampling: Resampling = ..., + ) -> NDArray[Any]: ... + def dataset_mask( + self, + out: NDArray[Any] | None = None, + out_shape: ShapeND | None = None, + window: WindowInput | None = None, + boundless: bool = False, + resampling: Resampling = ..., + ) -> NDArray[Any]: ... + def sample( + self, xy: Sequence[tuple[float, float]], indexes: Indexes | None = None, masked: bool = False + ) -> Iterator[NDArray[Any]]: ... + def stats(self, *, indexes: Indexes | None = None, approx: bool = False) -> list[Statistics]: ... + @deprecated("DatasetReaderBase.statistics() will be removed in 2.0.0; please switch to stats().") + def statistics(self, bidx: int, approx: bool = False, clear_cache: bool = False) -> Statistics: ... + +class MemoryFileBase: + name: str + mode: str + closed: bool + def __init__( + self, + file_or_bytes: bytes | BinaryIO | None = None, + dirname: str | None = None, + filename: str | None = None, + ext: str = "", + ) -> None: ... + def __len__(self) -> int: ... + def exists(self) -> bool: ... + def getbuffer(self) -> memoryview: ... + def close(self) -> None: ... + def seek(self, offset: int, whence: int = 0) -> int: ... + def tell(self) -> int: ... + def read(self, size: int = -1) -> bytes: ... + def write(self, data: bytes) -> int: ... + +class DatasetWriterBase(DatasetReaderBase): + name: str + mode: str + width: int + height: int + shape: tuple[int, int] + driver: str + + def __init__( + self, + path: str | os.PathLike[str] | _ParsedPath | _UnparsedPath, + mode: str, + driver: str | None = None, + width: int | None = None, + height: int | None = None, + count: int | None = None, + crs: CRSInput | None = None, + transform: Affine | None = None, + dtype: DTypeLike | None = None, + nodata: float | None = None, + gcps: Sequence[GroundControlPoint] | None = None, + rpcs: RPC | None = None, + sharing: bool = False, + **kwargs: Any, + ) -> None: ... + def write( + self, arr: NDArray[Any], indexes: Indexes | None = None, window: WindowInput | None = None, masked: bool = False + ) -> None: ... + def write_band(self, bidx: int, src: NDArray[Any], window: WindowInput | None = None) -> None: ... + def update_tags(self, bidx: int = 0, ns: str | None = None, **kwargs: Any) -> None: ... + def set_band_description(self, bidx: int, value: str) -> None: ... + def set_band_unit(self, bidx: int, value: str) -> None: ... + def write_colormap(self, bidx: int, colormap: Colormap) -> None: ... + def write_mask(self, mask_array: NDArray[Any], window: WindowInput | None = None) -> None: ... + def build_overviews(self, factors: Sequence[int], resampling: Resampling = ...) -> None: ... + def update_stats( + self, *, stats: Sequence[Statistics] | None = None, indexes: Indexes | None = None, approx: bool = False + ) -> None: ... + def clear_stats(self) -> None: ... + +class MemoryDataset(DatasetWriterBase): + def __init__( + self, + image: NDArray[Any] | None = None, + dtype: DTypeLike | None = None, + count: int = 1, + width: int | None = None, + height: int | None = None, + transform: Affine | None = None, + gcps: Sequence[GroundControlPoint] | None = None, + rpcs: RPC | None = None, + crs: CRSInput | None = None, + ) -> None: ... + def __enter__(self) -> Self: ... + +class BufferedDatasetWriterBase(DatasetWriterBase): + def __init__( + self, + path: str | os.PathLike[str] | _ParsedPath | _UnparsedPath, + mode: str = "w", + driver: str | None = None, + width: int | None = None, + height: int | None = None, + count: int | None = None, + crs: CRSInput | None = None, + transform: Affine | None = None, + dtype: DTypeLike | None = None, + nodata: float | None = None, + gcps: Sequence[GroundControlPoint] | None = None, + rpcs: RPC | None = None, + sharing: bool = False, + **kwargs: Any, + ) -> None: ... + def stop(self) -> None: ... + +int8: Final[str] +uint8: Final[str] diff --git a/stubs/rasterio/rasterio/_path.pyi b/stubs/rasterio/rasterio/_path.pyi new file mode 100644 index 000000000000..c3d92cf20e32 --- /dev/null +++ b/stubs/rasterio/rasterio/_path.pyi @@ -0,0 +1,33 @@ +import os +from typing import Any, Final, Self + +SCHEMES: Final[dict[str, str]] +ARCHIVESCHEMES: Final[type[set[Any]]] +CURLSCHEMES: Final[set[str]] +REMOTESCHEMES: Final[set[str]] + +class _Path: + def as_vsi(self) -> str: ... + +class _ParsedPath(_Path): + path: str + archive: str | None + scheme: str | None + def __init__(self, path: str, archive: str | None, scheme: str | None) -> None: ... + @classmethod + def from_uri(cls, uri: str) -> Self: ... + @property + def name(self) -> str: ... + @property + def is_remote(self) -> bool: ... + @property + def is_local(self) -> bool: ... + +class _UnparsedPath(_Path): + path: str + def __init__(self, path: str) -> None: ... + @property + def name(self) -> str: ... + +def _parse_path(path: str | os.PathLike[str] | _Path) -> _ParsedPath | _UnparsedPath: ... +def _vsi_path(path: _Path) -> str: ... diff --git a/stubs/rasterio/rasterio/_show_versions.pyi b/stubs/rasterio/rasterio/_show_versions.pyi new file mode 100644 index 000000000000..1eeec0747405 --- /dev/null +++ b/stubs/rasterio/rasterio/_show_versions.pyi @@ -0,0 +1 @@ +def show_versions() -> None: ... diff --git a/stubs/rasterio/rasterio/_transform.pyi b/stubs/rasterio/rasterio/_transform.pyi new file mode 100644 index 000000000000..28a1a0bfc98f --- /dev/null +++ b/stubs/rasterio/rasterio/_transform.pyi @@ -0,0 +1,16 @@ +from collections.abc import Sequence +from typing import Any + +from rasterio.control import GroundControlPoint +from rasterio.errors import TransformWarning as TransformWarning +from rasterio.rpc import RPC + +class GCPTransformerBase: + def __init__(self, gcps: Sequence[GroundControlPoint]) -> None: ... + def close(self) -> None: ... + +class RPCTransformerBase: + def __init__(self, rpcs: RPC, **kwargs: Any) -> None: ... + def close(self) -> None: ... + +def _transform_from_gcps(gcps: Sequence[GroundControlPoint]) -> tuple[float, ...]: ... diff --git a/stubs/rasterio/rasterio/_typing.pyi b/stubs/rasterio/rasterio/_typing.pyi new file mode 100644 index 000000000000..5026e284cb3b --- /dev/null +++ b/stubs/rasterio/rasterio/_typing.pyi @@ -0,0 +1,15 @@ +from collections.abc import Sequence +from typing import BinaryIO, TypeAlias + +from rasterio.crs import CRS +from rasterio.io import BufferedDatasetWriter, DatasetReader, DatasetWriter, MemoryFile +from rasterio.windows import Window + +AnyDataset: TypeAlias = DatasetReader | DatasetWriter | BufferedDatasetWriter | MemoryFile +Colormap: TypeAlias = dict[int, tuple[int, int, int] | tuple[int, int, int, int]] +CRSInput: TypeAlias = str | dict[str, str] | CRS +FileOrBytes: TypeAlias = BinaryIO | bytes +Indexes: TypeAlias = int | Sequence[int] +NumType: TypeAlias = int | float +ShapeND: TypeAlias = Sequence[int] +WindowInput: TypeAlias = Window | tuple[tuple[int, int], tuple[int, int]] diff --git a/stubs/rasterio/rasterio/_version.pyi b/stubs/rasterio/rasterio/_version.pyi new file mode 100644 index 000000000000..063e03ad00dd --- /dev/null +++ b/stubs/rasterio/rasterio/_version.pyi @@ -0,0 +1,5 @@ +def gdal_version() -> str: ... +def get_gdal_version_info(key: str) -> str: ... +def check_gdal_version(major: int, minor: int) -> bool: ... +def get_geos_version() -> tuple[int, int, int]: ... +def get_proj_version() -> tuple[int, int, int]: ... diff --git a/stubs/rasterio/rasterio/_vsiopener.pyi b/stubs/rasterio/rasterio/_vsiopener.pyi new file mode 100644 index 000000000000..19d4d62489ea --- /dev/null +++ b/stubs/rasterio/rasterio/_vsiopener.pyi @@ -0,0 +1,20 @@ +from abc import ABC, abstractmethod +from contextlib import AbstractContextManager +from typing import Any, BinaryIO + +from rasterio.errors import OpenerRegistrationError as OpenerRegistrationError + +class FileContainer(ABC): + @abstractmethod + def open(self, path: str, mode: str = "r", **kwds: Any) -> BinaryIO: ... + +class MultiByteRangeResource(ABC): + @abstractmethod + def get_byte_ranges(self, offsets: list[int], sizes: list[int]) -> list[bytes]: ... + +class MultiByteRangeResourceContainer(FileContainer): + @abstractmethod + def open(self, path: str, **kwds: Any) -> MultiByteRangeResource: ... # type: ignore[override] + +def to_pyopener(obj: Any) -> FileContainer: ... +def _opener_registration(urlpath: str, obj: Any) -> AbstractContextManager[str]: ... diff --git a/stubs/rasterio/rasterio/_warp.pyi b/stubs/rasterio/rasterio/_warp.pyi new file mode 100644 index 000000000000..d3508f1f614b --- /dev/null +++ b/stubs/rasterio/rasterio/_warp.pyi @@ -0,0 +1,121 @@ +from collections.abc import Mapping, Sequence +from typing import Any, Final + +from numpy.typing import DTypeLike, NDArray +from rasterio._affine_types import Affine +from rasterio._io import DatasetReaderBase +from rasterio._typing import CRSInput, Indexes, ShapeND, WindowInput +from rasterio.control import GroundControlPoint +from rasterio.crs import CRS +from rasterio.enums import Resampling +from rasterio.io import DatasetReader +from rasterio.rpc import RPC + +SUPPORTED_RESAMPLING: Final[list[Resampling]] +DEFAULT_NODATA_FLAG: Final[object] + +def recursive_round(val: Any, precision: int) -> Any: ... +def _transform_geom( + src_crs: CRSInput, dst_crs: CRSInput, geom: Mapping[str, Any] | Sequence[Mapping[str, Any]], precision: int +) -> dict[str, Any] | list[dict[str, Any]]: ... +def _reproject( + source: NDArray[Any] | Any, + destination: NDArray[Any] | Any, + src_transform: Affine | None = None, + gcps: Sequence[GroundControlPoint] | None = None, + rpcs: RPC | None = None, + src_crs: CRSInput | None = None, + src_nodata: float | None = None, + dst_transform: Affine | None = None, + dst_crs: CRSInput | None = None, + dst_nodata: float | None = None, + dst_alpha: int = 0, + src_alpha: int = 0, + resampling: Resampling = ..., + init_dest_nodata: bool = True, + tolerance: float = 0.125, + num_threads: int = 1, + warp_mem_limit: int = 0, + working_data_type: int = 0, + src_geoloc_array: NDArray[Any] | None = None, + **kwargs: Any, +) -> tuple[NDArray[Any], Affine]: ... +def _calculate_default_transform( + src_crs: CRSInput, + dst_crs: CRSInput, + width: int, + height: int, + left: float | None = None, + bottom: float | None = None, + right: float | None = None, + top: float | None = None, + gcps: Sequence[GroundControlPoint] | None = None, + rpcs: RPC | None = None, + src_geoloc_array: NDArray[Any] | None = None, + **kwargs: Any, +) -> tuple[Affine, int, int]: ... +def _transform_bounds( + src_crs: CRS, dst_crs: CRS, left: float, bottom: float, right: float, top: float, densify_pts: int +) -> tuple[float, float, float, float]: ... +def _suggested_proxy_vrt_doc( + width: int, + height: int, + transform: Affine | None = None, + crs: CRSInput | None = None, + gcps: Sequence[GroundControlPoint] | None = None, + rpcs: RPC | None = None, +) -> str: ... + +class WarpedVRTReaderBase(DatasetReaderBase): + src_dataset: DatasetReader + src_crs: CRS + src_transform: Affine | None + resampling: Resampling + tolerance: float + src_nodata: float | None + dst_nodata: float | None + working_dtype: DTypeLike | None + warp_extras: dict[str, Any] + + def __init__( + self, + src_dataset: DatasetReader, + src_crs: CRSInput | None = None, + crs: CRSInput | None = None, + resampling: Resampling = ..., + tolerance: float = 0.125, + src_nodata: float | None = ..., + nodata: float | None = ..., + width: int | None = None, + height: int | None = None, + src_transform: Affine | None = None, + transform: Affine | None = None, + init_dest_nodata: bool = True, + src_alpha: int = 0, + dst_alpha: int = 0, + add_alpha: bool = False, + warp_mem_limit: int = 0, + dtype: DTypeLike | None = None, + **warp_extras: Any, + ) -> None: ... + def read( # type: ignore[override] + self, + indexes: Indexes | None = None, + out: NDArray[Any] | None = None, + window: WindowInput | None = None, + masked: bool = False, + out_shape: ShapeND | None = None, + resampling: Resampling = ..., + fill_value: float | None = None, + out_dtype: DTypeLike | None = None, + **kwargs: Any, + ) -> NDArray[Any]: ... + def read_masks( # type: ignore[override] + self, + indexes: Indexes | None = None, + out: NDArray[Any] | None = None, + out_shape: ShapeND | None = None, + window: WindowInput | None = None, + resampling: Resampling = ..., + **kwargs: Any, + ) -> NDArray[Any]: ... diff --git a/stubs/rasterio/rasterio/abc.pyi b/stubs/rasterio/rasterio/abc.pyi new file mode 100644 index 000000000000..d9ebb71719e0 --- /dev/null +++ b/stubs/rasterio/rasterio/abc.pyi @@ -0,0 +1 @@ +from rasterio._vsiopener import FileContainer as FileContainer, MultiByteRangeResourceContainer as MultiByteRangeResourceContainer diff --git a/stubs/rasterio/rasterio/cache.pyi b/stubs/rasterio/rasterio/cache.pyi new file mode 100644 index 000000000000..ab1f8b285843 --- /dev/null +++ b/stubs/rasterio/rasterio/cache.pyi @@ -0,0 +1,2 @@ +def invalidate(pattern: str) -> None: ... +def invalidate_all() -> None: ... diff --git a/stubs/rasterio/rasterio/control.pyi b/stubs/rasterio/rasterio/control.pyi new file mode 100644 index 000000000000..0fbec047e6be --- /dev/null +++ b/stubs/rasterio/rasterio/control.pyi @@ -0,0 +1,46 @@ +from collections.abc import Sequence +from typing import Literal, TypedDict, type_check_only + +@type_check_only +class GroundControlPointDict(TypedDict): + id: str + info: str | None + row: float + col: float + x: float + y: float + z: float | None + +@type_check_only +class GroundControlPointGeometry(TypedDict): + type: Literal["Point"] + coordinates: Sequence[float] + +@type_check_only +class GroundControlPointFeature(TypedDict): + id: str + type: Literal["Feature"] + geometry: GroundControlPointGeometry + properties: GroundControlPointDict + +class GroundControlPoint: + id: str + info: str | None + row: float + col: float + x: float + y: float + z: float | None + def __init__( + self, + row: float | None = None, + col: float | None = None, + x: float | None = None, + y: float | None = None, + z: float | None = None, + id: str | None = None, + info: str | None = None, + ) -> None: ... + def asdict(self) -> GroundControlPointDict: ... + @property + def __geo_interface__(self) -> GroundControlPointFeature: ... diff --git a/stubs/rasterio/rasterio/coords.pyi b/stubs/rasterio/rasterio/coords.pyi new file mode 100644 index 000000000000..c7b97fc2fe31 --- /dev/null +++ b/stubs/rasterio/rasterio/coords.pyi @@ -0,0 +1,11 @@ +from typing import NamedTuple, TypeAlias + +_Quadruple: TypeAlias = tuple[float, float, float, float] + +class BoundingBox(NamedTuple): + left: float + bottom: float + right: float + top: float + +def disjoint_bounds(bounds1: BoundingBox | _Quadruple, bounds2: BoundingBox | _Quadruple) -> bool: ... diff --git a/stubs/rasterio/rasterio/crs.pyi b/stubs/rasterio/rasterio/crs.pyi new file mode 100644 index 000000000000..4ee71c4ae66f --- /dev/null +++ b/stubs/rasterio/rasterio/crs.pyi @@ -0,0 +1,68 @@ +from collections.abc import Iterator, Mapping +from typing import Any, Self +from typing_extensions import deprecated, disjoint_base + +from rasterio.enums import WktVersion + +all_proj_keys: set[str] + +@disjoint_base +class CRS(Mapping[str, Any]): + def __init__(self, initialdata: Mapping[str, Any] | None = None, **kwargs: Any) -> None: ... + def __getitem__(self, key: str, /) -> Any: ... + def __iter__(self) -> Iterator[str]: ... + def __len__(self) -> int: ... + def __bool__(self) -> bool: ... + def __nonzero__(self) -> bool: ... + def __eq__(self, other: object, /) -> bool: ... + def __copy__(self) -> Self: ... + def __hash__(self) -> int: ... + def __getstate__(self) -> dict[str, Any]: ... + def __setstate__(self, state: Mapping[str, Any]) -> None: ... + def to_proj4(self) -> str: ... + def to_wkt(self, morph_to_esri_dialect: bool = False, version: WktVersion | str | None = None) -> str: ... + @property + def wkt(self) -> str: ... + def to_epsg(self, confidence_threshold: int = 70) -> int | None: ... + def to_authority(self, confidence_threshold: int = 70) -> tuple[str, str] | None: ... + def to_dict(self, projjson: bool = False) -> dict[str, Any]: ... + @property + def data(self) -> dict[str, Any]: ... + @property + def is_geographic(self) -> bool: ... + @property + def is_projected(self) -> bool: ... + @property + @deprecated("CRS.is_valid is deprecated since rasterio 1.4 and will be removed in 2.0.0.") + def is_valid(self) -> bool: ... + @property + def is_epsg_code(self) -> bool: ... + @property + def linear_units_factor(self) -> tuple[str, float]: ... + @property + def linear_units(self) -> str: ... + @property + def units_factor(self) -> tuple[str, float]: ... + @property + def geodetic_crs(self) -> CRS | None: ... + def to_string(self) -> str: ... + def equals(self, other: CRS, ignore_axis_order: bool = False) -> bool: ... + def get(self, item: str) -> Any: ... # type: ignore[override] + @staticmethod + def from_epsg(code: int | str) -> CRS: ... + @staticmethod + def from_authority(auth_name: str, code: int | str) -> CRS: ... + @staticmethod + def from_string(value: str, morph_from_esri_dialect: bool = False) -> CRS: ... + @staticmethod + def from_proj4(proj: str) -> CRS: ... + @staticmethod + def from_dict(initialdata: Mapping[str, Any] | None = None, **kwargs: Any) -> CRS: ... + @staticmethod + def from_wkt(wkt: str, morph_from_esri_dialect: bool = False) -> CRS: ... + @staticmethod + def from_user_input(value: Any, morph_from_esri_dialect: bool = False) -> CRS: ... + +def epsg_treats_as_latlong(input_crs: CRS) -> bool: ... +def epsg_treats_as_northingeasting(input_crs: CRS) -> bool: ... +def auth_preference(item: str) -> None: ... diff --git a/stubs/rasterio/rasterio/drivers.pyi b/stubs/rasterio/rasterio/drivers.pyi new file mode 100644 index 000000000000..96b6d727bd5b --- /dev/null +++ b/stubs/rasterio/rasterio/drivers.pyi @@ -0,0 +1,8 @@ +import os +from typing import Final + +blacklist: Final[dict[str, tuple[str, ...]]] + +def raster_driver_extensions() -> dict[str, str]: ... +def driver_from_extension(path: str | os.PathLike[str]) -> str: ... +def is_blacklisted(name: str, mode: str) -> bool: ... diff --git a/stubs/rasterio/rasterio/dtypes.pyi b/stubs/rasterio/rasterio/dtypes.pyi new file mode 100644 index 000000000000..16003a399610 --- /dev/null +++ b/stubs/rasterio/rasterio/dtypes.pyi @@ -0,0 +1,37 @@ +from collections.abc import Sequence +from typing import Any, Final + +from numpy.typing import ArrayLike, DTypeLike + +bool_: Final[str] +ubyte: Final[str] +uint8: Final[str] +sbyte: Final[str] +int8: Final[str] +uint16: Final[str] +int16: Final[str] +uint32: Final[str] +int32: Final[str] +int64: Final[str] +uint64: Final[str] +float16: Final[str] +float32: Final[str] +float64: Final[str] +complex_: Final[str] +complex64: Final[str] +complex128: Final[str] +complex_int16: Final[str] + +dtype_fwd: Final[dict[int, str | None]] +dtype_rev: Final[dict[str | None, int]] +typename_fwd: Final[dict[int, str]] +typename_rev: Final[dict[str, int]] +dtype_ranges: Final[dict[str, tuple[float, float]]] +dtype_info_registry: Final[dict[str, type]] + +def in_dtype_range(value: float, dtype: DTypeLike) -> bool: ... +def check_dtype(dt: DTypeLike) -> bool: ... +def get_minimum_dtype(values: ArrayLike) -> str: ... +def is_ndarray(array: Any) -> bool: ... +def can_cast_dtype(values: ArrayLike, dtype: DTypeLike) -> bool: ... +def validate_dtype(values: ArrayLike, valid_dtypes: Sequence[DTypeLike]) -> bool: ... diff --git a/stubs/rasterio/rasterio/enums.pyi b/stubs/rasterio/rasterio/enums.pyi new file mode 100644 index 000000000000..6e1a2fc76a6b --- /dev/null +++ b/stubs/rasterio/rasterio/enums.pyi @@ -0,0 +1,126 @@ +from enum import Enum, IntEnum + +class TransformDirection(IntEnum): + forward = 1 + reverse = 0 + +class TransformMethod(Enum): + affine = "transform" + gcps = "gcps" + rpcs = "rpcs" + +class ColorInterp(IntEnum): + undefined = 0 + gray = 1 + grey = 1 + palette = 2 + red = 3 + green = 4 + blue = 5 + alpha = 6 + hue = 7 + saturation = 8 + lightness = 9 + cyan = 10 + magenta = 11 + yellow = 12 + black = 13 + Y = 14 + Cb = 15 + Cr = 16 + pan = 17 + coastal = 18 + rededge = 19 + nir = 20 + swir = 21 + mwir = 22 + lwir = 23 + tir = 24 + other_ir = 25 + sar_ka = 30 + sar_k = 31 + sar_ku = 32 + sar_x = 33 + sar_c = 34 + sar_s = 35 + sar_l = 36 + sar_p = 37 + +class Resampling(IntEnum): + nearest = 0 + bilinear = 1 + cubic = 2 + cubic_spline = 3 + lanczos = 4 + average = 5 + mode = 6 + gauss = 7 + max = 8 + min = 9 + med = 10 + q1 = 11 + q3 = 12 + sum = 13 + rms = 14 + +class OverviewResampling(IntEnum): + nearest = 0 + bilinear = 1 + cubic = 2 + cubic_spline = 3 + lanczos = 4 + average = 5 + mode = 6 + gauss = 7 + rms = 14 + +class Compression(Enum): + jpeg = "JPEG" + lzw = "LZW" + packbits = "PACKBITS" + deflate = "DEFLATE" + ccittrle = "CCITTRLE" + ccittfax3 = "CCITTFAX3" + ccittfax4 = "CCITTFAX4" + lzma = "LZMA" + none = "NONE" + zstd = "ZSTD" + lerc = "LERC" + lerc_deflate = "LERC_DEFLATE" + lerc_zstd = "LERC_ZSTD" + webp = "WEBP" + jpeg2000 = "JPEG2000" + +class Interleaving(Enum): + pixel = "PIXEL" + line = "LINE" + band = "BAND" + tile = "TILE" + +class MaskFlags(IntEnum): + all_valid = 1 + per_dataset = 2 + alpha = 4 + nodata = 8 + +class PhotometricInterp(Enum): + black = "MINISBLACK" + white = "MINISWHITE" + rgb = "RGB" + cmyk = "CMYK" + ycbcr = "YCbCr" + cielab = "CIELAB" + icclab = "ICCLAB" + itulab = "ITULAB" + +class MergeAlg(Enum): + replace = "REPLACE" + add = "ADD" + +class WktVersion(Enum): + WKT2_2015 = "WKT2_2015" + WKT2 = "WKT2" + WKT2_2019 = "WKT2_2018" + WKT1_GDAL = "WKT1_GDAL" + WKT1 = "WKT1" + WKT1_ESRI = "WKT1_ESRI" diff --git a/stubs/rasterio/rasterio/env.pyi b/stubs/rasterio/rasterio/env.pyi new file mode 100644 index 000000000000..810f1f9cb374 --- /dev/null +++ b/stubs/rasterio/rasterio/env.pyi @@ -0,0 +1,98 @@ +import logging +import threading +from collections.abc import Callable, Iterable +from types import TracebackType +from typing import Any, Final, Self, TypeVar +from typing_extensions import deprecated + +from rasterio._env import ( + GDALDataFinder as GDALDataFinder, + GDALEnv as GDALEnv, + PROJDataFinder as PROJDataFinder, + get_gdal_config as get_gdal_config, + set_gdal_config as set_gdal_config, + set_proj_data_search_path as set_proj_data_search_path, +) +from rasterio.errors import ( + EnvError as EnvError, + GDALVersionError as GDALVersionError, + RasterioDeprecationWarning as RasterioDeprecationWarning, +) +from rasterio.session import DummySession as DummySession, Session as Session + +_F = TypeVar("_F", bound=Callable[..., Any]) + +class ThreadEnv(threading.local): + def __init__(self) -> None: ... + +local: ThreadEnv +log: logging.Logger + +class Env: + session: Session + options: dict[str, Any] + context_options: dict[str, Any] + def __init__( + self, + session: Session | None = None, + aws_unsigned: bool = False, + profile_name: str | None = None, + session_class: Callable[..., Session] = ..., + **options: Any, + ) -> None: ... + @classmethod + def default_options(cls) -> dict[str, Any]: ... + @classmethod + def from_defaults(cls, *args: Any, **kwargs: Any) -> Self: ... + def credentialize(self) -> None: ... + def drivers(self) -> dict[str, str]: ... + def __enter__(self) -> Self: ... + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_val: BaseException | None = None, + exc_tb: TracebackType | None = None, + ) -> None: ... + +def defenv(**options: Any) -> None: ... +def getenv() -> dict[str, Any]: ... +def hasenv() -> bool: ... +def setenv(**options: Any) -> None: ... +@deprecated("Please use Env.session.hascreds() instead.") +def hascreds() -> bool: ... +def delenv() -> None: ... + +class NullContextManager: + def __init__(self) -> None: ... + def __enter__(self) -> Self: ... + def __exit__(self, *args: object) -> None: ... + +def env_ctx_if_needed() -> Env | NullContextManager: ... +def ensure_env(f: _F) -> _F: ... +@deprecated("ensure_env_credentialled is a deprecated alias; use ensure_env_with_credentials instead.") +def ensure_env_credentialled(f: _F) -> _F: ... +def ensure_env_with_credentials(f: _F) -> _F: ... +def gdal_version() -> str: ... + +class GDALVersion: + major: int + minor: int + patch: int + def __init__(self, major: int = 0, minor: int = 0, patch: int = 0) -> None: ... + def __eq__(self, other: object) -> bool: ... + def __lt__(self, other: GDALVersion) -> bool: ... + @classmethod + def parse(cls, input: str | GDALVersion, include_patch: bool = False) -> Self: ... + @classmethod + def runtime(cls, include_patch: bool = False) -> Self: ... + def at_least(self, other: str | GDALVersion, include_patch: bool = False) -> bool: ... + +def require_gdal_version( + version: str | GDALVersion, + param: str | None = None, + values: Iterable[Any] | None = None, + is_max_version: bool = False, + reason: str = "", +) -> Callable[[_F], _F]: ... + +path: Final[str | None] diff --git a/stubs/rasterio/rasterio/errors.pyi b/stubs/rasterio/rasterio/errors.pyi new file mode 100644 index 000000000000..c883864c3f86 --- /dev/null +++ b/stubs/rasterio/rasterio/errors.pyi @@ -0,0 +1,40 @@ +from click import FileError + +class RasterioError(Exception): ... +class InvalidArrayError(RasterioError): ... +class WindowError(RasterioError): ... +class CRSError(ValueError): ... +class EnvError(RasterioError): ... +class DriverCapabilityError(RasterioError, ValueError): ... +class DriverRegistrationError(ValueError): ... + +class FileOverwriteError(FileError): + def __init__(self, message: str) -> None: ... + +class RasterioIOError(RasterioError, OSError): ... +class NodataShadowWarning(UserWarning): ... +class NotGeoreferencedWarning(UserWarning): ... +class TransformWarning(UserWarning): ... +class RPCError(ValueError): ... +class ShapeSkipWarning(UserWarning): ... +class GDALBehaviorChangeException(RuntimeError): ... +class GDALOptionNotImplementedError(RasterioError): ... +class GDALVersionError(RasterioError): ... +class WindowEvaluationError(ValueError): ... +class RasterioDeprecationWarning(FutureWarning): ... +class RasterBlockError(RasterioError): ... +class BandOverviewError(UserWarning): ... +class WarpOptionsError(RasterioError): ... +class UnsupportedOperation(RasterioError): ... +class OverviewCreationError(RasterioError): ... +class DatasetAttributeError(RasterioError, NotImplementedError): ... +class PathError(RasterioError): ... +class ResamplingAlgorithmError(RasterioError): ... +class TransformError(RasterioError): ... +class WarpedVRTError(RasterioError): ... +class DatasetIOShapeError(RasterioError): ... +class WarpOperationError(RasterioError): ... +class StatisticsError(RasterioError): ... +class OpenerRegistrationError(RasterioError): ... +class MergeError(RasterioError): ... +class StackError(RasterioError): ... diff --git a/stubs/rasterio/rasterio/features.pyi b/stubs/rasterio/rasterio/features.pyi new file mode 100644 index 000000000000..4cd4a7fac61c --- /dev/null +++ b/stubs/rasterio/rasterio/features.pyi @@ -0,0 +1,72 @@ +import os +from collections.abc import Iterable, Iterator, Mapping +from typing import Any, TypeAlias, overload +from typing_extensions import deprecated + +import numpy as np +from numpy.typing import DTypeLike, NDArray +from rasterio._affine_types import Affine +from rasterio.enums import MergeAlg as MergeAlg +from rasterio.io import DatasetReader +from rasterio.windows import Window as Window + +Geometry: TypeAlias = Mapping[str, Any] + +def geometry_mask( + geometries: Iterable[Geometry], out_shape: tuple[int, int], transform: Affine, all_touched: bool = False, invert: bool = False +) -> NDArray[np.bool_]: ... +def shapes( + source: NDArray[Any], mask: NDArray[np.bool_] | None = None, connectivity: int = 4, transform: Affine = ... +) -> Iterator[tuple[dict[str, Any], float | int]]: ... +def sieve( + source: NDArray[Any], size: int, out: NDArray[Any] | None = None, mask: NDArray[np.bool_] | None = None, connectivity: int = 4 +) -> NDArray[Any]: ... +def rasterize( + shapes: Iterable[tuple[Geometry, float] | Geometry], + out_shape: tuple[int, int] | None = None, + fill: float = 0, + nodata: float | None = None, + masked: bool = False, + out: NDArray[Any] | None = None, + transform: Affine = ..., + all_touched: bool = False, + merge_alg: MergeAlg = ..., + default_value: float = 1, + dtype: DTypeLike | None = None, + skip_invalid: bool = True, + dst_path: str | os.PathLike[str] | None = None, + dst_kwds: dict[str, Any] | None = None, +) -> NDArray[Any]: ... +def bounds(geometry: Geometry, north_up: bool = True, transform: Affine | None = None) -> tuple[float, float, float, float]: ... + +@overload +def geometry_window( + dataset: DatasetReader, shapes: Iterable[Geometry], pad_x: float = 0, pad_y: float = 0, *, boundless: bool = False +) -> Window: ... +@overload +@deprecated( + "`north_up`, `rotated`, and `pixel_precision` on features.geometry_window are " + "unused since rasterio 1.2.1 and will be removed in a future release." +) +def geometry_window( + dataset: DatasetReader, + shapes: Iterable[Geometry], + pad_x: float = 0, + pad_y: float = 0, + north_up: bool | None = None, + rotated: bool | None = None, + pixel_precision: float | None = None, + boundless: bool = False, +) -> Window: ... + +def is_valid_geom(geom: Geometry) -> bool: ... +def dataset_features( + src: DatasetReader, + bidx: int | None = None, + sampling: int = 1, + band: bool = True, + as_mask: bool = False, + with_nodata: bool = False, + geographic: bool = True, + precision: int = -1, +) -> Iterator[dict[str, Any]]: ... diff --git a/stubs/rasterio/rasterio/fill.pyi b/stubs/rasterio/rasterio/fill.pyi new file mode 100644 index 000000000000..8f121f75a3a8 --- /dev/null +++ b/stubs/rasterio/rasterio/fill.pyi @@ -0,0 +1,11 @@ +from typing import Any + +from numpy.ma import MaskedArray +from numpy.typing import NDArray + +def fillnodata( + image: NDArray[Any] | MaskedArray[Any, Any], + mask: NDArray[Any] | None = None, + max_search_distance: float = 100.0, + smoothing_iterations: int = 0, +) -> NDArray[Any]: ... diff --git a/stubs/rasterio/rasterio/io.pyi b/stubs/rasterio/rasterio/io.pyi new file mode 100644 index 000000000000..c90cdd8eeb21 --- /dev/null +++ b/stubs/rasterio/rasterio/io.pyi @@ -0,0 +1,63 @@ +from types import TracebackType +from typing import Any, Self +from typing_extensions import deprecated + +from numpy.typing import DTypeLike +from rasterio._affine_types import Affine +from rasterio._filepath import FilePathBase as FilePathBase +from rasterio._io import ( + BufferedDatasetWriterBase as BufferedDatasetWriterBase, + DatasetReaderBase as DatasetReaderBase, + DatasetWriterBase as DatasetWriterBase, + MemoryFileBase as MemoryFileBase, +) +from rasterio._typing import CRSInput, FileOrBytes +from rasterio.transform import TransformMethodsMixin +from rasterio.windows import WindowMethodsMixin + +class DatasetReader(DatasetReaderBase, WindowMethodsMixin, TransformMethodsMixin): ... +class DatasetWriter(DatasetWriterBase, WindowMethodsMixin, TransformMethodsMixin): ... +class BufferedDatasetWriter(BufferedDatasetWriterBase, WindowMethodsMixin, TransformMethodsMixin): ... + +class MemoryFile(MemoryFileBase): + def __init__( + self, file_or_bytes: FileOrBytes | None = None, dirname: str | None = None, filename: str | None = None, ext: str = ".tif" + ) -> None: ... + def open( + self, + driver: str | None = None, + width: int | None = None, + height: int | None = None, + count: int | None = None, + crs: CRSInput | None = None, + transform: Affine | None = None, + dtype: DTypeLike | None = None, + nodata: float | None = None, + sharing: bool = False, + thread_safe: bool = False, + **kwargs: Any, + ) -> DatasetReader | DatasetWriter: ... + def __enter__(self) -> Self: ... + def __exit__( + self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None + ) -> bool | None: ... + +class ZipMemoryFile(MemoryFile): + def __init__(self, file_or_bytes: FileOrBytes | None = None) -> None: ... + def open( # type: ignore[override] + self, path: str, driver: str | None = None, sharing: bool = False, thread_safe: bool = False, **kwargs: Any + ) -> DatasetReader: ... + +@deprecated("FilePath is supplanted by rasterio.open's `opener` keyword argument and will be removed in 2.0.0.") +class FilePath(FilePathBase): + def __init__(self, filelike_obj: Any, dirname: str | None = None, filename: str | None = None) -> None: ... + def open( + self, driver: str | None = None, sharing: bool = False, thread_safe: bool = False, **kwargs: Any + ) -> DatasetReader: ... + def __enter__(self) -> Self: ... + def __exit__( + self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None + ) -> bool | None: ... + +def get_writer_for_driver(driver: str) -> type[DatasetWriter | BufferedDatasetWriter] | None: ... +def get_writer_for_path(path: str, driver: str | None = None) -> type[DatasetWriter | BufferedDatasetWriter] | None: ... diff --git a/stubs/rasterio/rasterio/mask.pyi b/stubs/rasterio/rasterio/mask.pyi new file mode 100644 index 000000000000..bfb30da2077e --- /dev/null +++ b/stubs/rasterio/rasterio/mask.pyi @@ -0,0 +1,33 @@ +import logging +from collections.abc import Iterable, Mapping +from typing import Any, Final + +from numpy.typing import NDArray +from rasterio._affine_types import Affine +from rasterio.errors import WindowError as WindowError +from rasterio.features import geometry_mask as geometry_mask, geometry_window as geometry_window +from rasterio.io import DatasetReader + +logger: Final[logging.Logger] + +def raster_geometry_mask( + dataset: DatasetReader, + shapes: Iterable[Mapping[str, Any]], + all_touched: bool = False, + invert: bool = False, + crop: bool = False, + pad: bool = False, + pad_width: float = 0.5, +) -> tuple[NDArray[Any], Affine, tuple[int, int, int, int]]: ... +def mask( + dataset: DatasetReader, + shapes: Iterable[Mapping[str, Any]], + all_touched: bool = False, + invert: bool = False, + nodata: float | None = None, + filled: bool = True, + crop: bool = False, + pad: bool = False, + pad_width: float = 0.5, + indexes: int | Iterable[int] | None = None, +) -> tuple[NDArray[Any], Affine]: ... diff --git a/stubs/rasterio/rasterio/merge.pyi b/stubs/rasterio/rasterio/merge.pyi new file mode 100644 index 000000000000..2a29936406d0 --- /dev/null +++ b/stubs/rasterio/rasterio/merge.pyi @@ -0,0 +1,64 @@ +import logging +import os +from collections.abc import Callable, Sequence +from typing import Any, Final, Literal, TypeAlias, overload +from typing_extensions import deprecated + +from numpy.typing import DTypeLike, NDArray +from rasterio._affine_types import Affine +from rasterio.enums import Resampling +from rasterio.io import DatasetReader + +logger: Final[logging.Logger] + +MethodFunction: TypeAlias = Callable[..., None] +MERGE_METHODS: Final[dict[str, MethodFunction]] + +_Arr: TypeAlias = NDArray[Any] + +def copy_first(merged_data: _Arr, new_data: _Arr, merged_mask: _Arr, new_mask: _Arr, **kwargs: Any) -> None: ... +def copy_last(merged_data: _Arr, new_data: _Arr, merged_mask: _Arr, new_mask: _Arr, **kwargs: Any) -> None: ... +def copy_min(merged_data: _Arr, new_data: _Arr, merged_mask: _Arr, new_mask: _Arr, **kwargs: Any) -> None: ... +def copy_max(merged_data: _Arr, new_data: _Arr, merged_mask: _Arr, new_mask: _Arr, **kwargs: Any) -> None: ... +def copy_sum(merged_data: _Arr, new_data: _Arr, merged_mask: _Arr, new_mask: _Arr, **kwargs: Any) -> None: ... +def copy_count(merged_data: _Arr, new_data: _Arr, merged_mask: _Arr, new_mask: _Arr, **kwargs: Any) -> None: ... + +@overload +def merge( + sources: Sequence[DatasetReader | str | os.PathLike[str]], + bounds: tuple[float, float, float, float] | None = None, + res: float | tuple[float, float] | None = None, + nodata: float | None = None, + dtype: DTypeLike | None = None, + *, + indexes: int | Sequence[int] | None = None, + output_count: int | None = None, + resampling: Resampling = ..., + method: Literal["first", "last", "min", "max", "sum", "count"] | MethodFunction = "first", + target_aligned_pixels: bool = False, + mem_limit: int = 64, + use_highest_res: bool = False, + masked: bool = False, + dst_path: str | os.PathLike[str] | None = None, + dst_kwds: dict[str, Any] | None = None, +) -> tuple[NDArray[Any], Affine]: ... +@overload +@deprecated("The `precision` parameter is unused since rasterio 1.3 and will be removed in 2.0.0.") +def merge( + sources: Sequence[DatasetReader | str | os.PathLike[str]], + bounds: tuple[float, float, float, float] | None = None, + res: float | tuple[float, float] | None = None, + nodata: float | None = None, + dtype: DTypeLike | None = None, + precision: int | None = None, + indexes: int | Sequence[int] | None = None, + output_count: int | None = None, + resampling: Resampling = ..., + method: Literal["first", "last", "min", "max", "sum", "count"] | MethodFunction = "first", + target_aligned_pixels: bool = False, + mem_limit: int = 64, + use_highest_res: bool = False, + masked: bool = False, + dst_path: str | os.PathLike[str] | None = None, + dst_kwds: dict[str, Any] | None = None, +) -> tuple[NDArray[Any], Affine]: ... diff --git a/stubs/rasterio/rasterio/path.pyi b/stubs/rasterio/rasterio/path.pyi new file mode 100644 index 000000000000..b5e935ebfd94 --- /dev/null +++ b/stubs/rasterio/rasterio/path.pyi @@ -0,0 +1,13 @@ +from typing import TypeAlias +from typing_extensions import deprecated + +from rasterio._path import _ParsedPath, _UnparsedPath +from rasterio.errors import RasterioDeprecationWarning as RasterioDeprecationWarning + +ParsedPath: TypeAlias = _ParsedPath +UnparsedPath: TypeAlias = _UnparsedPath + +@deprecated("rasterio.path.parse_path is deprecated; use rasterio._path._parse_path or pass paths directly to rasterio.open.") +def parse_path(path: str) -> _ParsedPath | _UnparsedPath: ... +@deprecated("rasterio.path.vsi_path is deprecated; use rasterio._path._vsi_path directly.") +def vsi_path(path: _ParsedPath | _UnparsedPath) -> str: ... diff --git a/stubs/rasterio/rasterio/plot.pyi b/stubs/rasterio/rasterio/plot.pyi new file mode 100644 index 000000000000..7d7f27c0a535 --- /dev/null +++ b/stubs/rasterio/rasterio/plot.pyi @@ -0,0 +1,42 @@ +import logging +from collections.abc import Mapping, Sequence +from typing import Any, Final, Literal + +from numpy.typing import NDArray +from rasterio._affine_types import Affine +from rasterio.io import DatasetReader as DatasetReader +from rasterio.transform import guard_transform as guard_transform + +logger: Final[logging.Logger] + +def get_plt() -> Any: ... +def show( + source: NDArray[Any] | DatasetReader | tuple[DatasetReader, int], + with_bounds: bool = True, + contour: bool = False, + contour_label_kws: Mapping[str, Any] | None = None, + indexes: Sequence[int] | None = None, + ax: Any | None = None, + title: str | None = None, + transform: Affine | None = None, + percent_range: tuple[float, float] | None = None, + adjust: bool = True, + **kwargs: Any, +) -> Any: ... +def plotting_extent( + source: NDArray[Any] | DatasetReader, transform: Affine | None = None +) -> tuple[float, float, float, float]: ... +def reshape_as_image(arr: NDArray[Any]) -> NDArray[Any]: ... +def reshape_as_raster(arr: NDArray[Any]) -> NDArray[Any]: ... +def show_hist( + source: NDArray[Any] | DatasetReader, + bins: int = 10, + masked: bool = True, + title: str = "Histogram", + ax: Any | None = None, + label: str | Sequence[str] | None = None, + range: tuple[float, float] | None = None, + **kwargs: Any, +) -> None: ... +def adjust_band(band: NDArray[Any], kind: Literal["linear", "log"] | None = None) -> NDArray[Any]: ... +def contrast_strech(arr: NDArray[Any], percent_range: tuple[float, float] = (2.0, 98.0)) -> NDArray[Any]: ... diff --git a/stubs/rasterio/rasterio/profiles.pyi b/stubs/rasterio/rasterio/profiles.pyi new file mode 100644 index 000000000000..558ce1ced50c --- /dev/null +++ b/stubs/rasterio/rasterio/profiles.pyi @@ -0,0 +1,13 @@ +from collections import UserDict +from typing import Any, ClassVar, Final + +class Profile(UserDict[str, Any]): + defaults: ClassVar[dict[str, Any]] + def __init__(self, data: dict[str, Any] = ..., **kwds: Any) -> None: ... + def __getitem__(self, key: str) -> Any: ... + def __setitem__(self, key: str, val: Any) -> None: ... + +class DefaultGTiffProfile(Profile): + defaults: ClassVar[dict[str, Any]] + +default_gtiff_profile: Final[DefaultGTiffProfile] diff --git a/stubs/rasterio/rasterio/rpc.pyi b/stubs/rasterio/rasterio/rpc.pyi new file mode 100644 index 000000000000..b9e6d1e16ebe --- /dev/null +++ b/stubs/rasterio/rasterio/rpc.pyi @@ -0,0 +1,43 @@ +from collections.abc import Sequence +from typing import Any, Self + +class RPC: + height_off: float + height_scale: float + lat_off: float + lat_scale: float + line_den_coeff: Sequence[float] + line_num_coeff: Sequence[float] + line_off: float + line_scale: float + long_off: float + long_scale: float + samp_den_coeff: Sequence[float] + samp_num_coeff: Sequence[float] + samp_off: float + samp_scale: float + err_bias: float | None + err_rand: float | None + def __init__( + self, + height_off: float, + height_scale: float, + lat_off: float, + lat_scale: float, + line_den_coeff: Sequence[float], + line_num_coeff: Sequence[float], + line_off: float, + line_scale: float, + long_off: float, + long_scale: float, + samp_den_coeff: Sequence[float], + samp_num_coeff: Sequence[float], + samp_off: float, + samp_scale: float, + err_bias: float | None = None, + err_rand: float | None = None, + ) -> None: ... + def to_dict(self) -> dict[str, Any]: ... + def to_gdal(self) -> dict[str, str]: ... + @classmethod + def from_gdal(cls, rpcs: dict[str, str]) -> Self: ... diff --git a/stubs/rasterio/rasterio/sample.pyi b/stubs/rasterio/rasterio/sample.pyi new file mode 100644 index 000000000000..8c87ecae7fcf --- /dev/null +++ b/stubs/rasterio/rasterio/sample.pyi @@ -0,0 +1,10 @@ +from collections.abc import Iterable, Iterator, Sequence +from typing import Any + +from numpy.typing import NDArray +from rasterio.io import DatasetReader + +def sample_gen( + dataset: DatasetReader, xy: Iterable[tuple[float, float]], indexes: int | Sequence[int] | None = None, masked: bool = False +) -> Iterator[NDArray[Any]]: ... +def sort_xy(xy: Iterable[tuple[float, float]]) -> list[tuple[float, float]]: ... diff --git a/stubs/rasterio/rasterio/session.pyi b/stubs/rasterio/rasterio/session.pyi new file mode 100644 index 000000000000..76ab6ea93eb2 --- /dev/null +++ b/stubs/rasterio/rasterio/session.pyi @@ -0,0 +1,103 @@ +from typing import Any + +def parse_bool(v: bool | str | int) -> bool: ... + +class Session: + @classmethod + def hascreds(cls, config: dict[str, Any]) -> bool: ... + def get_credential_options(self) -> dict[str, str]: ... + @staticmethod + def from_foreign_session(session: Any, cls: type[Session] | None = None) -> Session: ... + @staticmethod + def cls_from_path(path: str) -> type[Session]: ... + @staticmethod + def from_path(path: str, *args: Any, **kwargs: Any) -> Session: ... + @staticmethod + def aws_or_dummy(*args: Any, **kwargs: Any) -> Session: ... + @staticmethod + def from_environ(*args: Any, **kwargs: Any) -> Session: ... + +class DummySession(Session): + credentials: dict[str, str] + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + @classmethod + def hascreds(cls, config: dict[str, Any]) -> bool: ... + def get_credential_options(self) -> dict[str, str]: ... + +class AWSSession(Session): + requester_pays: bool + unsigned: bool + endpoint_url: str | None + def __init__( + self, + session: Any | None = None, + aws_unsigned: bool | None = None, + aws_access_key_id: str | None = None, + aws_secret_access_key: str | None = None, + aws_session_token: str | None = None, + region_name: str | None = None, + profile_name: str | None = None, + endpoint_url: str | None = None, + requester_pays: bool = False, + ) -> None: ... + @classmethod + def hascreds(cls, config: dict[str, Any]) -> bool: ... + @property + def credentials(self) -> dict[str, str]: ... + def get_credential_options(self) -> dict[str, str]: ... + +class OSSSession(Session): + def __init__( + self, oss_access_key_id: str | None = None, oss_secret_access_key: str | None = None, oss_endpoint: str | None = None + ) -> None: ... + @classmethod + def hascreds(cls, config: dict[str, Any]) -> bool: ... + @property + def credentials(self) -> dict[str, str]: ... + def get_credential_options(self) -> dict[str, str]: ... + +class GSSession(Session): + def __init__(self, google_application_credentials: str | None = None) -> None: ... + @classmethod + def hascreds(cls, config: dict[str, Any]) -> bool: ... + @property + def credentials(self) -> dict[str, str]: ... + def get_credential_options(self) -> dict[str, str]: ... + +class SwiftSession(Session): + def __init__( + self, + session: Any | None = None, + swift_storage_url: str | None = None, + swift_auth_token: str | None = None, + swift_auth_v1_url: str | None = None, + swift_user: str | None = None, + swift_key: str | None = None, + ) -> None: ... + @classmethod + def hascreds(cls, config: dict[str, Any]) -> bool: ... + @property + def credentials(self) -> dict[str, str]: ... + def get_credential_options(self) -> dict[str, str]: ... + +class AzureSession(Session): + unsigned: bool + storage_account: str | None + def __init__( + self, + azure_storage_connection_string: str | None = None, + azure_storage_account: str | None = None, + azure_storage_access_token: str | None = None, + azure_storage_access_key: str | None = None, + azure_storage_sas_token: str | None = None, + azure_unsigned: bool = False, + azure_tenant_id: str | None = None, + azure_client_id: str | None = None, + azure_federated_token_file: str | None = None, + azure_authority_host: str | None = None, + ) -> None: ... + @classmethod + def hascreds(cls, config: dict[str, Any]) -> bool: ... + @property + def credentials(self) -> dict[str, str]: ... + def get_credential_options(self) -> dict[str, str]: ... diff --git a/stubs/rasterio/rasterio/shutil.pyi b/stubs/rasterio/rasterio/shutil.pyi new file mode 100644 index 000000000000..f0da0b6e2e99 --- /dev/null +++ b/stubs/rasterio/rasterio/shutil.pyi @@ -0,0 +1,13 @@ +import os +from typing import Any + +def exists(path: str | os.PathLike[str]) -> bool: ... +def copy( + src: str | os.PathLike[str] | Any, + dst: str | os.PathLike[str], + driver: str | None = None, + strict: bool = True, + **creation_options: Any, +) -> None: ... +def copyfiles(src: str | os.PathLike[str], dst: str | os.PathLike[str]) -> None: ... +def delete(path: str | os.PathLike[str], driver: str | None = None) -> None: ... diff --git a/stubs/rasterio/rasterio/stack.pyi b/stubs/rasterio/rasterio/stack.pyi new file mode 100644 index 000000000000..56a1553c55c9 --- /dev/null +++ b/stubs/rasterio/rasterio/stack.pyi @@ -0,0 +1,28 @@ +import logging +import os +from collections.abc import Sequence +from typing import Any, Final + +from numpy.typing import DTypeLike, NDArray +from rasterio._affine_types import Affine +from rasterio.enums import Resampling +from rasterio.io import DatasetReader + +logger: Final[logging.Logger] + +def stack( + sources: Sequence[DatasetReader | str | os.PathLike[str]], + bounds: tuple[float, float, float, float] | None = None, + res: float | tuple[float, float] | None = None, + nodata: float | None = None, + dtype: DTypeLike | None = None, + indexes: int | Sequence[int] | None = None, + output_count: int | None = None, + resampling: Resampling = ..., + target_aligned_pixels: bool = False, + mem_limit: int = 64, + use_highest_res: bool = False, + masked: bool = False, + dst_path: str | os.PathLike[str] | None = None, + dst_kwds: dict[str, Any] | None = None, +) -> tuple[NDArray[Any], Affine]: ... diff --git a/stubs/rasterio/rasterio/tools.pyi b/stubs/rasterio/rasterio/tools.pyi new file mode 100644 index 000000000000..0d78bca77964 --- /dev/null +++ b/stubs/rasterio/rasterio/tools.pyi @@ -0,0 +1,19 @@ +import os +from collections.abc import Callable, Iterable +from typing import Any, Final + +class JSONSequenceTool: + func: Callable[..., Iterable[Any]] + def __init__(self, func: Callable[..., Iterable[Any]]) -> None: ... + def __call__( + self, + src_path: str | os.PathLike[str], + dst_path: str | os.PathLike[str], + src_kwargs: dict[str, Any] | None = None, + dst_kwargs: dict[str, Any] | None = None, + func_args: Iterable[Any] | None = None, + func_kwargs: dict[str, Any] | None = None, + config: dict[str, Any] | None = None, + ) -> None: ... + +dataset_features_tool: Final[JSONSequenceTool] diff --git a/stubs/rasterio/rasterio/transform.pyi b/stubs/rasterio/rasterio/transform.pyi new file mode 100644 index 000000000000..98e32e6e9c5e --- /dev/null +++ b/stubs/rasterio/rasterio/transform.pyi @@ -0,0 +1,107 @@ +from collections.abc import Callable, Sequence +from typing import Any, Final, Literal, Self, TypeAlias, overload +from typing_extensions import deprecated + +from rasterio._affine_types import Affine as Affine +from rasterio._transform import GCPTransformerBase, RPCTransformerBase +from rasterio.control import GroundControlPoint +from rasterio.enums import TransformDirection as TransformDirection, TransformMethod as TransformMethod +from rasterio.errors import RasterioDeprecationWarning as RasterioDeprecationWarning +from rasterio.rpc import RPC + +_Sextuple: TypeAlias = tuple[float, float, float, float, float, float] +_OffsetOptions: TypeAlias = Literal["center", "ul", "ur", "ll", "lr"] +_RoundOperation: TypeAlias = Callable[[float], int] + +IDENTITY: Final[Affine] +GDAL_IDENTITY: Final[_Sextuple] + +class TransformMethodsMixin: + def xy( + self, + row: int | Sequence[int], + col: int | Sequence[int], + z: float | Sequence[float] | None = None, + offset: _OffsetOptions = "center", + transform_method: TransformMethod = ..., + **rpc_options: Any, + ) -> tuple[float, float] | tuple[list[float], list[float]]: ... + def index( + self, + x: float | Sequence[float], + y: float | Sequence[float], + z: float | Sequence[float] | None = None, + op: _RoundOperation | None = None, + precision: int | None = None, + transform_method: TransformMethod = ..., + **rpc_options: Any, + ) -> tuple[int, int] | tuple[list[int], list[int]]: ... + +def tastes_like_gdal(seq: Affine | _Sextuple) -> bool: ... +def guard_transform(transform: Affine | _Sextuple) -> Affine: ... +def from_origin(west: float, north: float, xsize: float, ysize: float) -> Affine: ... +def from_bounds(west: float, south: float, east: float, north: float, width: float, height: float) -> Affine: ... +def array_bounds(height: int, width: int, transform: Affine) -> tuple[float, float, float, float]: ... +def from_gcps(gcps: Sequence[GroundControlPoint]) -> Affine: ... +def xy( + transform: Affine | Sequence[GroundControlPoint] | RPC, + rows: int | Sequence[int], + cols: int | Sequence[int], + zs: float | Sequence[float] | None = None, + offset: _OffsetOptions = "center", + **rpc_options: Any, +) -> tuple[float, float] | tuple[list[float], list[float]]: ... +def rowcol( + transform: Affine | Sequence[GroundControlPoint] | RPC, + xs: float | Sequence[float], + ys: float | Sequence[float], + zs: float | Sequence[float] | None = None, + op: _RoundOperation | None = None, + precision: int | None = None, + **rpc_options: Any, +) -> tuple[int, int] | tuple[list[int], list[int]]: ... +def get_transformer(transform: Affine | Sequence[GroundControlPoint] | RPC, **rpc_options: Any) -> type[TransformerBase]: ... + +class TransformerBase: + def __init__(self) -> None: ... + def xy( + self, + rows: int | Sequence[int], + cols: int | Sequence[int], + zs: float | Sequence[float] | None = None, + offset: _OffsetOptions = "center", + ) -> tuple[float, float] | tuple[list[float], list[float]]: ... + + @overload + def rowcol( + self, + xs: float | Sequence[float], + ys: float | Sequence[float], + zs: float | Sequence[float] | None = None, + op: _RoundOperation | None = None, + ) -> tuple[int, int] | tuple[list[int], list[int]]: ... + @overload + @deprecated("The `precision` parameter is unused since rasterio 1.3 and will be removed in 2.0.0.") + def rowcol( + self, + xs: float | Sequence[float], + ys: float | Sequence[float], + zs: float | Sequence[float] | None = None, + op: _RoundOperation | None = None, + precision: int | None = None, + ) -> tuple[int, int] | tuple[list[int], list[int]]: ... + +class GDALTransformerBase(TransformerBase): + def __init__(self) -> None: ... + def close(self) -> None: ... + def __enter__(self) -> Self: ... + def __exit__(self, *args: object) -> None: ... + +class AffineTransformer(TransformerBase): + def __init__(self, affine_transform: Affine | _Sextuple) -> None: ... + +class GCPTransformer(GCPTransformerBase, GDALTransformerBase): + def __init__(self, gcps: Sequence[GroundControlPoint], tps: bool = False) -> None: ... + +class RPCTransformer(RPCTransformerBase, GDALTransformerBase): + def __init__(self, rpcs: RPC, **rpc_options: Any) -> None: ... diff --git a/stubs/rasterio/rasterio/vrt.pyi b/stubs/rasterio/rasterio/vrt.pyi new file mode 100644 index 000000000000..00f0212e7504 --- /dev/null +++ b/stubs/rasterio/rasterio/vrt.pyi @@ -0,0 +1,13 @@ +from types import TracebackType +from typing import Self + +from rasterio._warp import WarpedVRTReaderBase +from rasterio.transform import TransformMethodsMixin +from rasterio.windows import WindowMethodsMixin + +class WarpedVRT(WarpedVRTReaderBase, WindowMethodsMixin, TransformMethodsMixin): + def __enter__(self) -> Self: ... + def __exit__( + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None + ) -> None: ... + def __del__(self) -> None: ... diff --git a/stubs/rasterio/rasterio/warp.pyi b/stubs/rasterio/rasterio/warp.pyi new file mode 100644 index 000000000000..c6844532963e --- /dev/null +++ b/stubs/rasterio/rasterio/warp.pyi @@ -0,0 +1,84 @@ +from _typeshed import Incomplete +from collections.abc import Mapping, Sequence +from typing import Any, Final, TypeAlias, overload +from typing_extensions import deprecated + +from numpy.typing import ArrayLike, NDArray +from rasterio._affine_types import Affine +from rasterio._typing import CRSInput +from rasterio.control import GroundControlPoint +from rasterio.enums import Resampling +from rasterio.rpc import RPC + +_Resolution: TypeAlias = tuple[float, float] | float +_Gcps: TypeAlias = Sequence[GroundControlPoint] +_Rpcs: TypeAlias = RPC | Mapping[str, Any] + +SUPPORTED_RESAMPLING: Final[list[Resampling]] + +def transform( + src_crs: CRSInput, dst_crs: CRSInput, xs: ArrayLike, ys: ArrayLike, zs: ArrayLike | None = None +) -> tuple[list[float], list[float]] | tuple[list[float], list[float], list[float]]: ... + +@overload +def transform_geom( + src_crs: CRSInput, dst_crs: CRSInput, geom: Mapping[str, Any] | Sequence[Mapping[str, Any]], *, precision: float = -1 +) -> dict[str, Any] | list[dict[str, Any]]: ... +@overload +@deprecated( + "`antimeridian_cutting` and `antimeridian_offset` are no-ops since GDAL 2.2 " + "and will be removed in a future rasterio release. Call transform_geom " + "without them." +) +def transform_geom( + src_crs: CRSInput, + dst_crs: CRSInput, + geom: Mapping[str, Any] | Sequence[Mapping[str, Any]], + antimeridian_cutting: bool | None = None, + antimeridian_offset: float | None = None, + precision: float = -1, +) -> dict[str, Any] | list[dict[str, Any]]: ... + +def transform_bounds( + src_crs: CRSInput, dst_crs: CRSInput, left: float, bottom: float, right: float, top: float, densify_pts: int = 21 +) -> tuple[float, float, float, float]: ... +def reproject( + source: ArrayLike | Incomplete, + destination: ArrayLike | Incomplete | None = None, + src_transform: Affine | None = None, + gcps: _Gcps | None = None, + rpcs: _Rpcs | None = None, + src_crs: CRSInput | None = None, + src_nodata: float | None = None, + dst_transform: Affine | None = None, + dst_crs: CRSInput | None = None, + dst_nodata: float | None = None, + dst_resolution: _Resolution | None = None, + src_alpha: int = 0, + dst_alpha: int = 0, + masked: bool = False, + resampling: Resampling = ..., + num_threads: int = 1, + init_dest_nodata: bool = True, + warp_mem_limit: int = 0, + src_geoloc_array: NDArray[Any] | None = None, + **kwargs: Any, +) -> tuple[NDArray[Any], Affine]: ... +def aligned_target(transform: Affine, width: int, height: int, resolution: _Resolution) -> tuple[Affine, int, int]: ... +def calculate_default_transform( + src_crs: CRSInput, + dst_crs: CRSInput, + width: int, + height: int, + left: float | None = None, + bottom: float | None = None, + right: float | None = None, + top: float | None = None, + gcps: _Gcps | None = None, + rpcs: _Rpcs | None = None, + resolution: _Resolution | None = None, + dst_width: int | None = None, + dst_height: int | None = None, + src_geoloc_array: NDArray[Any] | None = None, + **kwargs: Any, +) -> tuple[Affine, int, int]: ... diff --git a/stubs/rasterio/rasterio/windows.pyi b/stubs/rasterio/rasterio/windows.pyi new file mode 100644 index 000000000000..db7ea49e8272 --- /dev/null +++ b/stubs/rasterio/rasterio/windows.pyi @@ -0,0 +1,79 @@ +from collections.abc import Callable, Sequence +from typing import Any, Self, TypeAlias, overload +from typing_extensions import deprecated + +from numpy.typing import NDArray +from rasterio._affine_types import Affine +from rasterio.errors import RasterioDeprecationWarning as RasterioDeprecationWarning, WindowError as WindowError + +_Bounds: TypeAlias = tuple[float, float, float, float] +_Ranges: TypeAlias = tuple[tuple[int, int], tuple[int, int]] +_Slices: TypeAlias = tuple[slice, slice] + +class WindowMethodsMixin: + @overload + def window(self, left: float, bottom: float, right: float, top: float) -> Window: ... + @overload + @deprecated("The `precision` parameter is unused since rasterio 1.3 and will be removed in 2.0.0.") + def window(self, left: float, bottom: float, right: float, top: float, precision: int | None = None) -> Window: ... + + def window_transform(self, window: Window) -> Affine: ... + def window_bounds(self, window: Window) -> _Bounds: ... + +def iter_args(function: Callable[..., Any]) -> Callable[..., Any]: ... +def toranges(window: Window | _Ranges) -> _Ranges: ... +def get_data_window(arr: NDArray[Any], nodata: float | None = None) -> Window: ... +def union(*windows: Window) -> Window: ... +def intersection(*windows: Window) -> Window: ... +def intersect(*windows: Window) -> bool: ... + +@overload +def from_bounds(left: float, bottom: float, right: float, top: float, transform: Affine | None = None) -> Window: ... +@overload +@deprecated( + "`height`, `width`, and `precision` on windows.from_bounds are unused since rasterio 1.3 and will be removed in 2.0.0." +) +def from_bounds( + left: float, + bottom: float, + right: float, + top: float, + transform: Affine | None = None, + height: int | None = None, + width: int | None = None, + precision: int | None = None, +) -> Window: ... + +def transform(window: Window, transform: Affine) -> Affine: ... +def bounds(window: Window, transform: Affine, height: int = 0, width: int = 0) -> _Bounds: ... +def crop(window: Window, height: int, width: int) -> Window: ... +def evaluate(window: Window, height: int, width: int, boundless: bool = False) -> Window: ... +def shape(window: Window, height: int = -1, width: int = -1) -> tuple[int, int]: ... +def window_index(window: Window, height: int = 0, width: int = 0) -> _Slices: ... +def round_window_to_full_blocks( + window: Window, block_shapes: Sequence[tuple[int, int]], height: int = 0, width: int = 0 +) -> Window: ... +def validate_length_value(instance: object, attribute: object, value: float) -> None: ... +def subdivide(window: Window, height: int, width: int) -> list[Window]: ... + +class Window: + col_off: float + row_off: float + width: float + height: float + def __init__(self, col_off: float, row_off: float, width: float, height: float) -> None: ... + def flatten(self) -> tuple[float, float, float, float]: ... + def todict(self) -> dict[str, float]: ... + def toranges(self) -> _Ranges: ... + def toslices(self) -> _Slices: ... + @classmethod + def from_slices( + cls, rows: slice | Sequence[int], cols: slice | Sequence[int], height: int = -1, width: int = -1, boundless: bool = False + ) -> Self: ... + def round_lengths(self, **kwds: Any) -> Window: ... + @deprecated("Window.round_shape is deprecated and will be removed in Rasterio 2.0.0; use round_lengths instead.") + def round_shape(self, **kwds: Any) -> Window: ... + def round_offsets(self, **kwds: Any) -> Window: ... + def round(self, ndigits: int | None = None) -> Window: ... + def crop(self, height: int, width: int) -> Window: ... + def intersection(self, other: Window) -> Window: ...