Skip to content

Instantly share code, notes, and snippets.

@ianhi
Last active May 15, 2025 14:38
Show Gist options
  • Save ianhi/9a31d295667ab6aec6893a6a6c331040 to your computer and use it in GitHub Desktop.
Save ianhi/9a31d295667ab6aec6893a6a6c331040 to your computer and use it in GitHub Desktop.
Xarray Tile Accessor
from typing import overload
import mercantile
import xarray as xr
@xr.register_dataset_accessor("tile")
@xr.register_dataarray_accessor("tile")
class TileAccessor:
def __init__(self, xarray_obj):
self._ds = xarray_obj
def mbbox(self, bbox: mercantile.LngLatBbox) -> xr.Dataset:
return self._ds.sel(
{
ds.cf["longitude"].name: slice(bbox.west, bbox.east),
ds.cf["latitude"].name: slice(bbox.south, bbox.north),
}
)
@overload
def __call__(self, tile: str) -> xr.Dataset: ...
def __call__(self, X: int, Y: int = None, zoom: int = None) -> xr.Dataset:
"""
Slice the bbox associated with the tile.
Valid inputs:
"lat/lon/zoom"
"lat,lon,zoom"
lat, lon, zoom (as integers)
not sure how to do params properly for this overload.
"""
# no safety checks! be good plz :)
if isinstance(X, str):
bbox = mercantile.bounds(tuple(map(int, X.replace(",", "/").split("/"))))
else:
bbox = mercantile.bounds(X, Y, zoom)
return self.mbbox(bbox)
@ianhi
Copy link
Author

ianhi commented May 15, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment