{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 01 - Getting watershed boundaries" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Region Selection and Map Preview with Ipyleaflet\n", "In this notebook, you will extract a selected watershed from the HydroSHEDS database (see the reference manual for more information on HydroSHEDS). A GeoJSON with the watershed boundaries will be available for download and usable for other tasks such as extracting meteorological data covered in the next notebooks." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Import the necessary libraries to format, send, and parse our returned results\n", "import os\n", "\n", "import birdy\n", "import geopandas as gpd\n", "import ipyleaflet\n", "import ipywidgets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you are running this locally (and not on the PAVICS-Hydro server), and your `notebook` is version prior to `5.3`, you might need to run this command `jupyter nbextension enable --py --sys-prefix ipyleaflet`. For more information see https://ipyleaflet.readthedocs.io/en/latest/installation.html.\n", "\n", "This next box is all boilerplate, you do not need to understand it or play with it. Simply run it! Many such code snippets are provided throughout the notebooks to make your life easier. You can then modify some options to taylor the code to your needs." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create WPS instances# Set environment variable WPS_URL to \"http://localhost:9099\" to run on the default local server\n", "pavics_url = \"https://pavics.ouranos.ca\"\n", "raven_url = os.environ.get(\"WPS_URL\", f\"{pavics_url}/twitcher/ows/proxy/raven/wps\")\n", "\n", "raven = birdy.WPSClient(raven_url)\n", "\n", "# Build an interactive map with ipyleaflet\n", "initial_lat_lon = (48.63, -74.71)\n", "\n", "leaflet_map = ipyleaflet.Map(\n", " center=initial_lat_lon,\n", " basemap=ipyleaflet.basemaps.OpenTopoMap,\n", ")\n", "\n", "# Add a custom zoom slider\n", "zoom_slider = ipywidgets.IntSlider(description=\"Zoom level:\", min=1, max=10, value=6)\n", "ipywidgets.jslink((zoom_slider, \"value\"), (leaflet_map, \"zoom\"))\n", "widget_control1 = ipyleaflet.WidgetControl(widget=zoom_slider, position=\"topright\")\n", "leaflet_map.add_control(widget_control1)\n", "\n", "# Add a marker to the map\n", "marker = ipyleaflet.Marker(location=initial_lat_lon, draggable=True)\n", "leaflet_map.add_layer(marker)\n", "\n", "# Add an overlay widget\n", "html = ipywidgets.HTML(\"\"\"Hover over a feature!\"\"\")\n", "html.layout.margin = \"0px 10px 10px 10px\"\n", "\n", "control = ipyleaflet.WidgetControl(widget=html, position=\"bottomleft\")\n", "leaflet_map.add_control(control)\n", "\n", "\n", "def update_html(feature, **kwargs):\n", " html.value = \"\"\"\n", "

USGS HydroBASINS

\n", "

ID: {}

\n", "

Upstream Area: {} sq. km.

\n", "

Sub-basin Area: {} sq. km.

\n", " \"\"\".format(\n", " feature[\"properties\"][\"id\"],\n", " feature[\"properties\"][\"UP_AREA\"], #\n", " feature[\"properties\"][\"SUB_AREA\"],\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using the map to select the outlet of the watershed\n", "When using the \"leaflet_map\" command, an interactive map will be displayed.\n", "\n", "Note that a blue marker will be displayed in the middle of the map, which can be dragged by interacting directly with it. Try dragging and placing the marker at the mouth of a river, over a large lake such as Lac Saint-Jean (next to Alma, east of the initial marker position), or anywhere else within North America. This coordinate will be used to find and extract the closest watershed outlet from the Hydrosheds database (see the reference manual for more info on Hydrosheds). The watershed ID and area will be displayed in the bottom left corner of the map.\n", "\n", "The user can zoom in and out on the map either by:\n", "* Using the Zoom level in the top right corner;\n", "* Using the + / - icons in the top left corner;\n", "* Double-clicking on the map on the area to zoom in." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Load the map in the notebook\n", "leaflet_map" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Display the lat/lon coordinates of the marker location.\n", "user_lonlat = list(reversed(marker.location))\n", "print(user_lonlat)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Get the shape of the watershed contributing to flow at the selected location.\n", "resp = raven.hydrobasins_select(location=str(user_lonlat), aggregate_upstream=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Before continuing, wait for the process above to finish**\n", "\n", "This can be monitored when the \"[*]:\" on the left of the cell is replaced with a number." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Extract the URL of the resulting GeoJSON feature\n", "feat = resp.get(asobj=False).feature\n", "print(\n", " \"This is the geoJSON file that can be used as the watershed contour in other toolboxes:\"\n", ")\n", "print(\"\")\n", "print(feat)\n", "print(\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## BEFORE CONTINUING:\n", "\n", "- If you are working in the writable-workspace, you will want to download the .geojson file at the link above and deposit it into your workspace on the left of your screen.\n", "- If you are running this in the default workspace after logging in, the workspace is read-only so we will provide files for you, and you can ignore this file for the time being." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Print the properties from the extracted watershed\n", "gdf = gpd.read_file(feat)\n", "gdf" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Now we will add the extracted watershed to the map above!\n", "\n", "Scroll back up after executing the next cell to see the watershed displayed in blue on the map. You may reextract another watershed by moving restarting the kernel or running all the cells from the beginning to reload the map." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Adding the GeoJSON to the map above.\n", "user_geojson = ipyleaflet.GeoData(\n", " geo_dataframe=gdf,\n", " style={\n", " \"color\": \"blue\",\n", " \"opacity\": 1,\n", " \"weight\": 1.9,\n", " \"fillOpacity\": 0.5,\n", " },\n", " hover_style={\"fillColor\": \"#b08a3e\", \"fillOpacity\": 0.9},\n", ")\n", "\n", "leaflet_map.add_layer(user_geojson)\n", "user_geojson.on_hover(update_html)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Congratulations!\n", "\n", "You have successfully created a watershed boundary file that can be used in the following notebooks. If you already have the boundaries of your watershed of interest, then you can upload them to your workspace instead of using this notebook to generate them. a geojson file is accepted, as is a shapefile. For shapefiles, provide a zip containing all the shape data (.shp, .shx, .dbf, .prj, etc.).\n" ] } ], "metadata": { "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.10.9" }, "nbdime-conflicts": { "local_diff": [ { "diff": [ { "diff": [ { "key": 0, "op": "addrange", "valuelist": [ "3.6.7" ] }, { "key": 0, "length": 1, "op": "removerange" } ], "key": "version", "op": "patch" } ], "key": "language_info", "op": "patch" } ], "remote_diff": [ { "diff": [ { "diff": [ { "key": 0, "op": "addrange", "valuelist": [ "3.6.10" ] }, { "key": 0, "length": 1, "op": "removerange" } ], "key": "version", "op": "patch" } ], "key": "language_info", "op": "patch" } ] } }, "nbformat": 4, "nbformat_minor": 4 }