|
11 | 11 | from typing import TYPE_CHECKING, Any |
12 | 12 |
|
13 | 13 | import earthaccess |
| 14 | +import rasterio.features |
14 | 15 | from geojson_pydantic import Feature, FeatureCollection |
15 | 16 | from isodate import parse_datetime as _parse_datetime |
16 | | -from rasterio.features import bounds |
17 | 17 | from rasterio.warp import transform_bounds |
18 | 18 | from urllib3.response import HTTPException # type: ignore |
19 | 19 |
|
@@ -212,18 +212,76 @@ def calculate_time_series_request_size( |
212 | 212 | def get_geojson_bounds( |
213 | 213 | geojson: Feature | FeatureCollection, |
214 | 214 | ) -> tuple[float, float, float, float]: |
215 | | - """Get the global bounding box for a geojson Feature or FeatureCollection""" |
216 | | - fc = geojson |
217 | | - if isinstance(fc, Feature): |
218 | | - fc = FeatureCollection(type="FeatureCollection", features=[geojson]) |
| 215 | + """Get the global bounding box for a GeoJSON Feature or FeatureCollection. |
219 | 216 |
|
220 | | - all_bounds = [ |
221 | | - bounds(feature.model_dump(exclude_none=True)) for feature in fc.features |
222 | | - ] |
| 217 | + Parameters |
| 218 | + ---------- |
| 219 | + geojson |
| 220 | + A GeoJSON Feature or FeatureCollection whose coordinates are expressed |
| 221 | + in WGS84 longitude/latitude. |
223 | 222 |
|
224 | | - minx = min(bound[0] for bound in all_bounds) |
225 | | - miny = min(bound[1] for bound in all_bounds) |
226 | | - maxx = max(bound[2] for bound in all_bounds) |
227 | | - maxy = max(bound[3] for bound in all_bounds) |
| 223 | + Returns |
| 224 | + ------- |
| 225 | + tuple[float, float, float, float] |
| 226 | + A tuple of `(minx, miny, maxx, maxy)` representing the bounding box in |
| 227 | + WGS84 degrees. |
228 | 228 |
|
229 | | - return (minx, miny, maxx, maxy) |
| 229 | + Examples |
| 230 | + -------- |
| 231 | + The bounding box for a point is simply the same point at both corners of the |
| 232 | + box: |
| 233 | +
|
| 234 | + >>> point = Feature( |
| 235 | + ... **{ |
| 236 | + ... "type": "Feature", |
| 237 | + ... "geometry": { |
| 238 | + ... "type": "Point", |
| 239 | + ... "coordinates": [12.38272, 53.46385], |
| 240 | + ... }, |
| 241 | + ... "properties": None, |
| 242 | + ... } |
| 243 | + ... ) |
| 244 | + >>> get_geojson_bounds(point) |
| 245 | + (12.38272, 53.46385, 12.38272, 53.46385) |
| 246 | +
|
| 247 | + For a polygon, the bounds are simply the smallest and largest coordinates |
| 248 | + in both the x and y directions amongst all points of the polygon: |
| 249 | +
|
| 250 | + >>> polygon = Feature( |
| 251 | + ... **{ |
| 252 | + ... "type": "Feature", |
| 253 | + ... "geometry": { |
| 254 | + ... "type": "Polygon", |
| 255 | + ... "coordinates": [ |
| 256 | + ... [ |
| 257 | + ... [13.38272, 52.46385], |
| 258 | + ... [13.42786, 52.46385], |
| 259 | + ... [13.42786, 52.48445], |
| 260 | + ... [13.38272, 52.48445], |
| 261 | + ... [13.38272, 52.46385], |
| 262 | + ... ] |
| 263 | + ... ], |
| 264 | + ... }, |
| 265 | + ... "properties": None, |
| 266 | + ... } |
| 267 | + ... ) |
| 268 | + >>> get_geojson_bounds(polygon) |
| 269 | + (13.38272, 52.46385, 13.42786, 52.48445) |
| 270 | +
|
| 271 | + For a feature collection, the bounds are the smallest and largest |
| 272 | + coordinates across all points of all geometries in the collection, as if a |
| 273 | + single feature with all points from all geometries were supplied instead: |
| 274 | +
|
| 275 | + >>> fc = FeatureCollection(type="FeatureCollection", features=[point, polygon]) |
| 276 | + >>> get_geojson_bounds(fc) |
| 277 | + (12.38272, 52.46385, 13.42786, 53.46385) |
| 278 | +
|
| 279 | + Notice that in the result above, the `minx` (first) and `maxy` (last) |
| 280 | + coordinates come from the point, because it sits to the west and north of |
| 281 | + the polygon, while the others (`maxx` and `miny`) come from the polygon. |
| 282 | + """ |
| 283 | + return rasterio.features.bounds( |
| 284 | + FeatureCollection(type="FeatureCollection", features=[geojson]) |
| 285 | + if isinstance(geojson, Feature) |
| 286 | + else geojson |
| 287 | + ) |
0 commit comments