Interactive map visualization of CML vector data

This module provides interactive map visualization for Commercial Microwave Link (CML) networks using Folium and GeoPandas. It allows you to explore link geometries on a map with various basemaps and controls.
Warning

Scroll wheel zoom is disabled in the documentation examples below to make page navigation easier. When you create maps yourself, scroll wheel zoom will be enabled by default.

cml, gauges = open_cml_sample(), open_gauge_sample()

Default map

Create a Folium map with multiple basemap options (OpenStreetMap, OpenTopoMap, Esri World Imagery), layer controls, fullscreen toggle, geocoder search, and measurement tools that will be used as a default for exploration.


setup_default_map


def setup_default_map(
    m:Map=None, # Optional folium map to be setup with basemaps and controls
    show:Literal='Esri.WorldGrayCanvas', # Basemap to show by default.
)->Map:

Create a default folium map with common basemaps, layers and controls.

m = setup_default_map()
Make this Notebook Trusted to load map: File -> Trust Notebook

Visualize Gauges on an interactive map.


explore_gauges


def explore_gauges(
    gauges:xarray.core.dataset.Dataset | xarray.core.dataarray.DataArray, # Gauges in pws OpenSense standard
    default:Callable=setup_default_map, # Function to set up a default map including for example basemaps or controls
    explore_kwargs:VAR_KEYWORD
)->Map:

Call self as a function.

m = explore_gauges(gauges)
Code
m.options['scrollWheelZoom'] = False
m
Make this Notebook Trusted to load map: File -> Trust Notebook

Visualize sublinkwise data


explore_data


def explore_data(
    cml:DataArray, # CML raw or derived data in OpenSense standard
    vmin:float=None, # Minimum value for the colormap
    vmax:float=None, # Maximum value for the colormap
    cmap:ListedColormap=<matplotlib.colors.ListedColormap object at 0x7f525e0fb110>, # Matplotlib colormap
)->Map:

Call self as a function.

cml = open_cml_sample()
Tip

If you are showing variables such as attenuation that will depend on several factors such as baseline, length, … remember to normalize the values. This step is not necessary when showing the rainfall.

For the sake of this example, we will normalise the variable based on data from two consecutive days. To avoid potential issues due to outliers, we will use quantiles 0.1 and 0.9.

cml = cml.sel(time=slice("2019-07-17T00:00", "2019-07-19T00:00"))
att = cml["tsl_max"] - cml["rsl_min"]
att.name = "att"
q = att.quantile([0.1, 0.9], dim="time")
att = (att - q.sel(quantile=0.1, drop=True)) / (q.sel(quantile=0.9, drop=True) - q.sel(quantile=0.1, drop=True))
/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/numpy/lib/_nanfunctions_impl.py:1593: RuntimeWarning: All-NaN slice encountered
  return fnb._ureduce(a,
Warning

Given the current state of development, we recommend plotting a maximum of one day of data at 15-minute intervals (approximately 96 timesteps). You can use the Romulo plot to identify the periods of interest. Please remember to toggle the visibility of the metadata before playing to achieve a more fluid animation.

In this case, to avoid performance issues, we will only show few hours of data.

m = explore_data(att.sel(time=slice("2019-07-17T18:00", "2019-07-18T03:00")), vmin=0, vmax=1)
Code
m.options['scrollWheelZoom'] = False
m
Make this Notebook Trusted to load map: File -> Trust Notebook

How to join visualizations?