Skip to content

Commit 0b93ae3

Browse files
authored
Merge pull request #135 from ICESat2-SlideRule/demo
feat: add download options to voila demo
2 parents 2f4545f + 753234e commit 0b93ae3

3 files changed

Lines changed: 94 additions & 48 deletions

File tree

demo/voila_demo.ipynb

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
}
4646
},
4747
"source": [
48-
"## Gridded Elevations ([atl06p](https://slideruleearth.io/rtd/api_reference/icesat2.html#atl06p))"
48+
"## Segment Elevations ([atl06p](https://slideruleearth.io/rtd/api_reference/icesat2.html#atl06p))"
4949
]
5050
},
5151
{
@@ -66,18 +66,20 @@
6666
"outputs": [],
6767
"source": [
6868
"# load the necessary packages\n",
69+
"from io import BytesIO\n",
6970
"from sliderule import icesat2, ipysliderule, io, sliderule\n",
7071
"import ipywidgets as widgets\n",
7172
"import geopandas\n",
7273
"import logging\n",
7374
"import warnings\n",
75+
"import base64\n",
7476
"import time\n",
77+
"import copy\n",
7578
"import json\n",
7679
"import re\n",
7780
"from IPython import display\n",
7881
"# atl03 plotting imports\n",
7982
"import numpy as np\n",
80-
"import matplotlib.lines\n",
8183
"import matplotlib.pyplot as plt\n",
8284
"# autoreload\n",
8385
"%load_ext autoreload\n",
@@ -134,8 +136,13 @@
134136
"run_output = widgets.Output()\n",
135137
"refresh_button = widgets.Button(description=\"Refresh Plot\")\n",
136138
"refresh_output = widgets.Output()\n",
139+
"download_output = widgets.Output()\n",
140+
"download_atl06_button = widgets.Button(description=\"Download File\")\n",
141+
"download_atl03_button = widgets.Button(description=\"Download File\")\n",
142+
"SRwidgets.file_format.options = [\"GeoJSON\",\"csv\",\"geoparquet\"]\n",
143+
"SRwidgets.file_format.value = 'geoparquet'\n",
137144
"show_code06_button = widgets.Button(description=\"Show Code\")\n",
138-
"show_code06_output = widgets.Output()"
145+
"show_code06_output = widgets.Output()\n"
139146
]
140147
},
141148
{
@@ -309,11 +316,17 @@
309316
" if max_plot_points > atl06_rsps.shape[0]:\n",
310317
" max_plot_points = atl06_rsps.shape[0]\n",
311318
" print(f'Plotting {max_plot_points} of {atl06_rsps.shape[0]} elevations. This may take 10-60+ seconds for larger point datasets.')\n",
312-
" fields = m.default_atl06_fields()\n",
313-
" atl06_rsps.leaflet.GeoData(m.map, column_name=SRwidgets.variable.value,\n",
314-
" cmap=SRwidgets.colormap, max_plot_points=max_plot_points, tooltip=True,\n",
315-
" colorbar=True, fields=fields)\n",
319+
" fields = atl06_rsps.leaflet.default_atl06_fields()\n",
320+
" atl06_rsps.leaflet.GeoData(m.map,\n",
321+
" column_name=SRwidgets.variable.value,\n",
322+
" cmap=SRwidgets.colormap,\n",
323+
" max_plot_points=max_plot_points,\n",
324+
" tooltip=True,\n",
325+
" colorbar=True,\n",
326+
" fields=fields\n",
327+
" )\n",
316328
" # install handlers and callbacks\n",
329+
" atl06_rsps.leaflet.set_observables(SRwidgets)\n",
317330
" atl06_rsps.leaflet.add_selected_callback(SRwidgets.atl06_click_handler)\n",
318331
" m.add_region_callback(atl06_rsps.leaflet.handle_region)\n",
319332
"\n",
@@ -330,11 +343,17 @@
330343
" if max_plot_points > atl06_rsps.shape[0]:\n",
331344
" max_plot_points = atl06_rsps.shape[0]\n",
332345
" print(f'Plotting {max_plot_points} of {atl06_rsps.shape[0]} elevations. This may take 10-60+ seconds for larger point datasets.')\n",
333-
" fields = m.default_atl06_fields()\n",
334-
" atl06_rsps.leaflet.GeoData(m.map, column_name=SRwidgets.variable.value,\n",
335-
" cmap=SRwidgets.colormap, max_plot_points=max_plot_points, tooltip=True,\n",
336-
" colorbar=True, fields=fields)\n",
346+
" fields = atl06_rsps.leaflet.default_atl06_fields()\n",
347+
" atl06_rsps.leaflet.GeoData(m.map,\n",
348+
" column_name=SRwidgets.variable.value,\n",
349+
" cmap=SRwidgets.colormap,\n",
350+
" max_plot_points=max_plot_points,\n",
351+
" tooltip=True,\n",
352+
" colorbar=True,\n",
353+
" fields=fields\n",
354+
" )\n",
337355
" # install handlers and callbacks\n",
356+
" atl06_rsps.leaflet.set_observables(SRwidgets)\n",
338357
" atl06_rsps.leaflet.add_selected_callback(SRwidgets.atl06_click_handler)\n",
339358
" m.add_region_callback(atl06_rsps.leaflet.handle_region)\n",
340359
"\n",
@@ -350,10 +369,43 @@
350369
" print('parms = ', atl06_json, sep='')\n",
351370
" print('gdf = icesat2.atl06p(parms)')\n",
352371
"\n",
372+
"# Download ATL06-SR data as geojson\n",
373+
"display.display(download_output)\n",
374+
"#SRwidgets.file_format.value = 'geoparquet'\n",
375+
"def download_file(gdf, filename, mime_type='text/json'):\n",
376+
" if (mime_type == 'text/json'):\n",
377+
" content = base64.b64encode(gdf.to_json().encode()).decode()\n",
378+
" elif (mime_type == 'text/csv'):\n",
379+
" content = base64.b64encode(gdf.to_csv().encode()).decode()\n",
380+
" elif (mime_type == 'application/vnd.apache.parquet'):\n",
381+
" fid = BytesIO()\n",
382+
" parms = copy.copy(atl06_parms)\n",
383+
" version = sliderule.get_version()\n",
384+
" parms['version'] = version['icesat2']['version']\n",
385+
" parms['commit'] = version['icesat2']['commit']\n",
386+
" io.to_parquet(gdf, fid, parameters=parms, regions=m.regions)\n",
387+
" content = base64.b64encode(fid.getbuffer()).decode()\n",
388+
" # create download link\n",
389+
" url = f'data:{mime_type};charset=utf-8;base64,{content}'\n",
390+
" js = f\"\"\"\n",
391+
" var a = document.createElement('a');\n",
392+
" a.setAttribute('download', '{filename}');\n",
393+
" a.setAttribute('href', '{url}');\n",
394+
" a.click();\n",
395+
" \"\"\"\n",
396+
" with download_output:\n",
397+
" display.clear_output()\n",
398+
" display.display(display.HTML(f'<script>{js}</script>'))\n",
399+
"\n",
400+
"def on_atl06_download_clicked(e=None):\n",
401+
" download_file(atl06_rsps, SRwidgets.atl06_filename,\n",
402+
" mime_type=SRwidgets.mime_type)\n",
403+
"\n",
353404
"# link buttons\n",
354405
"run_button.on_click(on_run_clicked)\n",
355406
"refresh_button.on_click(on_refresh_clicked)\n",
356-
"show_code06_button.on_click(on_show_code06_clicked)"
407+
"show_code06_button.on_click(on_show_code06_clicked)\n",
408+
"download_atl06_button.on_click(on_atl06_download_clicked)"
357409
]
358410
},
359411
{
@@ -412,9 +464,9 @@
412464
"]))\n",
413465
"\n",
414466
"# display buttons\n",
415-
"display.display(run_button)\n",
416-
"display.display(refresh_button, refresh_output)\n",
417-
"display.display(show_code06_button, show_code06_output)"
467+
"display.display(SRwidgets.HBox([run_button, refresh_button, refresh_output]))\n",
468+
"display.display(SRwidgets.HBox([download_atl06_button, SRwidgets.file_format]))\n",
469+
"display.display(SRwidgets.HBox([show_code06_button, show_code06_output]))\n"
418470
]
419471
},
420472
{
@@ -500,9 +552,6 @@
500552
" url = url_textbox.value\n",
501553
" icesat2.init(url, loglevel=logging.ERROR)\n",
502554
"\n",
503-
" # sliderule asset and data release\n",
504-
" asset = SRwidgets.asset.value\n",
505-
"\n",
506555
" # build sliderule parameters using latest values from widget\n",
507556
" atl03_parms = {\n",
508557
" # processing parameters\n",
@@ -596,8 +645,14 @@
596645
" print('parms = ', atl03_json, sep='')\n",
597646
" print('gdf = icesat2.atl03sp(parms)')\n",
598647
"\n",
648+
"\n",
649+
"def on_atl03_download_clicked(e=None):\n",
650+
" download_file(atl03_rsps, SRwidgets.atl03_filename,\n",
651+
" mime_type=SRwidgets.mime_type)\n",
652+
"\n",
599653
"# install click handler callback\n",
600-
"show_code03_button.on_click(on_show_code03_clicked)"
654+
"show_code03_button.on_click(on_show_code03_clicked)\n",
655+
"download_atl03_button.on_click(on_atl03_download_clicked)"
601656
]
602657
},
603658
{
@@ -636,6 +691,7 @@
636691
"display.display(elev_dropdown)\n",
637692
"display.display(pc_button)\n",
638693
"display.display(pc_output)\n",
694+
"display.display(SRwidgets.HBox([download_atl03_button, SRwidgets.file_format]))\n",
639695
"display.display(show_code03_button, show_code03_output)"
640696
]
641697
}

