6
6
from urllib .parse import urlparse
7
7
8
8
import attr
9
- import pyproj
10
9
import rasterio
11
10
from morecantile import TileMatrixSet
12
11
from openeo_pg_parser_networkx .pg_schema import BoundingBox
13
12
from rasterio .errors import RasterioIOError
14
13
from rasterio .transform import array_bounds
14
+ from rasterio .warp import transform_bounds
15
15
from rio_tiler .constants import WEB_MERCATOR_TMS , WGS84_CRS
16
16
from rio_tiler .errors import (
17
17
AssetAsBandError ,
25
25
from rio_tiler .tasks import multi_arrays
26
26
from rio_tiler .types import AssetInfo , BBox , Indexes
27
27
from rio_tiler .utils import cast_to_sequence
28
+ from typing_extension import TypedDict
28
29
29
- from .processes .implementations .utils import to_rasterio_crs
30
+
31
+ class Dims (TypedDict ):
32
+ """Estimate Dimensions."""
33
+
34
+ width : int
35
+ height : int
36
+ crs : rasterio .crs .CRS
37
+ bbox : List [float ]
30
38
31
39
32
40
def _estimate_output_dimensions (
@@ -35,7 +43,7 @@ def _estimate_output_dimensions(
35
43
bands : Optional [list [str ]],
36
44
width : Optional [int ] = None ,
37
45
height : Optional [int ] = None ,
38
- ) -> Dict [ str , Any ] :
46
+ ) -> Dims :
39
47
"""
40
48
Estimate output dimensions based on items and spatial extent.
41
49
@@ -50,7 +58,6 @@ def _estimate_output_dimensions(
50
58
Dictionary containing:
51
59
- width: Estimated or specified width
52
60
- height: Estimated or specified height
53
- - item_crs: CRS of the items
54
61
- crs: Target CRS to use
55
62
- bbox: Bounding box as a list [west, south, east, north]
56
63
"""
@@ -70,7 +77,7 @@ def _estimate_output_dimensions(
70
77
raise ValueError ("Missing required input: bands" )
71
78
72
79
# Extract CRS and resolution information from items
73
- item_crs = None
80
+ item_crs : rasterio . crs . CRS = None
74
81
x_resolutions = []
75
82
y_resolutions = []
76
83
@@ -87,14 +94,15 @@ def _estimate_output_dimensions(
87
94
if src_dst .transform :
88
95
x_resolutions .append (abs (src_dst .transform .a ))
89
96
y_resolutions .append (abs (src_dst .transform .e ))
97
+
90
98
# If no transform, check for assets metadata
91
99
else :
92
100
for _ , asset in item .get ("assets" , {}).items ():
93
101
# Get resolution from asset metadata
94
- asset_transform = asset .get ("proj:transform" )
95
- if asset_transform :
102
+ if asset_transform := asset .get ("proj:transform" ):
96
103
x_resolutions .append (abs (asset_transform [0 ]))
97
104
y_resolutions .append (abs (asset_transform [4 ]))
105
+
98
106
else :
99
107
# Default to 1024x1024 if no resolution is found
100
108
x_resolutions .append (1024 )
@@ -105,8 +113,7 @@ def _estimate_output_dimensions(
105
113
y_resolution = min (y_resolutions ) if y_resolutions else None
106
114
107
115
# Get target CRS and bounds
108
- projcrs = pyproj .crs .CRS (spatial_extent .crs or "epsg:4326" )
109
- crs = to_rasterio_crs (projcrs )
116
+ crs = rasterio .crs .CRS .from_user_input (spatial_extent .crs or "epsg:4326" )
110
117
111
118
# Convert bounds to the same CRS if needed
112
119
bbox = [
@@ -119,11 +126,6 @@ def _estimate_output_dimensions(
119
126
# If item CRS is different from spatial_extent CRS, we need to reproject the resolution
120
127
if item_crs and item_crs != crs :
121
128
# Calculate approximate resolution in target CRS
122
- transformer = pyproj .Transformer .from_crs (
123
- item_crs ,
124
- crs ,
125
- always_xy = True ,
126
- )
127
129
# Get reprojected resolution using a small 1x1 degree box at the center of the bbox
128
130
center_x = (bbox [0 ] + bbox [2 ]) / 2
129
131
center_y = (bbox [1 ] + bbox [3 ]) / 2
@@ -133,7 +135,8 @@ def _estimate_output_dimensions(
133
135
center_x + x_resolution ,
134
136
center_y + y_resolution ,
135
137
]
136
- dst_box = transformer .transform_bounds (* src_box )
138
+ dst_box = transform_bounds (item_crs , crs , * src_box , densify_pts = 21 )
139
+
137
140
x_resolution = abs (dst_box [2 ] - dst_box [0 ])
138
141
y_resolution = abs (dst_box [3 ] - dst_box [1 ])
139
142
@@ -155,13 +158,12 @@ def _estimate_output_dimensions(
155
158
)
156
159
157
160
# Return all information needed for rendering
158
- return {
159
- "width" : width ,
160
- "height" : height ,
161
- "item_crs" : item_crs ,
162
- "crs" : crs ,
163
- "bbox" : bbox ,
164
- }
161
+ return Dims (
162
+ width = width ,
163
+ height = height ,
164
+ crs = crs ,
165
+ bbox = bbox ,
166
+ )
165
167
166
168
167
169
def _reader (item : Dict [str , Any ], bbox : BBox , ** kwargs : Any ) -> ImageData :
0 commit comments