|
26 | 26 | import numpy as np |
27 | 27 | import xarray as xr |
28 | 28 | from dask_image import ndinterp |
| 29 | +import pyproj |
29 | 30 |
|
30 | 31 | from .constants import ( |
31 | 32 | AffineTransformMatrix, |
32 | 33 | AggFunction, |
33 | 34 | FillValues, |
34 | 35 | FloatInt, |
35 | 36 | PreventNaNPropagations, |
| 37 | + SCALE_LIMIT, |
36 | 38 | SpatialAggMethods, |
37 | 39 | SpatialInterpMethodInt, |
38 | 40 | SpatialInterpMethods, |
|
44 | 46 | _get_prevent_nan_propagation, |
45 | 47 | _get_spatial_agg_method, |
46 | 48 | _get_spatial_interp_method_int, |
| 49 | + _prep_spatial_interp_methods_downscale, |
47 | 50 | _select_variables, |
48 | 51 | normalize_grid_mapping, |
49 | 52 | ) |
@@ -243,6 +246,49 @@ def resample_dataset( |
243 | 246 | return xr.Dataset(data_vars=data_vars, coords=coords, attrs=dataset.attrs) |
244 | 247 |
|
245 | 248 |
|
| 249 | +def _downscale_source_dataset( |
| 250 | + source_ds: xr.Dataset, |
| 251 | + source_gm: GridMapping, |
| 252 | + target_gm: GridMapping, |
| 253 | + interp_methods: SpatialInterpMethods | None, |
| 254 | + agg_methods: SpatialAggMethods | None, |
| 255 | + prevent_nan_propagations: PreventNaNPropagations, |
| 256 | + transformer: pyproj.Transformer | None = None, |
| 257 | +) -> (xr.Dataset, GridMapping): |
| 258 | + if interp_methods in [0, "nearest"]: |
| 259 | + return source_ds, source_gm |
| 260 | + |
| 261 | + if transformer is None: |
| 262 | + target_xres = target_gm.x_res |
| 263 | + target_yres = target_gm.y_res |
| 264 | + else: |
| 265 | + target_bbox = transformer.transform_bounds(*target_gm.xy_bbox) |
| 266 | + target_xres = (target_bbox[2] - target_bbox[0]) / target_gm.width |
| 267 | + target_yres = (target_bbox[3] - target_bbox[1]) / target_gm.height |
| 268 | + |
| 269 | + x_scale = source_gm.x_res / target_xres |
| 270 | + y_scale = source_gm.y_res / target_yres |
| 271 | + if x_scale >= SCALE_LIMIT and y_scale >= SCALE_LIMIT: |
| 272 | + return source_ds, source_gm |
| 273 | + |
| 274 | + w, h = np.floor(x_scale * source_gm.width), np.floor(y_scale * source_gm.height) |
| 275 | + downscaled_size = (w if w >= 2 else 2, h if h >= 2 else 2) |
| 276 | + |
| 277 | + source_ds = resample_dataset( |
| 278 | + source_ds, |
| 279 | + ((1 / x_scale, 0, 0), (0, 1 / y_scale, 0)), |
| 280 | + (source_gm.xy_dim_names[1], source_gm.xy_dim_names[0]), |
| 281 | + downscaled_size, |
| 282 | + source_gm.tile_size, |
| 283 | + _prep_spatial_interp_methods_downscale(interp_methods), |
| 284 | + agg_methods, |
| 285 | + prevent_nan_propagations, |
| 286 | + ) |
| 287 | + source_gm = GridMapping.from_dataset(source_ds) |
| 288 | + |
| 289 | + return source_ds, source_gm |
| 290 | + |
| 291 | + |
246 | 292 | def _resample_array( |
247 | 293 | array: da.Array, |
248 | 294 | affine_matrix: AffineTransformMatrix, |
|
0 commit comments