Region Selection and Map Preview with Ipyleaflet

[1]:
# Import the necessary libraries to format, send, and parse our returned results
import os

import birdy
import geopandas as gpd
import ipyleaflet
import ipywidgets

If 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.

[2]:
# Create WPS instances
# Set environment variable WPS_URL to "http://localhost:9099" to run on the default local server
pavics_url = "https://pavics.ouranos.ca"
raven_url = os.environ.get("WPS_URL", f"{pavics_url}/twitcher/ows/proxy/raven/wps")

raven = birdy.WPSClient(raven_url)
[3]:
# Build an interactive map with ipyleaflet

initial_lat_lon = (48.63, -74.71)

leaflet_map = ipyleaflet.Map(
    center=initial_lat_lon,
    basemap=ipyleaflet.basemaps.OpenTopoMap,
)

# Add a custom zoom slider
zoom_slider = ipywidgets.IntSlider(description="Zoom level:", min=1, max=10, value=6)
ipywidgets.jslink((zoom_slider, "value"), (leaflet_map, "zoom"))
widget_control1 = ipyleaflet.WidgetControl(widget=zoom_slider, position="topright")
leaflet_map.add_control(widget_control1)

# Add a marker to the map
marker = ipyleaflet.Marker(location=initial_lat_lon, draggable=True)
leaflet_map.add_layer(marker)
[4]:
# Add an overlay widget

html = ipywidgets.HTML("""Hover over a feature!""")
html.layout.margin = "0px 10px 10px 10px"

control = ipyleaflet.WidgetControl(widget=html, position="bottomleft")
leaflet_map.add_control(control)


def update_html(feature, **kwargs):
    html.value = """
        <h2><b>USGS HydroBASINS</b></h2>
        <h4>ID: {}</h4>
        <h4>Upstream Area: {} sq. km.</h4>
        <h4>Sub-basin Area: {} sq. km.</h4>
    """.format(
        feature["properties"]["id"],
        feature["properties"]["UP_AREA"],
        feature["properties"]["SUB_AREA"],
    )
[5]:
# Load the map in the notebook
leaflet_map
[5]:

Before continuing!

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.

[6]:
user_lonlat = list(reversed(marker.location))
user_lonlat
[6]:
[-74.71, 48.63]
[7]:
# Get the shape of the watershed contributing to flow at the selected location.
resp = raven.hydrobasins_select(location=str(user_lonlat), aggregate_upstream=True)
[8]:
# Before continuing, wait for the process above to finish.

# Extract the URL of the resulting GeoJSON feature
feat = resp.get(asobj=False).feature
gdf = gpd.read_file(feat)
gdf
[8]:
id HYBAS_ID NEXT_DOWN NEXT_SINK DIST_SINK DIST_MAIN SUB_AREA UP_AREA PFAF_ID SIDE LAKE ENDO COAST ORDER SORT geometry
0 USGS_HydroBASINS_lake_na_lev12.99410 7129001061 7120323452 7120034520 517.6 517.6 8470.5 8773.1 725209301000 L 56 0 0 2 99410 POLYGON ((-75.1899 47.9954, -75.1819 47.9946, ...
[9]:
# Add this GeoJSON to the map above!
# Scroll back up after executing this cell to see the watershed displayed on the map.
user_geojson = ipyleaflet.GeoData(
    geo_dataframe=gdf,
    style={
        "color": "blue",
        "opacity": 1,
        "weight": 1.9,
        "fillOpacity": 0.5,
    },
    hover_style={"fillColor": "#b08a3e", "fillOpacity": 0.9},
)

leaflet_map.add_layer(user_geojson)
user_geojson.on_hover(update_html)