examples/api_widgets_demo.ipynb

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
"warnings.filterwarnings('ignore') # turn off warnings for demo\n",
3131
"\n",
3232
"from sliderule import icesat2, ipysliderule, io, sliderule\n",
33-
"import ipywidgets as widgets\n",
3433
"import geopandas\n",
3534
"import logging\n",
3635
"\n",
@@ -85,7 +84,7 @@
8584
"source": [
8685
"# display widgets for setting SlideRule parameters\n",
8786
"SRwidgets = ipysliderule.widgets()\n",
88-
"widgets.VBox(SRwidgets.atl06())"
87+
"SRwidgets.VBox(SRwidgets.atl06())"
8988
]
9089
},
9190
{
@@ -146,7 +145,7 @@
146145
},
147146
"outputs": [],
148147
"source": [
149-
"widgets.VBox([\n",
148+
"SRwidgets.VBox([\n",
150149
" SRwidgets.projection,\n",
151150
" SRwidgets.layers,\n",
152151
" SRwidgets.raster_functions\n",
@@ -219,6 +218,7 @@
219218
"elevations = [sliderule.emptyframe()]\n",
220219
"\n",
221220
"# for each region of interest\n",
221+
"sliderule.logger.warning('No valid regions to run') if not m.regions else None\n",
222222
"for poly in m.regions:\n",
223223
" # add polygon from map to sliderule parameters\n",
224224
" parms[\"poly\"] = poly\n",
@@ -269,7 +269,7 @@
269269
},
270270
"outputs": [],
271271
"source": [
272-
"widgets.VBox([\n",
272+
"SRwidgets.VBox([\n",
273273
" SRwidgets.variable,\n",
274274
" SRwidgets.cmap,\n",
275275
" SRwidgets.reverse,\n",
@@ -286,10 +286,11 @@
286286
"source": [
287287
"%matplotlib inline\n",
288288
"# ATL06-SR fields for hover tooltip\n",
289-
"fields = m.default_atl06_fields()\n",
289+
"fields = gdf.leaflet.default_atl06_fields()\n",
290290
"gdf.leaflet.GeoData(m.map, column_name=SRwidgets.variable.value, cmap=SRwidgets.colormap,\n",
291291
" max_plot_points=10000, tooltip=True, colorbar=True, fields=fields)\n",
292292
"# install handlers and callbacks\n",
293+
"gdf.leaflet.set_observables(SRwidgets)\n",
293294
"gdf.leaflet.add_selected_callback(SRwidgets.atl06_click_handler)\n",
294295
"m.add_region_callback(gdf.leaflet.handle_region)"
295296
]
@@ -314,7 +315,7 @@
314315
},
315316
"outputs": [],
316317
"source": [
317-
"widgets.VBox([\n",
318+
"SRwidgets.VBox([\n",
318319
" SRwidgets.plot_kind,\n",
319320
" SRwidgets.rgt,\n",
320321
" SRwidgets.ground_track,\n",
@@ -342,9 +343,7 @@
342343
"tags": []
343344
},
344345
"source": [
345-
"### Save GeoDataFrame to output file\n",
346-
"- [pytables HDF5](https://www.pytables.org/): easily read back as a Geopandas GeoDataFrame\n",
347-
"- [netCDF](https://www.unidata.ucar.edu/software/netcdf): interoperable with other programs"
346+
"### Save GeoDataFrame to output file"
348347
]
349348
},
350349
{
@@ -373,7 +372,6 @@
373372
"# save to file in format (HDF5 or netCDF)\n",
374373
"io.to_file(gdf, SRwidgets.file,\n",
375374
" format=SRwidgets.format,\n",
376-
" driver='pytables',\n",
377375
" parameters=parms,\n",
378376
" regions=m.regions,\n",
379377
" verbose=True)"
@@ -383,9 +381,7 @@
383381
"cell_type": "markdown",
384382
"metadata": {},
385383
"source": [
386-
"### Read GeoDataFrame from input file\n",
387-
"- [pytables HDF5](https://www.pytables.org/)\n",
388-
"- [netCDF](https://www.unidata.ucar.edu/software/netcdf)"
384+
"### Read GeoDataFrame from input file"
389385
]
390386
},
391387
{
@@ -410,7 +406,6 @@
410406
"# read from file in format (HDF5 or netCDF)\n",
411407
"gdf,parms,regions = io.from_file(SRwidgets.file,\n",
412408
" format=SRwidgets.format,\n",
413-
" driver='pytables',\n",
414409
" return_parameters=True,\n",
415410
" return_regions=True)"
416411
]

