Skip to content

Manning's n Region Polygon Authoring

This workflow writes Manning's n calibration region polygons to the plain-text HEC-RAS geometry file with GeomLandCover.set_mannings_region_polygons() and checks the paired regional Manning's n table remains readable.

Python
from pathlib import Path
import logging
import shutil
import sys

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.patches import Patch

repo_root = (
    Path.cwd().resolve().parent
    if Path.cwd().resolve().name == "examples"
    else Path.cwd().resolve()
)
if str(repo_root) not in sys.path:
    sys.path.insert(0, str(repo_root))
logging.getLogger("numexpr").setLevel(logging.WARNING)
logging.getLogger("numexpr.utils").setLevel(logging.WARNING)

from ras_commander.RasExamples import RasExamples
from ras_commander.geom.GeomLandCover import GeomLandCover
from ras_commander.hdf.HdfLandCover import HdfLandCover
from ras_commander.hdf.HdfMesh import HdfMesh

logging.getLogger("ras_commander").setLevel(logging.WARNING)

work_dir = Path("working") / "219_mannings_region_polygon_authoring"
work_dir.mkdir(parents=True, exist_ok=True)

project_path = RasExamples.extract_project(
    "Muncie",
    output_path=work_dir,
    suffix="219_region_polygons",
)

source_geom = project_path / "Muncie.g04"
authoring_geom = project_path / "Muncie_region_polygon_authoring.g04"
shutil.copy2(source_geom, authoring_geom)

source_geom_hdf = project_path / "Muncie.g04.hdf"
regions = HdfLandCover.get_mannings_region_polygons(source_geom_hdf)
mesh_areas = HdfMesh.get_mesh_areas(source_geom_hdf)
flat_area = regions[regions["Name"].astype(str).str.strip() == "Flat Area"].copy()

assert len(flat_area) == 1, "Expected one Muncie 'Flat Area' calibration region"
assert not mesh_areas.empty, "Expected Muncie 2D flow area perimeter"
flat_area[["Name", "geometry"]]
Name geometry
0 Flat Area POLYGON ((407719.543 1803114.117, 407651.697 1...
Python
GeomLandCover.set_mannings_region_polygons(
    authoring_geom,
    flat_area[["Name", "geometry"]],
)

region_n = GeomLandCover.get_region_mannings_n(authoring_geom)
flat_area_n = region_n[region_n["Region Name"] == "Flat Area"].reset_index(drop=True)

assert not flat_area_n.empty, "Region n-value table was not preserved"
assert authoring_geom.with_suffix(".g04.bak").exists(), "Expected a geometry backup"

flat_area_n
Table Number Land Cover Name MainChannel Region Name
0 6 building 100.000 Flat Area
1 6 medium density residential 0.072 Flat Area
2 6 open space 0.036 Flat Area
3 6 park 0.054 Flat Area
4 6 trees 0.108 Flat Area
5 6 urban 0.090 Flat Area
Python
fig, ax = plt.subplots(figsize=(7.5, 6.5))

mesh_areas.boundary.plot(
    ax=ax,
    color="#5f6368",
    linewidth=1.3,
    linestyle="--",
    alpha=0.9,
)

flat_area.plot(
    ax=ax,
    facecolor="#9bd3c6",
    edgecolor="#005f73",
    linewidth=2.2,
    alpha=0.42,
)
flat_area.boundary.plot(ax=ax, color="#003f5c", linewidth=2.0)

centroid = flat_area.geometry.iloc[0].centroid
ax.scatter(
    [centroid.x],
    [centroid.y],
    color="#ee9b00",
    edgecolor="#3d2c00",
    s=65,
    zorder=5,
    label="Region centroid",
)
ax.annotate(
    "Flat Area",
    xy=(centroid.x, centroid.y),
    xytext=(18, 16),
    textcoords="offset points",
    fontsize=10,
    fontweight="bold",
    arrowprops={"arrowstyle": "->", "color": "#3d2c00", "lw": 1.2},
)
ax.annotate(
    "Grid N",
    xy=(0.94, 0.91),
    xytext=(0.94, 0.78),
    xycoords="axes fraction",
    textcoords="axes fraction",
    ha="center",
    va="center",
    fontsize=10,
    fontweight="bold",
    arrowprops={"arrowstyle": "-|>", "color": "black", "lw": 1.4},
)

legend_handles = [
    Line2D(
        [0],
        [0],
        color="#5f6368",
        linestyle="--",
        linewidth=1.4,
        label="2D flow area perimeter",
    ),
    Patch(
        facecolor="#9bd3c6",
        edgecolor="#005f73",
        alpha=0.42,
        label="Calibration region polygon",
    ),
    Line2D(
        [0],
        [0],
        marker="o",
        color="none",
        markerfacecolor="#ee9b00",
        markeredgecolor="#3d2c00",
        markersize=8,
        label="Region centroid",
    ),
]

ax.text(
    0.045,
    0.055,
    "Muncie example project\nGeometry: Muncie.g04",
    transform=ax.transAxes,
    fontsize=8.5,
    va="bottom",
    bbox={"boxstyle": "round,pad=0.22", "facecolor": "white", "edgecolor": "#8a8a8a", "alpha": 0.88},
)

mesh_bounds = mesh_areas.total_bounds
region_bounds = flat_area.total_bounds
x_span = region_bounds[2] - region_bounds[0]
y_span = region_bounds[3] - region_bounds[1]
ax.annotate(
    "2D Interior Area perimeter",
    xy=(region_bounds[2] + 0.14 * x_span, region_bounds[3] - 0.42 * y_span),
    xytext=(region_bounds[2] - 0.20 * x_span, region_bounds[3] + 0.13 * y_span),
    fontsize=9,
    color="#3c4043",
    arrowprops={"arrowstyle": "->", "color": "#5f6368", "lw": 1.0},
)

ax.set_xlim(region_bounds[0] - 0.18 * x_span, region_bounds[2] + 0.18 * x_span)
ax.set_ylim(region_bounds[1] - 0.18 * y_span, region_bounds[3] + 0.22 * y_span)

ax.set_title("Manning's n Calibration Region - Muncie Example Project")
ax.set_xlabel("Project X Coordinate (ft)")
ax.set_ylabel("Project Y Coordinate (ft)")
ax.set_aspect("equal", adjustable="box")
ax.ticklabel_format(style="plain", useOffset=False)
ax.grid(True, color="#c9c9c9", linewidth=0.45, alpha=0.35)
ax.legend(handles=legend_handles, loc="upper left", frameon=True)

plt.tight_layout()
plt.show()

png