Skip to content

Commit 693b50c

Browse files
[rasterio] Accept int EPSG codes and any to_wkt provider in CRSInput
`CRS.from_user_input` dispatches on a `to_wkt` method before checking any concrete type, and reads a bare `int` as an EPSG code. Model the former as a `_SupportsToWkt` Protocol rather than taking a dependency on pyproj.
1 parent 89c00d7 commit 693b50c

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from __future__ import annotations
2+
3+
from typing_extensions import assert_type
4+
5+
import rasterio.warp
6+
from rasterio.crs import CRS
7+
from rasterio.io import MemoryFile
8+
9+
10+
class ForeignCRS:
11+
def to_wkt(self) -> str:
12+
return ""
13+
14+
15+
assert_type(rasterio.warp.transform_bounds(4326, 3857, 0.0, 0.0, 1.0, 1.0), tuple[float, float, float, float])
16+
rasterio.warp.transform_bounds(ForeignCRS(), ForeignCRS(), 0.0, 0.0, 1.0, 1.0)
17+
rasterio.warp.transform_bounds(CRS.from_epsg(4326), "EPSG:3857", 0.0, 0.0, 1.0, 1.0)
18+
rasterio.warp.transform_bounds({"init": "EPSG:4326"}, CRS.from_epsg(3857), 0.0, 0.0, 1.0, 1.0)
19+
rasterio.warp.transform_bounds(object(), 3857, 0.0, 0.0, 1.0, 1.0) # type: ignore
20+
rasterio.warp.transform(4326, ForeignCRS(), [0.0], [0.0])
21+
rasterio.warp.calculate_default_transform(4326, ForeignCRS(), 10, 10, left=0.0, bottom=0.0, right=1.0, top=1.0)
22+
MemoryFile().open(driver="GTiff", width=1, height=1, count=1, dtype="uint8", crs=4326)
23+
MemoryFile().open(driver="GTiff", width=1, height=1, count=1, dtype="uint8", crs=ForeignCRS())

stubs/rasterio/rasterio/_typing.pyi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,19 @@ class _SupportsGeoInterface(Protocol):
1616
@property
1717
def __geo_interface__(self) -> Mapping[str, Any]: ...
1818

19+
@type_check_only
20+
class _SupportsToWkt(Protocol):
21+
def to_wkt(self) -> str: ...
22+
1923
# A GeoJSON-like mapping, or any object exposing one through the
2024
# `__geo_interface__` protocol (e.g. shapely / geopandas geometries).
2125
# The runtime unwraps `__geo_interface__` before use, so both forms are
2226
# accepted anywhere a geometry is expected.
2327
Geometry: TypeAlias = Mapping[str, Any] | _SupportsGeoInterface # noqa: Y047
2428
Colormap: TypeAlias = dict[int, tuple[int, int, int] | tuple[int, int, int, int]]
25-
CRSInput: TypeAlias = str | dict[str, str] | CRS
29+
# A WKT / PROJ string, an EPSG code, a PROJ dict, or any object exposing
30+
# `to_wkt` (e.g. a pyproj CRS). `CRS.from_user_input` normalizes all of them.
31+
CRSInput: TypeAlias = str | int | dict[str, str] | CRS | _SupportsToWkt
2632
FileOrBytes: TypeAlias = BinaryIO | bytes
2733
Indexes: TypeAlias = int | Sequence[int]
2834
NumType: TypeAlias = int | float

0 commit comments

Comments
 (0)