-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] add titiler.xarray
module
#1007
Conversation
variable: str = attr.ib() | ||
|
||
# xarray.Dataset options | ||
opener: Callable[..., xarray.Dataset] = attr.ib(default=xarray_open_dataset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By making the opener
an option it eases the user to bring their own xarray_open_dataset
callable which may add more protocol
(e.g Azure, GCS ...)
reference: bool = attr.ib(default=False) | ||
decode_times: bool = attr.ib(default=False) | ||
consolidated: Optional[bool] = attr.ib(default=True) | ||
cache_client: Optional[CacheClient] = attr.ib(default=None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cache client is optional, basically users just need to provide an Object with get
and set
methods
da = da.rename({latitude_var_name: "y", longitude_var_name: "x"}) | ||
|
||
if "TIME" in da.dims: | ||
da = da.rename({"TIME": "time"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was added for
from titiler.xarray.io import Reader
with Reader("s3://aodn-cloud-optimised/model_sea_level_anomaly_gridded_realtime.zarr/", "GSL") as src:
print(src.info())
bounds=(-180.28109374046326, -60.1, 180.081081533432, 10.1) crs='http://www.opengis.net/def/crs/EPSG/0/4326' band_metadata=[] band_descriptions=[] dtype='float64' nodata_type='Nodata' colorinterp=None scales=None offsets=None colormap=None name='GSL' count=1 width=641 height=351 attrs={'description': 'GSLA + CAST2008 mean dynamic height ', 'long_name': 'gridded sea level', 'standard_name': 'sea_surface_height_above_geoid', 'units': 'm'}
vmin, vmax = da.attrs.get("valid_min"), da.attrs.get("valid_max") | ||
if "valid_range" in da.attrs and not (vmin is not None and vmax is not None): | ||
valid_range = da.attrs.get("valid_range") | ||
da.attrs.update({"valid_min": valid_range[0], "valid_max": valid_range[1]}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if valid_range
is something we find usually
if "TIME" in da.dims: | ||
da = da.rename({"TIME": "time"}) | ||
|
||
if _dims := [d for d in da.dims if d not in ["x", "y"]]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to support dataset with more than 3 dimension (e.g more than time, x, y)
# Sort the dataset by the updated longitude coordinates | ||
da = da.sortby(da.x) | ||
|
||
# TODO: Technically we don't have to select the first time, rio-tiler should handle 3D dataset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ we might enable all the times
values, and not select the first value by default
"query_string": urlencode(qs, doseq=True) if qs else None, | ||
"bounds": bounds, | ||
}, | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add layers to WMTS response
this will be use for STAC renders but maybe also for multiple variable support in XARRAY
right = Math.min(right, {{ tms.bbox.right }}) | ||
} | ||
bottom = Math.max(bottom, {{ tms.bbox.bottom }}) | ||
top = Math.min(top, {{ tms.bbox.top }}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed to do this because some NetCDF data have bounds that exceed the TMS bbox
|
||
|
||
@dataclass(init=False) | ||
class CompatXarrayParams(DefaultDependency): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not directly used in titiler.xarray but could be in a Tiler that would want to support both GDAL/Xarray dataset
|
||
|
||
@define(kw_only=True) | ||
class TilerFactory(BaseTilerFactory): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By sub-classing titiler.core.factory.TilerFactory
we avoid re-writing code
|
||
# remove some attribute from init | ||
img_preview_dependency: Type[DefaultDependency] = field(init=False) | ||
add_preview: bool = field(init=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't want to have preview
for now (I don't think any user would want this except if they control the dataset available)
|
||
return Response(content, media_type=media_type) | ||
|
||
# custom /statistics endpoints (remove /statistics - GET) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ IMO having a full dataset /statistics in a bit dangerous (as for the /preview endpoints)
geojson: Annotated[ | ||
Union[FeatureCollection, Feature], | ||
Body(description="GeoJSON Feature or FeatureCollection."), | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: we should maybe extract this and make a dependency that user could customize to control the size of the GeoJSON
md.router, | ||
prefix="/md", | ||
tags=["Multi Dimensional"], | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we might remove this in the final module
ref: developmentseed/titiler-xarray#68
depends on cogeotiff/rio-tiler#755
To Do
.io.Reader