Skip to content
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

Feature/xyz routes #88

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ venv.bak/
.spyderproject
.spyproject

# Pycharm project settings
.idea

# Rope project settings
.ropeproject

Expand Down
120 changes: 120 additions & 0 deletions examples/xyz_client.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "f29eb1d8",
"metadata": {},
"outputs": [],
"source": [
"from traitlets import Unicode\n",
"from ipyleaflet import Map, WMSLayer, basemaps\n",
"from ipyleaflet import Map, LocalTileLayer\n",
"from ipywidgets import Layout\n",
"\n",
"defaultLayout=Layout(width='960px', height='540px')\n",
"\n",
"\n",
"class TimeWMTSLayer(LocalTileLayer):\n",
"\n",
" time = Unicode('').tag(sync=True, o=True)\n",
"\n",
"\n",
" \n",
"wmts = TimeWMTSLayer(path='http://127.0.0.1:9000/tiles/air/{time}/{z}/{x}/{y}')\n",
" \n",
" \n",
"m = Map(basemap=basemaps.CartoDB.Positron, center=(39, -105.121558), zoom=2, layout=defaultLayout)\n",
"\n",
"m.add_layer(wmts)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "63c7b3ea",
"metadata": {},
"outputs": [],
"source": [
"from ipywidgets import SelectionSlider\n",
"from pandas import date_range\n",
"\n",
"times = date_range(\"2013-01-01\",\"2013-12-31\",freq=\"24H\").strftime(\"%Y-%m-%dT%H:%M\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "de7873d5",
"metadata": {},
"outputs": [],
"source": [
"slider = SelectionSlider(description='Time:', options=times)\n",
"\n",
"def update_wms(change):\n",
" wmts.time = '{}'.format(slider.value)\n",
" wmts.redraw()\n",
"\n",
"\n",
"slider.observe(update_wms, 'value')\n",
"slider"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0a0ccfa5",
"metadata": {},
"outputs": [],
"source": [
"m"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "51c6f493",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "39373134",
"metadata": {},
"outputs": [],
"source": [
"from ipyleaflet import Map, LocalTileLayer\n",
"from ipywidgets import Layout\n",
"defaultLayout=Layout(width='960px', height='540px')\n",
"\n",
"m = Map(center=(39, -105.121558), zoom=2, layout=defaultLayout)\n",
"m.add_layer(LocalTileLayer(path='http://127.0.0.1:9000/tiles/air/{z}/{x}/{y}'))\n",
"\n",
"m"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "xpublish",
"language": "python",
"name": "xpublish"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
219 changes: 219 additions & 0 deletions examples/xyz_server.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "e3ff8a25",
"metadata": {},
"outputs": [],
"source": [
"import xarray as xr, colorcet\n",
"from colorcet import bmw, coolwarm\n",
"\n",
"from xpublish.routers import xyz_router, base_router\n",
"from xpublish.utils.ows import validate_dataset"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "18a93f76",
"metadata": {},
"outputs": [],
"source": [
"ds = xr.tutorial.open_dataset(\n",
" \"air_temperature\", chunks=dict(lat=5, lon=5),\n",
")\n",
"ds"
]
},
{
"cell_type": "markdown",
"id": "b4034b22",
"metadata": {},
"source": [
"XYZ router accepts only spatial dimensions that are named 'x' and 'y'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0d0a23a4",
"metadata": {},
"outputs": [],
"source": [
"ds = ds.rename({\"lat\": \"y\", \"lon\": \"x\"})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4594bfc7",
"metadata": {},
"outputs": [],
"source": [
"validate_dataset(ds)"
]
},
{
"cell_type": "markdown",
"id": "31482162",
"metadata": {},
"source": [
"XYZ uses morecantile to tile the dataarray. Morecantile supports different grids, not only the Web Mercator which is the most common and it is used by Google Maps and OpenStreetMap.\n",
"In this example the dataset needs to be reprojected to match the Web Mercator projection."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "babd049e",
"metadata": {},
"outputs": [],
"source": [
"ds.rio.set_spatial_dims(x_dim=\"x\", y_dim=\"y\", inplace=True)\n",
"ds.rio.write_crs(4326, inplace=True)\n",
"\n",
"ds = ds.rio.reproject(\n",
" # epsg: 3857\n",
" dst_crs= \"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs\" \n",
" )"
]
},
{
"cell_type": "markdown",
"id": "6e5b0a3d",
"metadata": {},
"source": [
"XYZ router accepts 2 map options to:\n",
"- crs_epsg: set the correct grid tiling \n",
"- color_mapping: produce custom images setting the datashader parameters or matplotlib parameters"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "99a8bbb6",
"metadata": {},
"outputs": [],
"source": [
"crs_epsg = 3857\n",
"\n",
"color_mapping = {\n",
" \n",
" \"datashader_settings\":{\n",
" # parameters for datashader.Canvas.raster method\n",
" \"raster\": {\"upsample_method\": \"linear\"}, \n",
" # parameters for datashader.transfer_functions.shade\n",
" \"shade\": { \"cmap\": colorcet.bmy,#[\"blue\",\"red\"], \n",
" \"how\": \"linear\", \n",
" \"span\": [float(ds[\"air\"].min()), float(ds[\"air\"].max())], \n",
" \"alpha\": 200 }\n",
" }, \n",
"}\n",
"\n",
"xyz_router.set_options(crs_epsg, color_mapping=color_mapping)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0e2de0f6",
"metadata": {},
"outputs": [],
"source": [
"ds.rest(routers=[xyz_router, base_router])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f278ecc6",
"metadata": {},
"outputs": [],
"source": [
"import nest_asyncio \n",
"nest_asyncio.apply()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2d1638d8",
"metadata": {},
"outputs": [],
"source": [
"ds.rest.serve(port=9000,log_level='info')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0bd5eaaa",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "e6617860",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "bcd9d240",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "5735e747",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "ec675f0e",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "51e0de7f",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "xpublish",
"language": "python",
"name": "xpublish"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
2 changes: 1 addition & 1 deletion xpublish/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from fastapi import FastAPI, HTTPException

from .dependencies import get_cache, get_dataset, get_dataset_ids
from .routers import base_router, common_router, dataset_collection_router, zarr_router
from .routers import base_router, common_router, dataset_collection_router, zarr_router, xyz_router
from .utils.api import (
SingleDatasetOpenAPIOverrider,
check_route_conflicts,
Expand Down
1 change: 1 addition & 0 deletions xpublish/routers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .base import base_router
from .common import common_router, dataset_collection_router
from .zarr import zarr_router
from .xyz import xyz_router
iacopoff marked this conversation as resolved.
Show resolved Hide resolved
Loading