Effortless River Dynamics Analysis: Mastering Flood Modeling with Just 30 Lines of Python

Effortless River Dynamics Analysis: Mastering Flood Modeling with Just 30 Lines of Python

In the realm of spatial analysis, understanding river dynamics is crucial for effective flood management and environmental conservation. But what if you could conduct a comprehensive analysis with minimal code? In this guide, I’ll show you how to harness the power of Python to model river behavior and visualize flood risks—all in under 30 lines of code! Whether you’re a seasoned programmer or a curious beginner, this step-by-step tutorial will empower you to explore the fascinating world of hydrology using simple yet powerful Python libraries.

Prerequisites

  • Basic knowledge of Python programming.

  • Familiarity with libraries like NumPy, Pandas, Geopandas and Matplotlib.

  • Understanding of geospatial data concepts.

Skills Practiced

  • Working with Digital Elevation Models (DEMs): Learn how to create, manipulate, and analyze DEMs using libraries like RIOXARRAY and XARRAY.

  • Geocoding and Spatial Data Handling: Gain proficiency in geocoding geographical features using the OSMNX library, enabling you to extract and utilize real-world data effectively.

  • Data Manipulation with NumPy and Pandas: Develop skills in data manipulation and analysis using NUMPY for numerical operations and pandas for handling structured data.

  • Spatial Interpolation Techniques: Understand how to interpolate spatial data using KD-trees for enhanced flood analysis, allowing for accurate estimation of elevation values across various geographical points.

  • Effective Data Visualization: Master the art of visualizing geographical data with MATPLOTLIB and GEOPANDAS creating insightful maps that highlight critical floodplain areas and river dynamics.

Setup

To get started with our river dynamics analysis, we’ll be using Jupyter Notebook within a virtual environment created through Anaconda. This setup provides a powerful and flexible platform for running Python code, managing dependencies, and visualizing data. Here’s how to set it up:

  1. Install Anaconda: If you haven't already, download and install Anaconda from the official website. Anaconda simplifies package management and deployment, making it easier to work with data science libraries.

  2. Create a Virtual Environment: Open the Anaconda Prompt and create a new virtual environment. This helps isolate your project dependencies from other projects on your system. You can create an environment with the following command:

     conda create --name river_analysis python=3.9
    

    Replace river_analysis with your preferred environment name.

  3. Activate the Environment: Once the environment is created, activate it using:

     conda activate river_analysis
    
  4. Install Required Libraries: With your virtual environment activated, install the necessary libraries for our analysis. You can do this by running:

     conda install numpy pandas geopandas matplotlib rioxarray osmnx xarray
    

    This command installs essential packages for data manipulation, geospatial analysis, and visualization.

  5. Launch Jupyter Notebook: After installing the required libraries, start Jupyter Notebook by running:

     jupyter notebook
    

    This command will open a new tab in your web browser where you can create and manage Jupyter notebooks.

  6. Create a New Notebook: In the Jupyter interface, click on "New" and select "Python 3" to create a new notebook. You’re now ready to start coding!

Link to the USGS DEM File am using.

Link to GitHub Repo

Install and Import required libraries

Loading the Digital Elevation Model data

We can use the USGS DEM Data, and just drag to define to define area of interest. i ended up using the 30m resolution data and focused on the Girardeau, Missouri region.

Using the ‘open_rasterio” function from rioxarray to read the GeoTIfff file named USGS_13_n38w090_20230117.tif. The resulting object, dem, is an xarray DataArray that contains the raster data along with its associated metadata. We can obtain the coordinates from the region using the website BoundingBox I roughly approximated the area i need. Choose Geojson as the file format and copy the coordinates.

Next obtain the DEM data, load it, define the area of interest, convert it to python object and use it to clip the raster data

The clip method is called on the dem DataArray to extract only the part of the raster that falls within the defined polygon. The coordinate reference system (CRS) is specified as EPSG:4326 (WGS 84).

Next we reduce the resolution of the clipped raster by averaging values over blocks of 3 pixels in both x and y dimensions. The boundary='trim' option ensures that any pixels that do not fit into complete blocks are trimmed off and finally visualize the processed raster data.

Fetching the River Coordinates

Using OSMNX we can fetch the river coordinates for my case, i had to query and find the specific OSMNX id for the Mississippi River using the name was resulting in an error.

Next we obtain the bounds of the cropped raster and clip the river geometry to ensure it matches the area of interest. This step is crucial to tailor our focus to specific river sections enhancing both the relevance and accuracy of our analysis.

Net we crop the DEM using the bounding box defined by the river geometry and visualize the cropped DEM alongside the river geometry.

Calculation of the REM

To calculate the REM we will need to do one of few things. The first thing will be sampling the elevation along the river followed by interpolating the elevation values to create a 2D elevation raster and then subtracting the interpolated elevation raster from the DEM to remain with the elevation values of the river. Let’s do that.

We start by creating a function to extract the X and Y coordinates from the river geometry and strong them as xarray Dataarrays. The elevation values along the river are sampled from the cropped DEM using nearest-neighbor interpolation. The sampling serves as an efficient method for obtaining initial elevation estimates from nearby data points.

This next section prepares arrays of coordinates for both sampled points along the river and all points in the original DEM for interpolation.

We then perform a spatial interpolation of elevation data using a KD-tree where we find nearby sampled points for given locations where elevation needs to be estimated, and then calculate the weighted contributions from these points based on their distances, and construct an organized raster representation of interpolated elevation values.

Following the obtaining of the values from the nearest neighbor analysis, interpolation helps in the smoothing of the data to obtain more accurate estimates of elevation at query locations. This reduces the potential impact of outliers or anomalies in the sampled data.

Calculating Relative Elevation Model(REM)

Next we calculate the elative Elevation Model (REM) by subtracting the interpolated elevation values(elevation_raster) from the cropped Digital Elevation Model (DEM). The REM represents the difference in elevation between the original terrain (cropped DEM) and the interpolated elevation. This calculation is crucial for identifying areas that are relatively higher or lower than the surrounding terrain, which is essential for flood risk assessment.

Next, we generate a hill-shade representation of the cropped Digital Elevation Model (DEM) to provide a three-dimensional perspective of the terrain. Finally, we stack the hillshade image and the shaded REM into a single composite image, which integrates both visualizations into one cohesive representation. This composite image is then displayed using plt.imshow() and saved as 'output_rem.png', providing a comprehensive view of flood-prone areas and enhancing our understanding of river dynamics.

Finally, we stack the hillshade image and the shaded REM into a single composite image, which integrates both visualizations into one cohesive representation. This composite image is then displayed using plt.imshow() and saved as 'output_rem.png', this allows us to see the dynamics of flood-prone regions and where the river has historically passed through.

From the image you can see where the river currently is, and where it has historically passed through. Nice.