{ "cells": [ { "cell_type": "markdown", "id": "2471571e", "metadata": {}, "source": [ "(gm-section)=\n", "# Grondwatermonitoring (GM) in samenhang\n", "Downloading head-data using for Groundwater Monitoring Wells ({ref}`gmw-in-gld-section`) can require a lot of requests to the BRO-REST-service: characteristics, GrounwaterMonitoringWells and GroundwaterLevelDossiers/GroundwaterAnalysisReports. To simplify this process PDOK hosts the dataset \"Grondwatermonitoring (GM) in samenhang\" (available since 2024), which contains summary and characteristic information about registration objects within the groundwater monitoring domain, including the relationships between these registration objects. It provides key data such as the horizontal and vertical positions of measurement tubes, but not full well or tube metadata.\n", "\n", "Previously ({ref}`gm-in-gld-section`) we demonstrated the use of this dataset to download groundwater heads within a specific area. In this notebook we will show more options to use this dataset, for example to filter the monitoring tubes before downloading actual measurements." ] }, { "cell_type": "code", "execution_count": null, "id": "629b85cf", "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import brodata" ] }, { "cell_type": "markdown", "id": "5c5b7099", "metadata": {}, "source": [ "## Download location of tubes\n", "First we will download the location of grundwater monitoring tubes by calling `brodata.gm.get_data_in_extent` with the argument `kind=None`. This only requires a singe request to the PDOK-webservice, and resurns a GeoDataFrame. The index of this GeoDataFrame contains the bro-id of the Groundwater Monitoring Well and the tube number." ] }, { "cell_type": "code", "execution_count": null, "id": "7534e484", "metadata": {}, "outputs": [], "source": [ "extent = [117700, 118700, 439400, 440400]\n", "tubes = brodata.gm.get_data_in_extent(extent, kind=None)\n", "tubes" ] }, { "cell_type": "markdown", "id": "eda04976", "metadata": {}, "source": [ "## Making a selection of tubes\n", "Before we will download measurements, we can make a selection. For example, we can select all tubes where the top of the well screen is below -2.5 m NAP.\n", "\n", "We can then plot the selection of this GeoDataFrame on a map using `tubes.plot()`." ] }, { "cell_type": "code", "execution_count": null, "id": "8fd53aac", "metadata": {}, "outputs": [], "source": [ "max_screen_top_position = -2.5\n", "mask = tubes['screen_top_position'] < max_screen_top_position\n", "print(f\"{mask.sum()} of {len(tubes)} tubes selected where screen_top_position < {max_screen_top_position}\")\n", "tubes_sel = tubes[mask]\n", "\n", "f, ax = plt.subplots()\n", "ax.axis(\"scaled\")\n", "ax.axis(extent)\n", "tubes.plot(ax=ax)\n", "tubes_sel.plot(ax=ax, marker='o', edgecolor='red', facecolor='none');" ] }, { "cell_type": "markdown", "id": "55f5a8d1", "metadata": {}, "source": [ "## Downloading groundwater level data\n", "We can then download groundwater level data using `brodata.gm.get_observations()`. This downloads data for two of the three monitoring tubes. So the third monitoring tube does not contain any groundwater level data." ] }, { "cell_type": "code", "execution_count": null, "id": "7a66eb63", "metadata": {}, "outputs": [], "source": [ "obs_df = brodata.gm.get_observations(extent=extent, tubes=tubes_sel, kind=\"gld\", as_csv=True)\n", "obs_df" ] }, { "cell_type": "markdown", "id": "76f1e20f", "metadata": {}, "source": [ "## Combining tubes and observations\n", "We can then add these observations to the tubes-GeoDataFrame using the method `brodata.gmw.add_observations_to_tubes`. If multiple Groundwater Level Dossiers are available for a single monitoring tube, they are combined.\n", "\n", "The index of the tubes-GeoDataFrame and the measurement-dataframe both needs to be a MultiIndex, with the bro-id of the GroundwaterMonitoringWell and the tube-number as the levels. For the tubes-GeoDataFrame this is allready the case, but for the measurement-Dataframe (`obs_df`) we need to change the index.\n", "\n", "THe resulting GeoDataFrame contains all the columns from the tubes-GeoDataFrame, with the added columns `observation` and `groundwaterLevelDossier`. The column `observation` contains one DataFrame with observations per monitoring tube. THe column `groundwaterLevelDossier` contains a list of GroundwaterLevelDossier-ids per monitoring tube. If we would have downloaded GroundwaterAnalysisReports (`kind=\"gar\"`), these columns would have been named `laboratoryAnalysis` and `groundwaterAnalysisReport`." ] }, { "cell_type": "code", "execution_count": null, "id": "a9bc82b4", "metadata": {}, "outputs": [], "source": [ "obs_df = obs_df.reset_index().set_index([\"groundwaterMonitoringWell\", \"tubeNumber\"])\n", "tubes_sel = brodata.gmw.add_observations_to_tubes(tubes_sel, obs_df, kind=\"gld\")\n", "tubes_sel" ] }, { "cell_type": "code", "execution_count": null, "id": "cfd3ebe2", "metadata": {}, "outputs": [], "source": [ "f, ax = plt.subplots(ncols=2, figsize=(10, 5))\n", "ax[0].axis(\"scaled\")\n", "ax[0].axis(extent)\n", "for i, index in enumerate(tubes_sel.index):\n", " color = f\"C{i}\"\n", " obs = tubes_sel.at[index, \"observation\"]\n", " marker = \"o\"\n", " if obs.empty:\n", " marker = \"x\"\n", " else:\n", " obs[\"value\"].plot(ax=ax[1], color=color, label=f\"{index[0]} filter {index[1]}\")\n", " tubes_sel.loc[[index]].plot(ax=ax[0], marker=marker, color=color)\n", " ax[0].annotate(\n", " f\"{index[0]}\\n filter {index[1]}\",\n", " xy=tubes_sel.loc[index].geometry.centroid.coords[0],\n", " ha=\"center\",\n", " xytext=(0, 5),\n", " textcoords=\"offset points\",\n", " )\n", "\n", "ax[1].legend();" ] } ], "metadata": { "kernelspec": { "display_name": "brodata", "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.12.12" } }, "nbformat": 4, "nbformat_minor": 5 }