examples/atl03_widgets_demo.ipynb

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
"warnings.filterwarnings('ignore')# autoreload\n",
4141
"\n",
4242
"from sliderule import icesat2, ipysliderule, sliderule, io, earthdata\n",
43-
"import ipywidgets as widgets\n",
4443
"import geopandas\n",
4544
"import logging\n",
4645
"\n",
@@ -93,7 +92,7 @@
9392
"# display widgets for setting SlideRule parameters\n",
9493
"SRwidgets = ipysliderule.widgets()\n",
9594
"SRwidgets.set_atl03_defaults()\n",
96-
"widgets.VBox(SRwidgets.atl03())"
95+
"SRwidgets.VBox(SRwidgets.atl03())"
9796
]
9897
},
9998
{
@@ -154,7 +153,7 @@
154153
},
155154
"outputs": [],
156155
"source": [
157-
"widgets.VBox([\n",
156+
"SRwidgets.VBox([\n",
158157
" SRwidgets.projection,\n",
159158
" SRwidgets.layers,\n",
160159
" SRwidgets.raster_functions\n",
@@ -221,6 +220,7 @@
221220
"# find granule for each region of interest\n",
222221
"granules_list = []\n",
223222
"# for each region of interest\n",
223+
"sliderule.logger.warning('No valid regions to run') if not m.regions else None\n",
224224
"for poly in m.regions:\n",
225225
" granules = earthdata.cmr(short_name=\"ATL03\",\n",
226226
" polygon=poly,\n",
@@ -309,7 +309,7 @@
309309
},
310310
"outputs": [],
311311
"source": [
312-
"widgets.VBox([\n",
312+
"SRwidgets.VBox([\n",
313313
" SRwidgets.variable,\n",
314314
" SRwidgets.cmap,\n",
315315
" SRwidgets.reverse,\n",
@@ -326,10 +326,11 @@
326326
"source": [
327327
"%matplotlib inline\n",
328328
"# ATL03 fields for hover tooltip\n",
329-
"fields = m.default_atl03_fields()\n",
329+
"fields = gdf.leaflet.default_atl03_fields()\n",
330330
"gdf.leaflet.GeoData(m.map, column_name=SRwidgets.variable.value, cmap=SRwidgets.colormap,\n",
331331
" max_plot_points=10000, tooltip=True, colorbar=True, fields=fields)\n",
332332
"# install handlers and callbacks\n",
333+
"gdf.leaflet.set_observables(SRwidgets)\n",
333334
"gdf.leaflet.add_selected_callback(SRwidgets.atl03_click_handler)\n",
334335
"m.add_region_callback(gdf.leaflet.handle_region)"
335336
]
@@ -350,7 +351,7 @@
350351
},
351352
"outputs": [],
352353
"source": [
353-
"widgets.VBox([\n",
354+
"SRwidgets.VBox([\n",
354355
" SRwidgets.plot_classification,\n",
355356
" SRwidgets.rgt,\n",
356357
" SRwidgets.ground_track,\n",
@@ -377,9 +378,7 @@
377378
"cell_type": "markdown",
378379
"metadata": {},
379380
"source": [
380-
"### Save GeoDataFrame to output file\n",
381-
"- [pytables HDF5](https://www.pytables.org/): easily read back as a Geopandas GeoDataFrame\n",
382-
"- [netCDF](https://www.unidata.ucar.edu/software/netcdf): interoperable with other programs"
381+
"### Save GeoDataFrame to output file"
383382
]
384383
},
385384
{
@@ -408,7 +407,6 @@
408407
"# save to file in format (HDF5 or netCDF)\n",
409408
"io.to_file(gdf, SRwidgets.file,\n",
410409
" format=SRwidgets.format,\n",
411-
" driver='pytables',\n",
412410
" parameters=parms,\n",
413411
" regions=m.regions,\n",
414412
" verbose=True)"
@@ -418,9 +416,7 @@
418416
"cell_type": "markdown",
419417
"metadata": {},
420418
"source": [
421-
"### Read GeoDataFrame from input file\n",
422-
"- [pytables HDF5](https://www.pytables.org/)\n",
423-
"- [netCDF](https://www.unidata.ucar.edu/software/netcdf)"
419+
"### Read GeoDataFrame from input file"
424420
]
425421
},
426422
{
@@ -445,7 +441,6 @@
445441
"# read from file in format (HDF5 or netCDF)\n",
446442
"gdf,parms,regions = io.from_file(SRwidgets.file,\n",
447443
" format=SRwidgets.format,\n",
448-
" driver='pytables',\n",
449444
" return_parameters=True,\n",
450445
" return_regions=True)"
451446
]
@@ -514,7 +509,7 @@
514509
"name": "python",
515510
"nbconvert_exporter": "python",
516511
"pygments_lexer": "ipython3",
517-
"version": "3.12.0"
512+
"version": "3.10.13"
518513
}
519514
},
520515
"nbformat": 4,

0 commit comments

Comments
 (0)