From 708d8ef8decb227d1a1337fff2f6bf0176991255 Mon Sep 17 00:00:00 2001 From: Nicholas Delli Carpini Date: Wed, 11 Dec 2024 10:48:52 -0500 Subject: [PATCH 1/4] add crs to GetMetadata requests --- xpublish_wms/query.py | 5 +++++ xpublish_wms/wms/get_metadata.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/xpublish_wms/query.py b/xpublish_wms/query.py index e2270a9..d8f3af7 100644 --- a/xpublish_wms/query.py +++ b/xpublish_wms/query.py @@ -44,6 +44,10 @@ class WMSGetMetadataQuery(WMSBaseQuery): description="Bounding box to use for calculating min and max in the format 'minx,miny,maxx,maxy'", ), ) + crs: Literal["EPSG:4326", "EPSG:3857"] = Field( + "EPSG:4326", + description="Coordinate reference system to use for the query. EPSG:4326 and EPSG:3857 are supported for this request", + ) time: Optional[str] = ( Field( None, @@ -273,6 +277,7 @@ def wms_query( day=day, range=range, bbox=bbox, + crs=crs if srs is None else srs, time=time, elevation=elevation, ) diff --git a/xpublish_wms/wms/get_metadata.py b/xpublish_wms/wms/get_metadata.py index f993e4d..417ae8e 100644 --- a/xpublish_wms/wms/get_metadata.py +++ b/xpublish_wms/wms/get_metadata.py @@ -105,7 +105,7 @@ def get_minmax( bbox=query.bbox if not entire_layer else "-180,-90,180,90", width=1 if entire_layer else 512, height=1 if entire_layer else 512, - crs="EPSG:4326", + crs=query.crs, time=query.time, elevation=query.elevation, styles="raster/default", From d8218d90d8fbe77f09e4489e683e5302d147b334 Mon Sep 17 00:00:00 2001 From: Nicholas Delli Carpini Date: Wed, 11 Dec 2024 13:44:05 -0500 Subject: [PATCH 2/4] check for coord in variables for additional_coords --- xpublish_wms/wms/get_metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xpublish_wms/wms/get_metadata.py b/xpublish_wms/wms/get_metadata.py index 417ae8e..1220155 100644 --- a/xpublish_wms/wms/get_metadata.py +++ b/xpublish_wms/wms/get_metadata.py @@ -139,7 +139,7 @@ def get_layer_details(ds: xr.Dataset, layer_name: str) -> dict: additional_coords = ds.gridded.additional_coords(da) additional_coord_values = { - coord: da.cf.coords[coord].values.tolist() for coord in additional_coords + coord: (da.cf.coords[coord] if coord in da.cf.coords else da[coord]).values.tolist() for coord in additional_coords } return { From 043b489c9d68e2d08a8665db458cc656b54f88e2 Mon Sep 17 00:00:00 2001 From: Nicholas Delli Carpini Date: Thu, 12 Dec 2024 10:27:14 -0500 Subject: [PATCH 3/4] use default values in GetMap for additional coords not specified in request params --- xpublish_wms/wms/get_map.py | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/xpublish_wms/wms/get_map.py b/xpublish_wms/wms/get_map.py index 2b089d7..720863c 100644 --- a/xpublish_wms/wms/get_map.py +++ b/xpublish_wms/wms/get_map.py @@ -174,7 +174,7 @@ def ensure_query_types( self.autoscale = query.autoscale available_selectors = ds.gridded.additional_coords(ds[self.parameter]) - self.dim_selectors = {k: query_params[k] for k in available_selectors} + self.dim_selectors = {k: query_params[k] if k in query_params else None for k in available_selectors} def select_layer(self, ds: xr.Dataset) -> xr.DataArray: """ @@ -235,23 +235,34 @@ def select_elevation(self, ds: xr.Dataset, da: xr.DataArray) -> xr.DataArray: def select_custom_dim(self, da: xr.DataArray) -> xr.DataArray: """ Select other dimension, ensuring a 2D array + + If dimension is provided : + - use xarray to access custom coord + - method nearest to ensure at least one result + + Otherwise: + - Get first value of coord + :param da: :return: """ # Filter dimension from custom query, if any for dim, value in self.dim_selectors.items(): if dim in da.coords: - dtype = da[dim].dtype - method = None - if "timedelta" in str(dtype): - value = pd.to_timedelta(value) - elif np.issubdtype(dtype, np.integer): - value = int(value) - method = "nearest" - elif np.issubdtype(dtype, np.floating): - value = float(value) - method = "nearest" - da = da.sel({dim: value}, method=method) + if value is None: + da = da.isel({dim: 0}) + else: + dtype = da[dim].dtype + method = None + if "timedelta" in str(dtype): + value = pd.to_timedelta(value) + elif np.issubdtype(dtype, np.integer): + value = int(value) + method = "nearest" + elif np.issubdtype(dtype, np.floating): + value = float(value) + method = "nearest" + da = da.sel({dim: value}, method=method) # Squeeze single value dimensions da = da.squeeze() From 1102b997f5a67ac66c4c35bee02526115c0d389f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:55:20 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- xpublish_wms/wms/get_map.py | 5 ++++- xpublish_wms/wms/get_metadata.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/xpublish_wms/wms/get_map.py b/xpublish_wms/wms/get_map.py index 720863c..752b6da 100644 --- a/xpublish_wms/wms/get_map.py +++ b/xpublish_wms/wms/get_map.py @@ -174,7 +174,10 @@ def ensure_query_types( self.autoscale = query.autoscale available_selectors = ds.gridded.additional_coords(ds[self.parameter]) - self.dim_selectors = {k: query_params[k] if k in query_params else None for k in available_selectors} + self.dim_selectors = { + k: query_params[k] if k in query_params else None + for k in available_selectors + } def select_layer(self, ds: xr.Dataset) -> xr.DataArray: """ diff --git a/xpublish_wms/wms/get_metadata.py b/xpublish_wms/wms/get_metadata.py index 1220155..050bc4a 100644 --- a/xpublish_wms/wms/get_metadata.py +++ b/xpublish_wms/wms/get_metadata.py @@ -139,7 +139,10 @@ def get_layer_details(ds: xr.Dataset, layer_name: str) -> dict: additional_coords = ds.gridded.additional_coords(da) additional_coord_values = { - coord: (da.cf.coords[coord] if coord in da.cf.coords else da[coord]).values.tolist() for coord in additional_coords + coord: ( + da.cf.coords[coord] if coord in da.cf.coords else da[coord] + ).values.tolist() + for coord in additional_coords } return {