Spatial (CRS, coordinates, geometry)#

Note

Engine: OpenSWMM 6 — refactored.

solver.spatial exposes the geographic side of the model: the coordinate reference system, node/link/subcatchment/gage coordinates, link polyline vertices, and subcatchment polygons.

Reference: openswmm_spatial.h.


Quickstart#

from openswmm.engine import Solver

with Solver("model.inp") as s:
    # CRS — read or write.
    print(s.spatial.crs)
    s.spatial.crs = "EPSG:4326"

    # Per-object coords (int or str).
    x, y = s.spatial.node_coord("J1")
    s.spatial.set_node_coord("J1", x + 5.0, y)

    # Bulk arrays.
    coords = s.spatial.node_coords()        # shape (n_nodes, 2)
    s.spatial.set_node_coords(coords * 1.0)  # round-trip

    # Geometry — polyline + polygon (numpy arrays).
    verts = s.spatial.link_vertices("C1")    # (n, 2)
    poly = s.spatial.subcatchment_polygon("S1")

CRS#

Property / method

What it does

s.spatial.crs

str property. Reads/writes the CRS string (EPSG token, WKT, or proj string). Reading a model with no CRS raises CRSError.


Per-object coordinates#

All four families have a uniform shape: int | str object selectors, (x, y) tuples, plus explicit setters.

Method

Object selector

Returns / accepts

node_coord(node) / set_node_coord(node, x, y)

int | str

(x, y) tuple

link_coord(link) / set_link_coord(link, x, y)

int | str

(x, y) tuple

subcatchment_coord(sub) / set_subcatchment_coord(sub, x, y)

int | str

(x, y) tuple

gage_coord(gage) / set_gage_coord(gage, x, y)

int | str

(x, y) tuple


Bulk coordinate arrays#

For vectorised work, use the bulk node-coord pair:

coords = s.spatial.node_coords()       # np.ndarray, shape (n_nodes, 2)
coords += [0.0, 100.0]                  # shift north by 100 ft
s.spatial.set_node_coords(coords)

The C API doesn’t currently expose bulk equivalents for links, subcatchments, or gages — those go one at a time.


Polyline + polygon geometry#

verts = s.spatial.link_vertices("C1")       # (n, 2) float64
poly  = s.spatial.subcatchment_polygon("S1") # (n, 2) float64

# Replace.
s.spatial.set_link_vertices("C1", new_verts)
s.spatial.set_subcatchment_polygon("S1", new_poly)

Both arrays are column-stacked (x, y) pairs; reshape with NumPy as needed.


See also#