From e1660cde42340c15a68f6080f1969dc9ab3392a8 Mon Sep 17 00:00:00 2001 From: Qiusheng Wu Date: Sun, 23 Jan 2022 00:06:56 -0500 Subject: [PATCH] Added attribute table GUI #179 --- docs/notebooks/44_attribute_table.ipynb | 127 ++++++ docs/tutorials.md | 1 + examples/README.md | 1 + examples/notebooks/44_attribute_table.ipynb | 127 ++++++ examples/workshops/us_cities.geojson | 121 ------ leafmap/foliumap.py | 6 + leafmap/plotlymap.py | 71 ++-- leafmap/toolbar.py | 423 +++++++++++++++++++- mkdocs.yml | 1 + requirements.txt | 1 + 10 files changed, 715 insertions(+), 164 deletions(-) create mode 100644 docs/notebooks/44_attribute_table.ipynb create mode 100644 examples/notebooks/44_attribute_table.ipynb delete mode 100644 examples/workshops/us_cities.geojson diff --git a/docs/notebooks/44_attribute_table.ipynb b/docs/notebooks/44_attribute_table.ipynb new file mode 100644 index 0000000000..ddcb04b032 --- /dev/null +++ b/docs/notebooks/44_attribute_table.ipynb @@ -0,0 +1,127 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://githubtocolab.com/giswqs/leafmap/blob/master/examples/notebooks/44_attribute_table.ipynb)\n", + "[![image](https://mybinder.org/badge_logo.svg)](https://gishub.org/leafmap-binder)\n", + "\n", + "Uncomment the following line to install [leafmap](https://leafmap.org) if needed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# !pip install leafmap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import leafmap" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add vector data to the map and use the GUI to open attribute table." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "m = leafmap.Map()\n", + "\n", + "url = \"https://raw.githubusercontent.com/giswqs/leafmap/master/examples/data/countries.geojson\"\n", + "m.add_geojson(url, layer_name=\"Countries\", fill_colors=['red', 'yellow', 'green', 'orange'], info_mode=False)\n", + "\n", + "in_geojson = 'https://raw.githubusercontent.com/giswqs/leafmap/master/examples/data/cable-geo.geojson'\n", + "m.add_geojson(in_geojson, layer_name=\"Cable lines\", info_mode=False)\n", + "\n", + "m" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![](https://i.imgur.com/IIoLVSG.gif)" + ] + } + ], + "metadata": { + "hide_input": false, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "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.9.7" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/tutorials.md b/docs/tutorials.md index 8f197e5d8f..026e02a8cc 100644 --- a/docs/tutorials.md +++ b/docs/tutorials.md @@ -47,6 +47,7 @@ 41. Loading COG/STAC items using the raster GUI ([notebook](https://leafmap.org/notebooks/41_raster_gui)) 42. Creating Cloud Optimized GeoTIFF (COG) ([notebook](https://leafmap.org/notebooks/42_create_cog)) 43. Searching for locations and features in vector data ([notebook](https://leafmap.org/notebooks/43_search_control)) +44. Opening vector data attribute table without coding ([notebook](https://leafmap.org/notebooks/44_attribute_table)) ## Demo diff --git a/examples/README.md b/examples/README.md index 43373624f5..891a1fcc3f 100644 --- a/examples/README.md +++ b/examples/README.md @@ -58,6 +58,7 @@ 41. Loading COG/STAC items using the raster GUI ([notebook](https://leafmap.org/notebooks/41_raster_gui)) 42. Creating Cloud Optimized GeoTIFF (COG) ([notebook](https://leafmap.org/notebooks/42_create_cog)) 43. Searching for locations and features in vector data ([notebook](https://leafmap.org/notebooks/43_search_control)) +44. Opening vector data attribute table without coding ([notebook](https://leafmap.org/notebooks/44_attribute_table)) ## Demo diff --git a/examples/notebooks/44_attribute_table.ipynb b/examples/notebooks/44_attribute_table.ipynb new file mode 100644 index 0000000000..ddcb04b032 --- /dev/null +++ b/examples/notebooks/44_attribute_table.ipynb @@ -0,0 +1,127 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://githubtocolab.com/giswqs/leafmap/blob/master/examples/notebooks/44_attribute_table.ipynb)\n", + "[![image](https://mybinder.org/badge_logo.svg)](https://gishub.org/leafmap-binder)\n", + "\n", + "Uncomment the following line to install [leafmap](https://leafmap.org) if needed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# !pip install leafmap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import leafmap" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add vector data to the map and use the GUI to open attribute table." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "m = leafmap.Map()\n", + "\n", + "url = \"https://raw.githubusercontent.com/giswqs/leafmap/master/examples/data/countries.geojson\"\n", + "m.add_geojson(url, layer_name=\"Countries\", fill_colors=['red', 'yellow', 'green', 'orange'], info_mode=False)\n", + "\n", + "in_geojson = 'https://raw.githubusercontent.com/giswqs/leafmap/master/examples/data/cable-geo.geojson'\n", + "m.add_geojson(in_geojson, layer_name=\"Cable lines\", info_mode=False)\n", + "\n", + "m" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![](https://i.imgur.com/IIoLVSG.gif)" + ] + } + ], + "metadata": { + "hide_input": false, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "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.9.7" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/workshops/us_cities.geojson b/examples/workshops/us_cities.geojson deleted file mode 100644 index cd88418756..0000000000 --- a/examples/workshops/us_cities.geojson +++ /dev/null @@ -1,121 +0,0 @@ -{ -"type": "FeatureCollection", -"name": "us_cities", -"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, -"features": [ -{ "type": "Feature", "properties": { "name": "Agana", "sov_a3": "USA", "latitude": 13.47002, "longitude": 144.75002, "pop_max": 122411 }, "geometry": { "type": "Point", "coordinates": [ 144.75002, 13.47002 ] } }, -{ "type": "Feature", "properties": { "name": "San Bernardino", "sov_a3": "USA", "latitude": 34.12038, "longitude": -117.30003, "pop_max": 1745000 }, "geometry": { "type": "Point", "coordinates": [ -117.30003, 34.12038 ] } }, -{ "type": "Feature", "properties": { "name": "Bridgeport", "sov_a3": "USA", "latitude": 41.17998, "longitude": -73.19996, "pop_max": 1018000 }, "geometry": { "type": "Point", "coordinates": [ -73.19996, 41.17998 ] } }, -{ "type": "Feature", "properties": { "name": "Rochester", "sov_a3": "USA", "latitude": 43.17043, "longitude": -77.61995, "pop_max": 755000 }, "geometry": { "type": "Point", "coordinates": [ -77.61995, 43.17043 ] } }, -{ "type": "Feature", "properties": { "name": "International Falls", "sov_a3": "USA", "latitude": 48.60113, "longitude": -93.41085, "pop_max": 15240 }, "geometry": { "type": "Point", "coordinates": [ -93.41085, 48.60113 ] } }, -{ "type": "Feature", "properties": { "name": "St. Paul", "sov_a3": "USA", "latitude": 44.94399, "longitude": -93.08497, "pop_max": 734854 }, "geometry": { "type": "Point", "coordinates": [ -93.08497, 44.94399 ] } }, -{ "type": "Feature", "properties": { "name": "Billings", "sov_a3": "USA", "latitude": 45.7883, "longitude": -108.54, "pop_max": 104552 }, "geometry": { "type": "Point", "coordinates": [ -108.54, 45.7883 ] } }, -{ "type": "Feature", "properties": { "name": "Great Falls", "sov_a3": "USA", "latitude": 47.50029, "longitude": -111.29999, "pop_max": 66558 }, "geometry": { "type": "Point", "coordinates": [ -111.29999, 47.50029 ] } }, -{ "type": "Feature", "properties": { "name": "Missoula", "sov_a3": "USA", "latitude": 46.87224, "longitude": -113.99305, "pop_max": 72856 }, "geometry": { "type": "Point", "coordinates": [ -113.99305, 46.87224 ] } }, -{ "type": "Feature", "properties": { "name": "Minot", "sov_a3": "USA", "latitude": 48.23249, "longitude": -101.29582, "pop_max": 39439 }, "geometry": { "type": "Point", "coordinates": [ -101.29582, 48.23249 ] } }, -{ "type": "Feature", "properties": { "name": "Fargo", "sov_a3": "USA", "latitude": 46.87723, "longitude": -96.78943, "pop_max": 162842 }, "geometry": { "type": "Point", "coordinates": [ -96.78943, 46.87723 ] } }, -{ "type": "Feature", "properties": { "name": "Hilo", "sov_a3": "USA", "latitude": 19.7, "longitude": -155.09003, "pop_max": 52391 }, "geometry": { "type": "Point", "coordinates": [ -155.09003, 19.7 ] } }, -{ "type": "Feature", "properties": { "name": "Olympia", "sov_a3": "USA", "latitude": 47.03804, "longitude": -122.89943, "pop_max": 156984 }, "geometry": { "type": "Point", "coordinates": [ -122.89943, 47.03804 ] } }, -{ "type": "Feature", "properties": { "name": "Spokane", "sov_a3": "USA", "latitude": 47.67, "longitude": -117.41995, "pop_max": 347705 }, "geometry": { "type": "Point", "coordinates": [ -117.41995, 47.67 ] } }, -{ "type": "Feature", "properties": { "name": "Vancouver", "sov_a3": "USA", "latitude": 45.6303, "longitude": -122.63999, "pop_max": 525802 }, "geometry": { "type": "Point", "coordinates": [ -122.63999, 45.6303 ] } }, -{ "type": "Feature", "properties": { "name": "Flagstaff", "sov_a3": "USA", "latitude": 35.1981, "longitude": -111.65051, "pop_max": 63993 }, "geometry": { "type": "Point", "coordinates": [ -111.65051, 35.1981 ] } }, -{ "type": "Feature", "properties": { "name": "Tucson", "sov_a3": "USA", "latitude": 32.205, "longitude": -110.88999, "pop_max": 823000 }, "geometry": { "type": "Point", "coordinates": [ -110.88999, 32.205 ] } }, -{ "type": "Feature", "properties": { "name": "Santa Barbara", "sov_a3": "USA", "latitude": 34.43499, "longitude": -119.71999, "pop_max": 181632 }, "geometry": { "type": "Point", "coordinates": [ -119.71999, 34.43499 ] } }, -{ "type": "Feature", "properties": { "name": "Fresno", "sov_a3": "USA", "latitude": 36.74772, "longitude": -119.77298, "pop_max": 616353 }, "geometry": { "type": "Point", "coordinates": [ -119.77298, 36.74772 ] } }, -{ "type": "Feature", "properties": { "name": "Eureka", "sov_a3": "USA", "latitude": 40.80222, "longitude": -124.1475, "pop_max": 42398 }, "geometry": { "type": "Point", "coordinates": [ -124.1475, 40.80222 ] } }, -{ "type": "Feature", "properties": { "name": "Colorado Springs", "sov_a3": "USA", "latitude": 38.86296, "longitude": -104.79199, "pop_max": 493654 }, "geometry": { "type": "Point", "coordinates": [ -104.79199, 38.86296 ] } }, -{ "type": "Feature", "properties": { "name": "Reno", "sov_a3": "USA", "latitude": 39.52998, "longitude": -119.82001, "pop_max": 328585 }, "geometry": { "type": "Point", "coordinates": [ -119.82001, 39.52998 ] } }, -{ "type": "Feature", "properties": { "name": "Elko", "sov_a3": "USA", "latitude": 40.83251, "longitude": -115.76199, "pop_max": 19252 }, "geometry": { "type": "Point", "coordinates": [ -115.76199, 40.83251 ] } }, -{ "type": "Feature", "properties": { "name": "Albuquerque", "sov_a3": "USA", "latitude": 35.10497, "longitude": -106.64133, "pop_max": 898642 }, "geometry": { "type": "Point", "coordinates": [ -106.64133, 35.10497 ] } }, -{ "type": "Feature", "properties": { "name": "Salem", "sov_a3": "USA", "latitude": 44.92807, "longitude": -123.0239, "pop_max": 229010 }, "geometry": { "type": "Point", "coordinates": [ -123.0239, 44.92807 ] } }, -{ "type": "Feature", "properties": { "name": "Casper", "sov_a3": "USA", "latitude": 42.86662, "longitude": -106.31249, "pop_max": 60791 }, "geometry": { "type": "Point", "coordinates": [ -106.31249, 42.86662 ] } }, -{ "type": "Feature", "properties": { "name": "Topeka", "sov_a3": "USA", "latitude": 39.05001, "longitude": -95.66998, "pop_max": 132091 }, "geometry": { "type": "Point", "coordinates": [ -95.66998, 39.05001 ] } }, -{ "type": "Feature", "properties": { "name": "Kansas City", "sov_a3": "USA", "latitude": 39.10709, "longitude": -94.60409, "pop_max": 1469000 }, "geometry": { "type": "Point", "coordinates": [ -94.60409, 39.10709 ] } }, -{ "type": "Feature", "properties": { "name": "Tulsa", "sov_a3": "USA", "latitude": 36.12, "longitude": -95.93002, "pop_max": 946962 }, "geometry": { "type": "Point", "coordinates": [ -95.93002, 36.12 ] } }, -{ "type": "Feature", "properties": { "name": "Sioux Falls", "sov_a3": "USA", "latitude": 43.54999, "longitude": -96.73, "pop_max": 155724 }, "geometry": { "type": "Point", "coordinates": [ -96.73, 43.54999 ] } }, -{ "type": "Feature", "properties": { "name": "Shreveport", "sov_a3": "USA", "latitude": 32.50002, "longitude": -93.77002, "pop_max": 248053 }, "geometry": { "type": "Point", "coordinates": [ -93.77002, 32.50002 ] } }, -{ "type": "Feature", "properties": { "name": "Baton Rouge", "sov_a3": "USA", "latitude": 30.45795, "longitude": -91.14016, "pop_max": 422072 }, "geometry": { "type": "Point", "coordinates": [ -91.14016, 30.45795 ] } }, -{ "type": "Feature", "properties": { "name": "Ft. Worth", "sov_a3": "USA", "latitude": 32.73998, "longitude": -97.34004, "pop_max": 1440454 }, "geometry": { "type": "Point", "coordinates": [ -97.34004, 32.73998 ] } }, -{ "type": "Feature", "properties": { "name": "Corpus Christi", "sov_a3": "USA", "latitude": 27.74281, "longitude": -97.40189, "pop_max": 277454 }, "geometry": { "type": "Point", "coordinates": [ -97.40189, 27.74281 ] } }, -{ "type": "Feature", "properties": { "name": "Austin", "sov_a3": "USA", "latitude": 30.26695, "longitude": -97.74278, "pop_max": 1161000 }, "geometry": { "type": "Point", "coordinates": [ -97.74278, 30.26695 ] } }, -{ "type": "Feature", "properties": { "name": "Amarillo", "sov_a3": "USA", "latitude": 35.22998, "longitude": -101.83, "pop_max": 181766 }, "geometry": { "type": "Point", "coordinates": [ -101.83, 35.22998 ] } }, -{ "type": "Feature", "properties": { "name": "El Paso", "sov_a3": "USA", "latitude": 31.77998, "longitude": -106.51, "pop_max": 753000 }, "geometry": { "type": "Point", "coordinates": [ -106.51, 31.77998 ] } }, -{ "type": "Feature", "properties": { "name": "Laredo", "sov_a3": "USA", "latitude": 27.50614, "longitude": -99.50722, "pop_max": 434768 }, "geometry": { "type": "Point", "coordinates": [ -99.50722, 27.50614 ] } }, -{ "type": "Feature", "properties": { "name": "Burlington", "sov_a3": "USA", "latitude": 44.4758, "longitude": -73.21247, "pop_max": 93807 }, "geometry": { "type": "Point", "coordinates": [ -73.21247, 44.4758 ] } }, -{ "type": "Feature", "properties": { "name": "Montgomery", "sov_a3": "USA", "latitude": 32.3616, "longitude": -86.27919, "pop_max": 198325 }, "geometry": { "type": "Point", "coordinates": [ -86.27919, 32.3616 ] } }, -{ "type": "Feature", "properties": { "name": "Tallahassee", "sov_a3": "USA", "latitude": 30.44999, "longitude": -84.28003, "pop_max": 221222 }, "geometry": { "type": "Point", "coordinates": [ -84.28003, 30.44999 ] } }, -{ "type": "Feature", "properties": { "name": "Orlando", "sov_a3": "USA", "latitude": 28.50998, "longitude": -81.38003, "pop_max": 1350000 }, "geometry": { "type": "Point", "coordinates": [ -81.38003, 28.50998 ] } }, -{ "type": "Feature", "properties": { "name": "Jacksonville", "sov_a3": "USA", "latitude": 30.33002, "longitude": -81.66999, "pop_max": 988000 }, "geometry": { "type": "Point", "coordinates": [ -81.66999, 30.33002 ] } }, -{ "type": "Feature", "properties": { "name": "Savannah", "sov_a3": "USA", "latitude": 32.02111, "longitude": -81.11, "pop_max": 180187 }, "geometry": { "type": "Point", "coordinates": [ -81.11, 32.02111 ] } }, -{ "type": "Feature", "properties": { "name": "Columbia", "sov_a3": "USA", "latitude": 34.03998, "longitude": -80.89998, "pop_max": 398093 }, "geometry": { "type": "Point", "coordinates": [ -80.89998, 34.03998 ] } }, -{ "type": "Feature", "properties": { "name": "Indianapolis", "sov_a3": "USA", "latitude": 39.74999, "longitude": -86.17005, "pop_max": 1436000 }, "geometry": { "type": "Point", "coordinates": [ -86.17005, 39.74999 ] } }, -{ "type": "Feature", "properties": { "name": "Wilmington", "sov_a3": "USA", "latitude": 34.22552, "longitude": -77.94502, "pop_max": 161560 }, "geometry": { "type": "Point", "coordinates": [ -77.94502, 34.22552 ] } }, -{ "type": "Feature", "properties": { "name": "Knoxville", "sov_a3": "USA", "latitude": 35.97001, "longitude": -83.92003, "pop_max": 655400 }, "geometry": { "type": "Point", "coordinates": [ -83.92003, 35.97001 ] } }, -{ "type": "Feature", "properties": { "name": "Richmond", "sov_a3": "USA", "latitude": 37.55002, "longitude": -77.44999, "pop_max": 912000 }, "geometry": { "type": "Point", "coordinates": [ -77.44999, 37.55002 ] } }, -{ "type": "Feature", "properties": { "name": "Charleston", "sov_a3": "USA", "latitude": 38.34974, "longitude": -81.63273, "pop_max": 123799 }, "geometry": { "type": "Point", "coordinates": [ -81.63273, 38.34974 ] } }, -{ "type": "Feature", "properties": { "name": "Baltimore", "sov_a3": "USA", "latitude": 39.29999, "longitude": -76.61998, "pop_max": 2255000 }, "geometry": { "type": "Point", "coordinates": [ -76.61998, 39.29999 ] } }, -{ "type": "Feature", "properties": { "name": "Syracuse", "sov_a3": "USA", "latitude": 43.04999, "longitude": -76.15001, "pop_max": 662577 }, "geometry": { "type": "Point", "coordinates": [ -76.15001, 43.04999 ] } }, -{ "type": "Feature", "properties": { "name": "Augusta", "sov_a3": "USA", "latitude": 44.31056, "longitude": -69.77999, "pop_max": 24042 }, "geometry": { "type": "Point", "coordinates": [ -69.77999, 44.31056 ] } }, -{ "type": "Feature", "properties": { "name": "Sault Ste. Marie", "sov_a3": "USA", "latitude": 46.49526, "longitude": -84.34528, "pop_max": 83805 }, "geometry": { "type": "Point", "coordinates": [ -84.34528, 46.49526 ] } }, -{ "type": "Feature", "properties": { "name": "Sitka", "sov_a3": "USA", "latitude": 57.0604, "longitude": -135.32755, "pop_max": 8931 }, "geometry": { "type": "Point", "coordinates": [ -135.32755, 57.0604 ] } }, -{ "type": "Feature", "properties": { "name": "Pago Pago", "sov_a3": "USA", "latitude": -14.27661, "longitude": -170.70665, "pop_max": 12576 }, "geometry": { "type": "Point", "coordinates": [ -170.70665, -14.27661 ] } }, -{ "type": "Feature", "properties": { "name": "Helena", "sov_a3": "USA", "latitude": 46.59275, "longitude": -112.03529, "pop_max": 38725 }, "geometry": { "type": "Point", "coordinates": [ -112.03529, 46.59275 ] } }, -{ "type": "Feature", "properties": { "name": "Bismarck", "sov_a3": "USA", "latitude": 46.80832, "longitude": -100.78332, "pop_max": 63871 }, "geometry": { "type": "Point", "coordinates": [ -100.78332, 46.80832 ] } }, -{ "type": "Feature", "properties": { "name": "Boise", "sov_a3": "USA", "latitude": 43.60859, "longitude": -116.22749, "pop_max": 338071 }, "geometry": { "type": "Point", "coordinates": [ -116.22749, 43.60859 ] } }, -{ "type": "Feature", "properties": { "name": "San Jose", "sov_a3": "USA", "latitude": 37.29998, "longitude": -121.84999, "pop_max": 1668000 }, "geometry": { "type": "Point", "coordinates": [ -121.84999, 37.29998 ] } }, -{ "type": "Feature", "properties": { "name": "Sacramento", "sov_a3": "USA", "latitude": 38.57502, "longitude": -121.47004, "pop_max": 1604000 }, "geometry": { "type": "Point", "coordinates": [ -121.47004, 38.57502 ] } }, -{ "type": "Feature", "properties": { "name": "Las Vegas", "sov_a3": "USA", "latitude": 36.21, "longitude": -115.22001, "pop_max": 1823000 }, "geometry": { "type": "Point", "coordinates": [ -115.22001, 36.21 ] } }, -{ "type": "Feature", "properties": { "name": "Santa Fe", "sov_a3": "USA", "latitude": 35.68693, "longitude": -105.93724, "pop_max": 92681 }, "geometry": { "type": "Point", "coordinates": [ -105.93724, 35.68693 ] } }, -{ "type": "Feature", "properties": { "name": "Portland", "sov_a3": "USA", "latitude": 45.52002, "longitude": -122.67999, "pop_max": 1875000 }, "geometry": { "type": "Point", "coordinates": [ -122.67999, 45.52002 ] } }, -{ "type": "Feature", "properties": { "name": "Salt Lake City", "sov_a3": "USA", "latitude": 40.77502, "longitude": -111.93005, "pop_max": 966000 }, "geometry": { "type": "Point", "coordinates": [ -111.93005, 40.77502 ] } }, -{ "type": "Feature", "properties": { "name": "Cheyenne", "sov_a3": "USA", "latitude": 41.14001, "longitude": -104.81971, "pop_max": 72927 }, "geometry": { "type": "Point", "coordinates": [ -104.81971, 41.14001 ] } }, -{ "type": "Feature", "properties": { "name": "Des Moines", "sov_a3": "USA", "latitude": 41.57998, "longitude": -93.61998, "pop_max": 380655 }, "geometry": { "type": "Point", "coordinates": [ -93.61998, 41.57998 ] } }, -{ "type": "Feature", "properties": { "name": "Omaha", "sov_a3": "USA", "latitude": 41.24, "longitude": -96.00999, "pop_max": 877110 }, "geometry": { "type": "Point", "coordinates": [ -96.00999, 41.24 ] } }, -{ "type": "Feature", "properties": { "name": "Oklahoma City", "sov_a3": "USA", "latitude": 35.47004, "longitude": -97.51868, "pop_max": 788000 }, "geometry": { "type": "Point", "coordinates": [ -97.51868, 35.47004 ] } }, -{ "type": "Feature", "properties": { "name": "Pierre", "sov_a3": "USA", "latitude": 44.36834, "longitude": -100.35055, "pop_max": 13879 }, "geometry": { "type": "Point", "coordinates": [ -100.35055, 44.36834 ] } }, -{ "type": "Feature", "properties": { "name": "San Antonio", "sov_a3": "USA", "latitude": 29.48733, "longitude": -98.50731, "pop_max": 1473000 }, "geometry": { "type": "Point", "coordinates": [ -98.50731, 29.48733 ] } }, -{ "type": "Feature", "properties": { "name": "Jackson", "sov_a3": "USA", "latitude": 32.29882, "longitude": -90.185, "pop_max": 250902 }, "geometry": { "type": "Point", "coordinates": [ -90.185, 32.29882 ] } }, -{ "type": "Feature", "properties": { "name": "Raleigh", "sov_a3": "USA", "latitude": 35.81878, "longitude": -78.64469, "pop_max": 1163515 }, "geometry": { "type": "Point", "coordinates": [ -78.64469, 35.81878 ] } }, -{ "type": "Feature", "properties": { "name": "Cleveland", "sov_a3": "USA", "latitude": 41.46999, "longitude": -81.695, "pop_max": 1890000 }, "geometry": { "type": "Point", "coordinates": [ -81.695, 41.46999 ] } }, -{ "type": "Feature", "properties": { "name": "Cincinnati", "sov_a3": "USA", "latitude": 39.16188, "longitude": -84.45692, "pop_max": 1636000 }, "geometry": { "type": "Point", "coordinates": [ -84.45692, 39.16188 ] } }, -{ "type": "Feature", "properties": { "name": "Nashville", "sov_a3": "USA", "latitude": 36.16997, "longitude": -86.77998, "pop_max": 877000 }, "geometry": { "type": "Point", "coordinates": [ -86.77998, 36.16997 ] } }, -{ "type": "Feature", "properties": { "name": "Memphis", "sov_a3": "USA", "latitude": 35.11999, "longitude": -90.0, "pop_max": 1081000 }, "geometry": { "type": "Point", "coordinates": [ -90.0, 35.11999 ] } }, -{ "type": "Feature", "properties": { "name": "Norfolk", "sov_a3": "USA", "latitude": 36.84996, "longitude": -76.28001, "pop_max": 1047869 }, "geometry": { "type": "Point", "coordinates": [ -76.28001, 36.84996 ] } }, -{ "type": "Feature", "properties": { "name": "Milwaukee", "sov_a3": "USA", "latitude": 43.05266, "longitude": -87.91997, "pop_max": 1388000 }, "geometry": { "type": "Point", "coordinates": [ -87.91997, 43.05266 ] } }, -{ "type": "Feature", "properties": { "name": "Buffalo", "sov_a3": "USA", "latitude": 42.87998, "longitude": -78.88, "pop_max": 1016000 }, "geometry": { "type": "Point", "coordinates": [ -78.88, 42.87998 ] } }, -{ "type": "Feature", "properties": { "name": "Pittsburgh", "sov_a3": "USA", "latitude": 40.43, "longitude": -79.99999, "pop_max": 1838000 }, "geometry": { "type": "Point", "coordinates": [ -79.99999, 40.43 ] } }, -{ "type": "Feature", "properties": { "name": "Kodiak", "sov_a3": "USA", "latitude": 57.79, "longitude": -152.40699, "pop_max": 9461 }, "geometry": { "type": "Point", "coordinates": [ -152.40699, 57.79 ] } }, -{ "type": "Feature", "properties": { "name": "Cold Bay", "sov_a3": "USA", "latitude": 55.2, "longitude": -162.71509, "pop_max": 200 }, "geometry": { "type": "Point", "coordinates": [ -162.71509, 55.2 ] } }, -{ "type": "Feature", "properties": { "name": "Bethel", "sov_a3": "USA", "latitude": 60.7933, "longitude": -161.7558, "pop_max": 6228 }, "geometry": { "type": "Point", "coordinates": [ -161.7558, 60.7933 ] } }, -{ "type": "Feature", "properties": { "name": "Point Hope", "sov_a3": "USA", "latitude": 68.34773, "longitude": -166.80802, "pop_max": 461 }, "geometry": { "type": "Point", "coordinates": [ -166.80802, 68.34773 ] } }, -{ "type": "Feature", "properties": { "name": "Barrow", "sov_a3": "USA", "latitude": 71.29057, "longitude": -156.78858, "pop_max": 4336 }, "geometry": { "type": "Point", "coordinates": [ -156.78858, 71.29057 ] } }, -{ "type": "Feature", "properties": { "name": "Nome", "sov_a3": "USA", "latitude": 64.5061, "longitude": -165.40637, "pop_max": 3485 }, "geometry": { "type": "Point", "coordinates": [ -165.40637, 64.5061 ] } }, -{ "type": "Feature", "properties": { "name": "Valdez", "sov_a3": "USA", "latitude": 61.136, "longitude": -146.34829, "pop_max": 4036 }, "geometry": { "type": "Point", "coordinates": [ -146.34829, 61.136 ] } }, -{ "type": "Feature", "properties": { "name": "Juneau", "sov_a3": "USA", "latitude": 58.31413, "longitude": -134.42, "pop_max": 30711 }, "geometry": { "type": "Point", "coordinates": [ -134.42, 58.31413 ] } }, -{ "type": "Feature", "properties": { "name": "Fairbanks", "sov_a3": "USA", "latitude": 64.83698, "longitude": -147.71066, "pop_max": 56993 }, "geometry": { "type": "Point", "coordinates": [ -147.71066, 64.83698 ] } }, -{ "type": "Feature", "properties": { "name": "Prudhoe Bay", "sov_a3": "USA", "latitude": 70.29218, "longitude": -148.66936, "pop_max": 2500 }, "geometry": { "type": "Point", "coordinates": [ -148.66936, 70.29218 ] } }, -{ "type": "Feature", "properties": { "name": "San Juan", "sov_a3": "USA", "latitude": 18.44002, "longitude": -66.12998, "pop_max": 2478905 }, "geometry": { "type": "Point", "coordinates": [ -66.12998, 18.44002 ] } }, -{ "type": "Feature", "properties": { "name": "Minneapolis", "sov_a3": "USA", "latitude": 44.97998, "longitude": -93.25179, "pop_max": 2616000 }, "geometry": { "type": "Point", "coordinates": [ -93.25179, 44.97998 ] } }, -{ "type": "Feature", "properties": { "name": "Honolulu", "sov_a3": "USA", "latitude": 21.30688, "longitude": -157.858, "pop_max": 786000 }, "geometry": { "type": "Point", "coordinates": [ -157.858, 21.30688 ] } }, -{ "type": "Feature", "properties": { "name": "Seattle", "sov_a3": "USA", "latitude": 47.57, "longitude": -122.33998, "pop_max": 3074000 }, "geometry": { "type": "Point", "coordinates": [ -122.33998, 47.57 ] } }, -{ "type": "Feature", "properties": { "name": "Phoenix", "sov_a3": "USA", "latitude": 33.53998, "longitude": -112.06999, "pop_max": 3551000 }, "geometry": { "type": "Point", "coordinates": [ -112.06999, 33.53998 ] } }, -{ "type": "Feature", "properties": { "name": "San Diego", "sov_a3": "USA", "latitude": 32.82002, "longitude": -117.17999, "pop_max": 2916000 }, "geometry": { "type": "Point", "coordinates": [ -117.17999, 32.82002 ] } }, -{ "type": "Feature", "properties": { "name": "St. Louis", "sov_a3": "USA", "latitude": 38.63502, "longitude": -90.23998, "pop_max": 2199000 }, "geometry": { "type": "Point", "coordinates": [ -90.23998, 38.63502 ] } }, -{ "type": "Feature", "properties": { "name": "New Orleans", "sov_a3": "USA", "latitude": 29.995, "longitude": -90.03997, "pop_max": 785000 }, "geometry": { "type": "Point", "coordinates": [ -90.03997, 29.995 ] } }, -{ "type": "Feature", "properties": { "name": "Dallas", "sov_a3": "USA", "latitude": 32.82002, "longitude": -96.84002, "pop_max": 4798000 }, "geometry": { "type": "Point", "coordinates": [ -96.84002, 32.82002 ] } }, -{ "type": "Feature", "properties": { "name": "Boston", "sov_a3": "USA", "latitude": 42.32996, "longitude": -71.07001, "pop_max": 4467000 }, "geometry": { "type": "Point", "coordinates": [ -71.07001, 42.32996 ] } }, -{ "type": "Feature", "properties": { "name": "Tampa", "sov_a3": "USA", "latitude": 27.94699, "longitude": -82.45862, "pop_max": 2314000 }, "geometry": { "type": "Point", "coordinates": [ -82.45862, 27.94699 ] } }, -{ "type": "Feature", "properties": { "name": "Philadelphia", "sov_a3": "USA", "latitude": 39.99997, "longitude": -75.17, "pop_max": 5492000 }, "geometry": { "type": "Point", "coordinates": [ -75.17, 39.99997 ] } }, -{ "type": "Feature", "properties": { "name": "Detroit", "sov_a3": "USA", "latitude": 42.32996, "longitude": -83.08006, "pop_max": 4101000 }, "geometry": { "type": "Point", "coordinates": [ -83.08006, 42.32996 ] } }, -{ "type": "Feature", "properties": { "name": "Anchorage", "sov_a3": "USA", "latitude": 61.21997, "longitude": -149.90021, "pop_max": 260283 }, "geometry": { "type": "Point", "coordinates": [ -149.90021, 61.21997 ] } }, -{ "type": "Feature", "properties": { "name": "San Francisco", "sov_a3": "USA", "latitude": 37.74001, "longitude": -122.45998, "pop_max": 3450000 }, "geometry": { "type": "Point", "coordinates": [ -122.45998, 37.74001 ] } }, -{ "type": "Feature", "properties": { "name": "Denver", "sov_a3": "USA", "latitude": 39.73919, "longitude": -104.98402, "pop_max": 2313000 }, "geometry": { "type": "Point", "coordinates": [ -104.98402, 39.73919 ] } }, -{ "type": "Feature", "properties": { "name": "Houston", "sov_a3": "USA", "latitude": 29.81997, "longitude": -95.33998, "pop_max": 4459000 }, "geometry": { "type": "Point", "coordinates": [ -95.33998, 29.81997 ] } }, -{ "type": "Feature", "properties": { "name": "Miami", "sov_a3": "USA", "latitude": 25.78761, "longitude": -80.22411, "pop_max": 5585000 }, "geometry": { "type": "Point", "coordinates": [ -80.22411, 25.78761 ] } }, -{ "type": "Feature", "properties": { "name": "Atlanta", "sov_a3": "USA", "latitude": 33.83001, "longitude": -84.39995, "pop_max": 4506000 }, "geometry": { "type": "Point", "coordinates": [ -84.39995, 33.83001 ] } }, -{ "type": "Feature", "properties": { "name": "Chicago", "sov_a3": "USA", "latitude": 41.82999, "longitude": -87.75005, "pop_max": 8990000 }, "geometry": { "type": "Point", "coordinates": [ -87.75005, 41.82999 ] } }, -{ "type": "Feature", "properties": { "name": "Los Angeles", "sov_a3": "USA", "latitude": 33.98998, "longitude": -118.17998, "pop_max": 12500000 }, "geometry": { "type": "Point", "coordinates": [ -118.17998, 33.98998 ] } }, -{ "type": "Feature", "properties": { "name": "Washington D.C.", "sov_a3": "USA", "latitude": 38.89955, "longitude": -77.00942, "pop_max": 4338000 }, "geometry": { "type": "Point", "coordinates": [ -77.00942, 38.89955 ] } }, -{ "type": "Feature", "properties": { "name": "New York", "sov_a3": "USA", "latitude": 40.74998, "longitude": -73.98002, "pop_max": 19040000 }, "geometry": { "type": "Point", "coordinates": [ -73.98002, 40.74998 ] } } -] -} diff --git a/leafmap/foliumap.py b/leafmap/foliumap.py index 3a0c77c7cf..107dee9d34 100644 --- a/leafmap/foliumap.py +++ b/leafmap/foliumap.py @@ -1953,6 +1953,12 @@ def video_overlay(self, url, bounds, name): "The folium plotting backend does not support this function. Use the ipyleaflet plotting backend instead." ) + def add_search_control( + self, url, marker=None, zoom=None, position="topleft", **kwargs + ): + """Adds a search control to the map.""" + print("The folium plotting backend does not support this function.") + def delete_dp_report(name): """Deletes a datapane report. diff --git a/leafmap/plotlymap.py b/leafmap/plotlymap.py index e3e3a16b83..0ae4992c76 100644 --- a/leafmap/plotlymap.py +++ b/leafmap/plotlymap.py @@ -106,7 +106,7 @@ def show( refresh (bool, optional): Whether to refresh the map when the map is resized. Defaults to False. Returns: - Canvas: [description] + Canvas: Map canvas. """ if not toolbar: super().show(**kwargs) @@ -627,22 +627,22 @@ def add_gdf_demo( fig = go.Choroplethmapbox( geojson=geojson_url, - featureidkey='properties.{}'.format(label_col), + featureidkey="properties.{}".format(label_col), locations=gdf[label_col], z=gdf[color_col], autocolorscale=False, colorscale=color_continuous_scale, - marker_line_color='peachpuff', + marker_line_color="peachpuff", colorbar=dict( - title={'text': "Legend"}, + title={"text": "Legend"}, thickness=15, len=0.35, - bgcolor='rgba(255,255,255,0.6)', - xanchor='left', + bgcolor="rgba(255,255,255,0.6)", + xanchor="left", x=0.02, - yanchor='bottom', - y=0.05 - ) + yanchor="bottom", + y=0.05, + ), ) self.add_trace(fig) @@ -706,12 +706,12 @@ def add_gdf( self.set_center(center_lat, center_lon, zoom) del fig - def add_geojson_layer(self, geojson_in, name, color='blue', opacity=1): + def add_geojson_layer(self, geojson_in, name, color="blue", opacity=1): """Prepare proper and give style for different type of Geometry Args: in_geojson (str | dict): The file path or http URL to the input GeoJSON or a dictionary containing the geojson. - name (str): Name for the Layer + name (str): Name for the Layer color (str, optional): Plain name for color (e.g: blue) or color code (e.g: #FF0000) opacity(float, optional): opacity of the layer in Map """ @@ -723,24 +723,24 @@ def add_geojson_layer(self, geojson_in, name, color='blue', opacity=1): data = geojson_in elif geojson_in.startswith("http"): data = requests.get(geojson_in).json() - elif geojson_in.lower().endswith(('.json', '.geojson')): + elif geojson_in.lower().endswith((".json", ".geojson")): with open(geojson_in) as fp: data = json.load(fp) else: data = geojson_in """ Only Checking Geometry of first feature( todo : handle multiple type of Geometry in same geojson ) """ - first_feature = data['features'][0] - geometry_type = first_feature['geometry']['type'] - - if(geometry_type.lower() in ["polygon", 'multipolygon']): - type = 'fill' - elif(geometry_type.lower() in ["linstring", 'multilinestring']): - type = 'line' - elif(geometry_type.lower() in ["point", "multipoint"]): - type = 'circle' + first_feature = data["features"][0] + geometry_type = first_feature["geometry"]["type"] + + if geometry_type.lower() in ["polygon", "multipolygon"]: + type = "fill" + elif geometry_type.lower() in ["linstring", "multilinestring"]: + type = "line" + elif geometry_type.lower() in ["point", "multipoint"]: + type = "circle" else: - type = 'fill' + type = "fill" self.add_geojson(data, name, type, color, opacity) @@ -749,31 +749,25 @@ def add_geojson(self, data, name, type, color, opacity): Args: data (dict): Geojson in Dict form - name (str): Name for the Layer + name (str): Name for the Layer color (str, optional): Plain name for color (e.g: blue) or color code (e.g: #FF0000) opacity(float, optional): opacity of the layer in Map """ new_layer = { - 'source': data, - 'name': name, - 'type': type, - 'opacity': opacity, - 'color': color, - + "source": data, + "name": name, + "type": type, + "opacity": opacity, + "color": color, } - if(type == 'circle'): - new_layer['circle'] = { - 'radius': 5 - } + if type == "circle": + new_layer["circle"] = {"radius": 5} existing_layers = list(self.layout.mapbox.layers) existing_layers.append(new_layer) - self.update_layout( - mapbox={ - 'layers': tuple(existing_layers) - }) + self.update_layout(mapbox={"layers": tuple(existing_layers)}) def fix_widget_error(): @@ -784,8 +778,7 @@ def fix_widget_error(): import shutil basedatatypesPath = os.path.join( - os.path.dirname( - os.__file__), "site-packages", "plotly", "basedatatypes.py" + os.path.dirname(os.__file__), "site-packages", "plotly", "basedatatypes.py" ) backup_file = basedatatypesPath.replace(".py", "_bk.py") diff --git a/leafmap/toolbar.py b/leafmap/toolbar.py index 69490b1b94..c40215f34c 100644 --- a/leafmap/toolbar.py +++ b/leafmap/toolbar.py @@ -260,10 +260,18 @@ def main_toolbar(m): "name": "search_geojson", "tooltip": "Search features in GeoJSON layer", }, - # "spinner": { - # "name": "placeholder2", - # "tooltip": "This is a placeholder", - # }, + "table": { + "name": "attribute_table", + "tooltip": "Open attribute table", + }, + "smile-o": { + "name": "placeholder2", + "tooltip": "This is a placeholder", + }, + "spinner": { + "name": "placeholder2", + "tooltip": "This is a placeholder", + }, "question": { "name": "help", "tooltip": "Get help", @@ -362,6 +370,8 @@ def tool_callback(change): open_raster_gui(m) elif tool_name == "search_geojson": search_geojson_gui(m) + elif tool_name == "attribute_table": + select_table_gui(m) elif tool_name == "help": import webbrowser @@ -3357,7 +3367,11 @@ def button_clicked(change): def plotly_whitebox_gui(canvas): + """Display a GUI for the whitebox tool. + Args: + canvas (plotlymap.Canvas): Map canvas. + """ import whiteboxgui.whiteboxgui as wbt container_widget = canvas.container_widget @@ -3638,3 +3652,404 @@ def button_clicked(change): m.tool_control = toolbar_control else: return toolbar_widget + + +def select_table_gui(m=None): + """GUI for selecting layers to display attribute table. + + Args: + m (leafmap.Map, optional): The leaflet Map object. Defaults to None. + + Returns: + ipywidgets: The tool GUI widget. + """ + import ipysheet + + widget_width = "250px" + padding = "0px 0px 0px 5px" # upper, right, bottom, left + style = {"description_width": "initial"} + + toolbar_button = widgets.ToggleButton( + value=False, + tooltip="Toolbar", + icon="table", + layout=widgets.Layout(width="28px", height="28px", padding="0px 0px 0px 4px"), + ) + + close_button = widgets.ToggleButton( + value=False, + tooltip="Close the tool", + icon="times", + button_style="primary", + layout=widgets.Layout(height="28px", width="28px", padding="0px 0px 0px 4px"), + ) + + layer_options = [] + if len(m.geojson_layers) > 0: + layer_options = [layer.name for layer in m.geojson_layers] + + layers = widgets.Dropdown( + options=layer_options, + value=None, + description="Layer:", + layout=widgets.Layout(width=widget_width, padding=padding), + style=style, + ) + + buttons = widgets.ToggleButtons( + value=None, + options=["Apply", "Reset", "Close"], + tooltips=["Apply", "Reset", "Close"], + button_style="primary", + ) + buttons.style.button_width = "80px" + + output = widgets.Output(layout=widgets.Layout(width=widget_width, padding=padding)) + + if len(m.geojson_layers) == 0: + with output: + print("Please add vector data layers to the map before using this tool.") + + toolbar_widget = widgets.VBox() + toolbar_widget.children = [toolbar_button] + toolbar_header = widgets.HBox() + toolbar_header.children = [close_button, toolbar_button] + toolbar_footer = widgets.VBox() + toolbar_footer.children = [ + layers, + buttons, + output, + ] + + toolbar_event = ipyevents.Event( + source=toolbar_widget, watched_events=["mouseenter", "mouseleave"] + ) + + def handle_toolbar_event(event): + + if event["type"] == "mouseenter": + toolbar_widget.children = [toolbar_header, toolbar_footer] + elif event["type"] == "mouseleave": + if not toolbar_button.value: + toolbar_widget.children = [toolbar_button] + toolbar_button.value = False + close_button.value = False + + toolbar_event.on_dom_event(handle_toolbar_event) + + def toolbar_btn_click(change): + if change["new"]: + close_button.value = False + toolbar_widget.children = [toolbar_header, toolbar_footer] + else: + if not close_button.value: + toolbar_widget.children = [toolbar_button] + + toolbar_button.observe(toolbar_btn_click, "value") + + def close_btn_click(change): + if change["new"]: + toolbar_button.value = False + if m is not None: + m.toolbar_reset() + if m.tool_control is not None and m.tool_control in m.controls: + m.remove_control(m.tool_control) + m.tool_control = None + + toolbar_widget.close() + + close_button.observe(close_btn_click, "value") + + def button_clicked(change): + if change["new"] == "Apply": + if len(m.geojson_layers) > 0 and layers.value is not None: + if hasattr(m, "table_control"): + m.remove_control(m.table_control) + lyr_index = layers.options.index(layers.value) + data = m.geojson_layers[lyr_index].data + df = geojson_to_df(data) + show_table_gui(m, df) + elif change["new"] == "Reset": + output.clear_output() + layers.value = None + + elif change["new"] == "Close": + if m is not None: + m.toolbar_reset() + if m.tool_control is not None and m.tool_control in m.controls: + m.remove_control(m.tool_control) + m.tool_control = None + + toolbar_widget.close() + + buttons.value = None + + buttons.observe(button_clicked, "value") + + toolbar_button.value = True + if m is not None: + toolbar_control = ipyleaflet.WidgetControl( + widget=toolbar_widget, position="topright" + ) + + if toolbar_control not in m.controls: + m.add_control(toolbar_control) + m.tool_control = toolbar_control + else: + return toolbar_widget + + +def show_table_gui(m, df): + """Open the attribute table GUI. + + Args: + m (leafmap.Map, optional): The leaflet Map object + + Returns: + ipywidgets: The tool GUI widget. + """ + import ipysheet + + widget_width = "560px" + padding = "0px 0px 0px 5px" # upper, right, bottom, left + style = {"description_width": "initial"} + + sheet = ipysheet.from_dataframe(df.head(10)) + + output = widgets.Output( + layout=widgets.Layout( + width=widget_width, + padding=padding, + ) + ) + + checkbox = widgets.Checkbox( + description="Show all rows", + indent=False, + layout=widgets.Layout(padding=padding, width="115px"), + ) + + sheet.layout.width = output.layout.width + + def checkbox_clicked(change): + + output.clear_output() + + if change["new"]: + sheet = ipysheet.from_dataframe(df) + else: + sheet = ipysheet.from_dataframe(df.head(10)) + + sheet.layout.max_width = output.layout.width + output.layout.max_height = str(int(m.layout.height[:-2]) - 220) + "px" + sheet.layout.max_height = output.layout.height + if sheet.layout.height > output.layout.max_height: + sheet.layout.height = output.layout.max_height + with output: + display(sheet) + + checkbox.observe(checkbox_clicked, "value") + + toolbar_button = widgets.ToggleButton( + value=False, + tooltip="Minimize window", + icon="window-minimize", + layout=widgets.Layout(width="28px", height="28px", padding="0px 0px 0px 4px"), + ) + + close_button = widgets.ToggleButton( + value=False, + tooltip="Close the tool", + icon="times", + button_style="primary", + layout=widgets.Layout(height="28px", width="28px", padding="0px 0px 0px 4px"), + ) + + toolbar_widget = widgets.VBox() + m.table_widget = toolbar_widget + m.table_output = output + + reset_btn = widgets.Button( + tooltip="Reset the plot", + icon="home", + layout=widgets.Layout(height="28px", width="28px", padding="0px 0px 0px 0px"), + ) + + def reset_btn_clicked(b): + + output.layout.width = widget_width + output.layout.max_height = str(int(m.layout.height[:-2]) - 220) + "px" + + reset_btn.on_click(reset_btn_clicked) + + fullscreen_btn = widgets.Button( + tooltip="Fullscreen the attribute table", + icon="arrows-alt", + layout=widgets.Layout(height="28px", width="28px", padding="0px 0px 0px 0px"), + ) + + def fullscreen_btn_clicked(b): + + output.layout.width = "1000px" + output.layout.max_height = str(int(m.layout.height[:-2]) - 220) + "px" + + sheet.layout.width = output.layout.width + with output: + output.clear_output() + display(sheet) + + fullscreen_btn.on_click(fullscreen_btn_clicked) + + width_btn = widgets.Button( + tooltip="Change table width", + icon="arrows-h", + layout=widgets.Layout(height="28px", width="28px", padding="0px 0px 0px 0px"), + ) + + height_btn = widgets.Button( + tooltip="Change table height", + icon="arrows-v", + layout=widgets.Layout(height="28px", width="28px", padding="0px 0px 0px 0px"), + ) + + width_slider = widgets.IntSlider( + value=560, + min=550, + max=1500, + step=10, + description="", + readout=False, + continuous_update=False, + layout=widgets.Layout(width="100px", padding=padding), + style={"description_width": "initial"}, + ) + + width_slider_label = widgets.Label( + layout=widgets.Layout(padding="0px 10px 0px 0px") + ) + widgets.jslink((width_slider, "value"), (width_slider_label, "value")) + + def width_changed(change): + if change["new"]: + output.layout.width = str(width_slider.value) + "px" + + if checkbox.value: + sheet = ipysheet.from_dataframe(df) + else: + sheet = ipysheet.from_dataframe(df.head(10)) + sheet.layout.width = output.layout.width + with output: + output.clear_output() + display(sheet) + + width_slider.observe(width_changed, "value") + + height_slider = widgets.IntSlider( + value=250, + min=200, + max=1000, + step=10, + description="", + readout=False, + continuous_update=False, + layout=widgets.Layout(width="100px", padding=padding), + style={"description_width": "initial"}, + ) + + height_slider_label = widgets.Label() + widgets.jslink((height_slider, "value"), (height_slider_label, "value")) + + def height_changed(change): + if change["new"]: + output.layout.max_height = str(height_slider.value) + "px" + if checkbox.value: + sheet = ipysheet.from_dataframe(df) + else: + sheet = ipysheet.from_dataframe(df.head(10)) + + sheet.layout.height = output.layout.max_height + with output: + output.clear_output() + display(sheet) + + height_slider.observe(height_changed, "value") + + toolbar_widget.children = [toolbar_button] + toolbar_header = widgets.HBox() + toolbar_header.children = [ + close_button, + toolbar_button, + reset_btn, + fullscreen_btn, + width_btn, + width_slider, + width_slider_label, + height_btn, + height_slider, + height_slider_label, + checkbox, + ] + toolbar_footer = widgets.VBox() + toolbar_footer.children = [ + output, + ] + + toolbar_event = ipyevents.Event( + source=toolbar_widget, watched_events=["mouseenter", "mouseleave"] + ) + + def handle_toolbar_event(event): + + if event["type"] == "mouseenter": + toolbar_widget.children = [toolbar_header, toolbar_footer] + toolbar_button.icon = "window-minimize" + elif event["type"] == "mouseleave": + if not toolbar_button.value: + toolbar_widget.children = [toolbar_button] + toolbar_button.value = False + close_button.value = False + toolbar_button.icon = "window-maximize" + + toolbar_event.on_dom_event(handle_toolbar_event) + + def toolbar_btn_click(change): + if change["new"]: + close_button.value = False + toolbar_widget.children = [toolbar_header, toolbar_footer] + toolbar_button.icon = "window-minimize" + else: + if not close_button.value: + toolbar_widget.children = [toolbar_button] + toolbar_button.icon = "window-maximize" + + toolbar_button.observe(toolbar_btn_click, "value") + + def close_btn_click(change): + if change["new"]: + toolbar_button.value = False + if m is not None: + m.toolbar_reset() + if m.table_control is not None and m.table_control in m.controls: + m.remove_control(m.table_control) + m.table_control = None + delattr(m, "table_control") + + toolbar_widget.close() + + close_button.observe(close_btn_click, "value") + + with output: + + display(sheet) + + toolbar_button.value = True + if m is not None: + table_control = ipyleaflet.WidgetControl( + widget=toolbar_widget, position="topright" + ) + + if table_control not in m.controls: + m.add_control(table_control) + m.table_control = table_control + else: + return toolbar_widget diff --git a/mkdocs.yml b/mkdocs.yml index 095e7a55fa..4c3e246d71 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -124,3 +124,4 @@ nav: - notebooks/41_raster_gui.ipynb - notebooks/42_create_cog.ipynb - notebooks/43_search_control.ipynb + - notebooks/44_attribute_table.ipynb diff --git a/requirements.txt b/requirements.txt index 392d6966a4..a00af4e05b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ here-map-widget-for-jupyter>=1.1.1 ipyevents<=0.9.0 ipyfilechooser>=0.6.0 ipyleaflet +ipysheet jupyterlab>=3.0.0 matplotlib mss