# Install devtools if not already installed
if (!require("devtools")) install.packages("devtools")
# Install fluvgeo from GitHub
devtools::install_github("FluvialGeomorph/fluvgeo")22 fluvgeo R Package
📐 Theory
Overview
The fluvgeo package provides a comprehensive suite of tools for fluvial geomorphology analysis in R. It is the core package of the FluvialGeomorph toolbox, providing functions for processing, analyzing, and visualizing stream channel geometry, planform characteristics, and longitudinal profiles.
- Repository: https://github.com/FluvialGeomorph/fluvgeo
- License: CC0 1.0 Universal
- Language: R
- Dependencies: R (≥ 3.5.0), sf, dplyr, ggplot2, raster
Installation
From GitHub
Load Package
library(fluvgeo)
library(sf)
library(dplyr)
library(ggplot2)Key Features
The fluvgeo package provides functionality for:
- Cross Section Analysis: Import, process, and analyze cross section survey data
- Longitudinal Profile Analysis: Extract and analyze stream profiles from DEMs and survey data
- Planform Analysis: Calculate sinuosity, meander geometry, and channel migration
- Hydraulic Calculations: Compute hydraulic parameters from channel geometry
- Visualization: Create publication-quality plots and maps
- Data Management: Import/export tools for common survey data formats
Package Workflow
flowchart TB
Start([Start fluvgeo Analysis])
subgraph Import["Data Import"]
ImportDEM["Import DEM<br/>(import_dem)"]
ImportXS["Import Cross Sections<br/>(xs_import)"]
ImportProfile["Import Profile<br/>(profile_import)"]
ImportFlowline["Import Flowline<br/>(import_flowline)"]
end
subgraph Process["Data Processing"]
ProcessXS["Process XS Geometry<br/>(xs_process)"]
ProcessProfile["Process Profile<br/>(profile_process)"]
ExtractFlowline["Extract Flowline<br/>(extract_flowline)"]
DelineateWS["Delineate Watershed<br/>(delineate_watershed)"]
end
subgraph Analyze["Analysis"]
XSMetrics["XS Metrics<br/>(xs_metrics)"]
Bankfull["Identify Bankfull<br/>(xs_bankfull)"]
Dimensions["Calculate Dimensions<br/>(xs_dimensions)"]
Sinuosity["Calculate Sinuosity<br/>(sinuosity)"]
Slope["Calculate Slope<br/>(profile_slope)"]
Radius["Radius of Curvature<br/>(radius_curvature)"]
end
subgraph Visualize["Visualization"]
PlotXS["Plot Cross Sections<br/>(plot_xs)"]
PlotProfile["Plot Profile<br/>(plot_profile)"]
PlotPlanform["Plot Planform<br/>(plot_planform)"]
CreateMaps["Create Maps<br/>(create_maps)"]
end
Export["Export Results<br/>(export_data)"]
End([Complete])
Start --> Import
Import --> Process
Process --> Analyze
Analyze --> Visualize
Visualize --> Export
Export --> End
ImportXS --> ProcessXS
ImportProfile --> ProcessProfile
ImportDEM --> ExtractFlowline
ImportDEM --> DelineateWS
ProcessXS --> XSMetrics
XSMetrics --> Bankfull
Bankfull --> Dimensions
ProcessProfile --> Slope
ExtractFlowline --> Sinuosity
ExtractFlowline --> Radius
Dimensions --> PlotXS
Slope --> PlotProfile
Sinuosity --> PlotPlanform
PlotXS --> CreateMaps
PlotProfile --> CreateMaps
PlotPlanform --> CreateMaps
style Start fill:#90EE90
style End fill:#90EE90
style Import fill:#E8F4F8,stroke:#2E86AB,stroke-width:2px
style Process fill:#FFF4E6,stroke:#F77F00,stroke-width:2px
style Analyze fill:#E8F5E9,stroke:#06A77D,stroke-width:2px
style Visualize fill:#FFF9C4,stroke:#F9C74F,stroke-width:2px
Main Functions
Cross Section Analysis
Import Cross Sections
Import cross section survey data from various formats.
# Import cross section data from CSV
xs_data <- xs_import(
path = "data/cross_sections.csv",
format = "csv",
crs = 26916 # UTM Zone 16N
)
# Import from shapefile
xs_data <- xs_import(
path = "data/cross_sections.shp",
format = "shapefile"
)
# Import from total station data
xs_data <- xs_import(
path = "data/survey_data.txt",
format = "total_station",
station_col = "Station",
elevation_col = "Elevation"
)Parameters:
path: File path to cross section dataformat: Data format (“csv”, “shapefile”, “total_station”, “excel”)crs: Coordinate reference system (EPSG code)station_col: Column name for station valueselevation_col: Column name for elevation values
Returns: An sf object containing cross section geometry
Process Cross Sections
Process and clean cross section geometry data.
# Process cross section geometry
xs_processed <- xs_process(
xs_data = xs_data,
smooth = TRUE,
smooth_window = 5,
remove_outliers = TRUE,
outlier_threshold = 3
)
# Interpolate missing stations
xs_interpolated <- xs_interpolate(
xs_data = xs_processed,
interval = 0.5 # meters
)Parameters:
xs_data: Cross section data objectsmooth: Apply smoothing to elevation datasmooth_window: Window size for moving averageremove_outliers: Remove elevation outliersoutlier_threshold: Standard deviations for outlier detection
Calculate XS Metrics
Calculate geometric metrics for cross sections.
# Calculate cross section metrics
xs_metrics <- xs_metrics(
xs_data = xs_processed,
bankfull_elevation = NULL, # Auto-detect or specify
method = "geometry" # or "vegetation", "field_indicators"
)
# View metrics
print(xs_metrics)Calculated Metrics:
- Cross-sectional area
- Wetted perimeter
- Hydraulic radius
- Top width
- Maximum depth
- Mean depth
- Width/depth ratio
Identify Bankfull
Identify bankfull stage using multiple methods.
# Identify bankfull using geometric method
bankfull_geom <- xs_bankfull(
xs_data = xs_processed,
method = "geometry",
plot = TRUE
)
# Identify bankfull using maximum width/depth ratio
bankfull_wd <- xs_bankfull(
xs_data = xs_processed,
method = "width_depth_ratio",
plot = TRUE
)
# Identify bankfull using field indicators
bankfull_field <- xs_bankfull(
xs_data = xs_processed,
method = "field_indicators",
indicators = c("top_of_bank", "vegetation_change", "bench")
)Methods:
geometry: Geometric inflection pointswidth_depth_ratio: Maximum width/depth ratiofield_indicators: Field-identified indicatorshydraulic: Hydraulic geometry relationships
Calculate Dimensions
Calculate bankfull channel dimensions.
# Calculate bankfull dimensions
dimensions <- xs_dimensions(
xs_data = xs_processed,
bankfull_elevation = bankfull_geom$elevation,
reach_name = "Reach 1"
)
# View dimensions
print(dimensions)Calculated Dimensions:
- Bankfull width (ft or m)
- Bankfull mean depth (ft or m)
- Bankfull maximum depth (ft or m)
- Bankfull cross-sectional area (ft² or m²)
- Width/depth ratio
- Hydraulic radius (ft or m)
Longitudinal Profile Analysis
Import Profile
Import longitudinal profile data.
# Import profile from survey data
profile_data <- profile_import(
path = "data/profile.csv",
station_col = "Station",
elevation_col = "Elevation",
crs = 26916
)
# Extract profile from DEM
profile_dem <- profile_extract_dem(
dem = dem_raster,
flowline = flowline_sf,
interval = 10 # meters
)Calculate Slope
Calculate reach and local slopes.
# Calculate reach slope
reach_slope <- profile_slope(
profile_data = profile_data,
method = "reach",
start_station = 0,
end_station = 1000
)
# Calculate local slopes
local_slopes <- profile_slope(
profile_data = profile_data,
method = "local",
window = 50 # meters
)
# Calculate water surface slope
ws_slope <- profile_slope(
profile_data = profile_data,
method = "water_surface",
flow_depth = 2.5 # meters
)Methods:
reach: Overall reach slopelocal: Moving window local slopeswater_surface: Water surface slope at specified depthenergy: Energy slope
Identify Features
Identify pools, riffles, and other features.
# Identify pool-riffle sequence
features <- profile_features(
profile_data = profile_data,
method = "residual_depth",
threshold = 0.5 # meters
)
# Calculate pool-riffle spacing
spacing <- pool_riffle_spacing(
features = features,
bankfull_width = 15 # meters
)
# Identify knickpoints
knickpoints <- identify_knickpoints(
profile_data = profile_data,
threshold = 0.02, # slope change threshold
min_length = 20 # minimum knickpoint length (m)
)Planform Analysis
Calculate Sinuosity
Calculate channel sinuosity.
# Calculate reach sinuosity
sinuosity_reach <- sinuosity(
flowline = flowline_sf,
method = "reach",
valley_line = valley_centerline_sf
)
# Calculate local sinuosity
sinuosity_local <- sinuosity(
flowline = flowline_sf,
method = "local",
window = 500 # meters
)
# Results
print(paste("Reach Sinuosity:", round(sinuosity_reach, 3)))Sinuosity Classification:
- < 1.05: Straight
- 1.05 - 1.25: Sinuous
- 1.25 - 1.50: Meandering
1.50: Highly meandering
Meander Geometry
Analyze meander geometry and characteristics.
# Identify meander bends
meanders <- identify_meanders(
flowline = flowline_sf,
method = "inflection_points",
min_amplitude = 10 # meters
)
# Calculate meander wavelength
wavelength <- meander_wavelength(
meanders = meanders,
method = "average"
)
# Calculate meander amplitude
amplitude <- meander_amplitude(
meanders = meanders,
valley_line = valley_centerline_sf
)
# Calculate meander belt width
belt_width <- meander_belt_width(
flowline = flowline_sf,
meanders = meanders,
method = "envelope"
)Meander Metrics:
- Wavelength: Distance between successive meander bends
- Amplitude: Maximum lateral extent of meander
- Belt width: Width of meander belt
- Radius of curvature: Bend radius
Radius of Curvature
Calculate radius of curvature along the channel.
# Calculate radius of curvature
curvature <- radius_curvature(
flowline = flowline_sf,
method = "three_point",
window = 3 # number of points
)
# Classify bend severity
bend_class <- classify_bends(
curvature = curvature,
bankfull_width = 15 # meters
)
# Plot curvature
plot_curvature(
flowline = flowline_sf,
curvature = curvature,
color_by = "radius"
)Bend Classification (Rc/W ratio):
10: Gentle bend
- 5 - 10: Moderate bend
- 2 - 5: Sharp bend
- < 2: Very sharp bend
Watershed Analysis
Delineate Watershed
Delineate watershed from DEM.
# Delineate watershed from pour point
watershed <- delineate_watershed(
dem = dem_raster,
pour_point = outlet_point_sf,
method = "d8" # or "dinf"
)
# Calculate drainage area
drainage_area <- calculate_drainage_area(
watershed = watershed,
units = "km2" # or "mi2", "acres"
)
# Extract watershed characteristics
ws_chars <- watershed_characteristics(
watershed = watershed,
dem = dem_raster,
include = c("area", "perimeter", "relief", "slope")
)Extract Flowline
Extract stream flowline from DEM.
# Extract flowline from DEM
flowline <- extract_flowline(
dem = dem_raster,
method = "d8",
threshold = 1000, # flow accumulation threshold
smooth = TRUE
)
# Smooth flowline
flowline_smooth <- smooth_flowline(
flowline = flowline,
method = "spline",
tolerance = 5 # meters
)
# Calculate flowline length
length <- calculate_length(
flowline = flowline_smooth,
units = "km" # or "mi", "m", "ft"
)Hydraulic Calculations
Manning’s Equation
Calculate flow velocity and discharge using Manning’s equation.
# Calculate velocity
velocity <- mannings_velocity(
hydraulic_radius = 1.5, # meters
slope = 0.002, # m/m
mannings_n = 0.035
)
# Calculate discharge
discharge <- mannings_discharge(
area = 25, # m²
hydraulic_radius = 1.5, # meters
slope = 0.002, # m/m
mannings_n = 0.035
)
# Estimate Manning's n
mannings_n <- estimate_mannings_n(
bed_material = "gravel",
vegetation = "moderate",
channel_irregularity = "minor",
method = "cowan"
)Hydraulic Geometry
Calculate hydraulic geometry parameters.
# Calculate hydraulic radius
hyd_radius <- hydraulic_radius(
area = 25, # m²
wetted_perimeter = 18 # m
)
# Calculate wetted perimeter
wetted_perim <- wetted_perimeter(
xs_data = xs_processed,
water_surface_elevation = 100.5
)
# Calculate flow area
flow_area <- calculate_flow_area(
xs_data = xs_processed,
water_surface_elevation = 100.5
)Visualization Functions
Plot Cross Sections
# Basic cross section plot
plot_xs(
xs_data = xs_processed,
xs_id = "XS-1",
bankfull_elevation = bankfull_geom$elevation,
title = "Cross Section XS-1"
)
# Multiple cross sections
plot_xs_multiple(
xs_data = xs_processed,
xs_ids = c("XS-1", "XS-2", "XS-3"),
layout = "grid",
ncol = 2
)
# Cross section with dimensions
plot_xs_dimensions(
xs_data = xs_processed,
xs_id = "XS-1",
dimensions = dimensions,
show_labels = TRUE
)Plot Longitudinal Profile
# Basic profile plot
plot_profile(
profile_data = profile_data,
title = "Longitudinal Profile",
show_slope = TRUE
)
# Profile with features
plot_profile_features(
profile_data = profile_data,
features = features,
color_by = "feature_type"
)
# Profile with cross sections
plot_profile_xs(
profile_data = profile_data,
xs_locations = xs_stations,
xs_data = xs_processed
)Plot Planform
# Basic planform plot
plot_planform(
flowline = flowline_sf,
watershed = watershed,
basemap = TRUE
)
# Planform with meanders
plot_planform_meanders(
flowline = flowline_sf,
meanders = meanders,
color_by = "wavelength"
)
# Planform with curvature
plot_planform_curvature(
flowline = flowline_sf,
curvature = curvature,
color_palette = "viridis"
)Create Maps
# Create assessment map
assessment_map <- create_map(
flowline = flowline_sf,
watershed = watershed,
xs_locations = xs_data,
features = features,
basemap = "terrain",
scale_bar = TRUE,
north_arrow = TRUE
)
# Export map
export_map(
map = assessment_map,
filename = "assessment_map.png",
width = 11,
height = 8.5,
dpi = 300
)Data Import/Export
Import Functions
# Import from various formats
data_csv <- import_data(
path = "data/survey.csv",
format = "csv"
)
data_shp <- import_data(
path = "data/features.shp",
format = "shapefile"
)
data_excel <- import_data(
path = "data/measurements.xlsx",
format = "excel",
sheet = "Cross Sections"
)
# Import DEM
dem <- import_dem(
path = "data/dem.tif",
crs = 26916
)Export Functions
# Export to CSV
export_data(
data = dimensions,
path = "output/dimensions.csv",
format = "csv"
)
# Export to shapefile
export_data(
data = flowline_sf,
path = "output/flowline.shp",
format = "shapefile"
)
# Export to GeoPackage
export_data(
data = xs_data,
path = "output/cross_sections.gpkg",
format = "gpkg",
layer_name = "cross_sections"
)
# Export summary report
export_report(
data = list(
dimensions = dimensions,
profile = profile_data,
sinuosity = sinuosity_reach
),
path = "output/summary_report.html",
format = "html",
template = "standard"
)Example Workflow
Here’s a complete example workflow using fluvgeo:
library(fluvgeo)
library(sf)
library(dplyr)
# 1. Import data
dem <- import_dem("data/dem.tif", crs = 26916)
xs_data <- xs_import("data/cross_sections.csv", format = "csv", crs = 26916)
# 2. Extract flowline
flowline <- extract_flowline(
dem = dem,
method = "d8",
threshold = 1000,
smooth = TRUE
)
# 3. Delineate watershed
watershed <- delineate_watershed(
dem = dem,
pour_point = outlet_point,
method = "d8"
)
# 4. Process cross sections
xs_processed <- xs_process(
xs_data = xs_data,
smooth = TRUE,
remove_outliers = TRUE
)
# 5. Identify bankfull
bankfull <- xs_bankfull(
xs_data = xs_processed,
method = "geometry",
plot = TRUE
)
# 6. Calculate dimensions
dimensions <- xs_dimensions(
xs_data = xs_processed,
bankfull_elevation = bankfull$elevation
)
# 7. Extract and analyze profile
profile <- profile_extract_dem(
dem = dem,
flowline = flowline,
interval = 10
)
slope <- profile_slope(
profile_data = profile,
method = "reach"
)
# 8. Calculate planform metrics
sinuosity_value <- sinuosity(
flowline = flowline,
method = "reach"
)
meanders <- identify_meanders(
flowline = flowline,
method = "inflection_points"
)
# 9. Create visualizations
plot_xs(xs_data = xs_processed, xs_id = "XS-1")
plot_profile(profile_data = profile)
plot_planform(flowline = flowline, watershed = watershed)
# 10. Export results
export_data(dimensions, "output/dimensions.csv")
export_data(flowline, "output/flowline.shp")
# 11. Generate report
create_summary_report(
xs_data = xs_processed,
dimensions = dimensions,
profile = profile,
sinuosity = sinuosity_value,
output_file = "output/analysis_report.html"
)Function Reference
Cross Section Functions
| Function | Description |
|---|---|
xs_import() |
Import cross section data |
xs_process() |
Process and clean XS geometry |
xs_interpolate() |
Interpolate XS stations |
xs_metrics() |
Calculate XS geometric metrics |
xs_bankfull() |
Identify bankfull stage |
xs_dimensions() |
Calculate bankfull dimensions |
plot_xs() |
Plot cross section |
plot_xs_multiple() |
Plot multiple cross sections |
Profile Functions
| Function | Description |
|---|---|
profile_import() |
Import profile data |
profile_extract_dem() |
Extract profile from DEM |
profile_process() |
Process profile data |
profile_slope() |
Calculate slope |
profile_features() |
Identify pools and riffles |
pool_riffle_spacing() |
Calculate pool-riffle spacing |
identify_knickpoints() |
Identify knickpoints |
plot_profile() |
Plot longitudinal profile |
Planform Functions
| Function | Description |
|---|---|
sinuosity() |
Calculate sinuosity |
identify_meanders() |
Identify meander bends |
meander_wavelength() |
Calculate wavelength |
meander_amplitude() |
Calculate amplitude |
meander_belt_width() |
Calculate belt width |
radius_curvature() |
Calculate radius of curvature |
classify_bends() |
Classify bend severity |
plot_planform() |
Plot planform map |
Watershed Functions
| Function | Description |
|---|---|
delineate_watershed() |
Delineate watershed |
calculate_drainage_area() |
Calculate drainage area |
watershed_characteristics() |
Extract watershed characteristics |
extract_flowline() |
Extract stream flowline |
smooth_flowline() |
Smooth flowline geometry |
Hydraulic Functions
| Function | Description |
|---|---|
mannings_velocity() |
Calculate velocity (Manning’s) |
mannings_discharge() |
Calculate discharge (Manning’s) |
estimate_mannings_n() |
Estimate Manning’s n |
hydraulic_radius() |
Calculate hydraulic radius |
wetted_perimeter() |
Calculate wetted perimeter |
calculate_flow_area() |
Calculate flow area |
Utility Functions
| Function | Description |
|---|---|
import_data() |
Import data from various formats |
export_data() |
Export data to various formats |
import_dem() |
Import DEM raster |
create_map() |
Create assessment map |
export_map() |
Export map to file |
create_summary_report() |
Generate summary report |
Best Practices
Data Quality
- Survey Data
- Use consistent coordinate systems
- Check for survey errors and outliers
- Document survey methods and equipment
- Include metadata with all datasets
- Cross Sections
- Survey perpendicular to flow
- Extend beyond bankfull on both sides
- Include floodplain features
- Mark bankfull indicators in field
- Longitudinal Profiles
- Use consistent datum
- Include sufficient upstream/downstream extent
- Document water surface elevations
- Note grade control features
Analysis Workflow
- Data Preparation
- Import and organize all data
- Check coordinate systems
- Remove obvious errors
- Document data sources
- Quality Control
- Visual inspection of all data
- Check for outliers
- Validate calculations
- Compare with field observations
- Analysis
- Use multiple methods when available
- Document assumptions
- Calculate uncertainty
- Compare with regional data
- Visualization
- Create clear, labeled plots
- Use consistent scales and units
- Include legends and annotations
- Export at appropriate resolution
- Documentation
- Record all processing steps
- Document function parameters
- Save intermediate results
- Create reproducible workflows
Troubleshooting
Common Issues
Problem: Data doesn’t align or appears in wrong location
Solution:
# Check CRS
st_crs(xs_data)
# Transform to correct CRS
xs_data <- st_transform(xs_data, crs = 26916)Problem: Automatic bankfull detection fails
Solution:
# Manually specify bankfull elevation
bankfull_manual <- xs_bankfull(
xs_data = xs_processed,
method = "manual",
elevation = 100.5
)
# Or use field indicators
bankfull_field <- xs_bankfull(
xs_data = xs_processed,
method = "field_indicators",
indicators = field_markers
)Problem: Extracted features don’t match field observations
Solution:
# Use higher resolution DEM
# Supplement with survey data
# Adjust extraction parameters
flowline <- extract_flowline(
dem = dem_high_res,
threshold = 500, # Lower threshold
smooth = TRUE,
smooth_factor = 0.5 # Less smoothing
)Additional Resources
Documentation
Support
- Issues - Report bugs or request features
- Discussions - Ask questions and share ideas
Citation
If you use fluvgeo in your research, please cite:
FluvialGeomorph Team (2024). fluvgeo: Fluvial Geomorphology Analysis Tools.
R package version X.X.X. https://github.com/FluvialGeomorph/fluvgeo
License
This package is released under the CC0 1.0 Universal license. You are free to use, modify, and distribute this software for any purpose.
Last updated: 2026-07-20