Below is an extended summary of this code, detailing how it generates both static images and interactive web maps for SWMM model elements (nodes, conduits, parcels) and what each function contributes to that workflow.
Overview
This code comprises two primary functionalities:
draw_model
– Generates a static image (PNG) of a SWMM model’s geometry (nodes, links, optional parcels) with optional basemap integration.create_map
– Produces an interactive web map (HTML/GeoJSON) reflecting the model’s network, centering on the model’s bounding box or centroid.
By combining methods for coordinate transformation, PIL-based drawing, and HTML/JavaScript templating, the module allows users to visualize SWMM models in a flexible way—either as a static, annotated image or an interactive map in a browser.
1. draw_model
Function
Purpose
draw_model
orchestrates the creation of a PNG image representing SWMM model data, optionally including:
- Nodes: Drawn as circles using a separate
draw_node
utility. - Conduits (Links): Drawn as lines with
draw_conduit
. - Parcels: (Optional) drawn as polygons (e.g., for flood-risk areas).
- Basemap layers: If configured, it calls
_draw_basemap
to overlay additional shapefile-based features (streets, polygons).
Key Arguments
model
: Aswmmio.Model
object (optional). If provided, the code automatically retrievesmodel.nodes()
andmodel.links()
.nodes
,conduits
: Pandas DataFrames containing geometry columns (e.g.,coords
). These can be passed directly if amodel
object is not used.parcels
: An optional DataFrame for polygon data. Each row needs adraw_coords
or coordinate info.title
andannotation
: Strings to annotate the final image with a title (top-left) and extra details (bottom-left).file_path
: If provided, the final PNG is saved to disk; if omitted, the PILImage
object is returned.bbox
: Custom bounding box for clipping. If omitted, the bounding box is derived from the data extents.px_width
: Desired output image width in pixels (default 2048). Internally, the function doubles this for anti-aliasing.
Workflow
-
Data Gathering:
- If
model
is provided, callsmodel.nodes()
andmodel.links()
for geometry. - Otherwise, uses the
nodes
andconduits
DataFrames directly.
- If
-
Coordinate Transform:
- Calls
px_to_irl_coords
to convert real-world or model coordinates into pixel coordinates. - Yields a bounding box and scale ratio for consistent rendering.
- Calls
-
Creating the Image:
- Makes a PIL
Image
of the appropriate dimension and background color (white). - Obtains a
Draw
handle (draw = ImageDraw.Draw(img)
).
- Makes a PIL
-
Basemap Layers (optional):
- If
config.include_basemap
isTrue
, calls_draw_basemap
to load shapefiles fromconfig.basemap_options
and draw them in the background (e.g., roads, property boundaries).
- If
-
Drawing:
- Parcels: If provided, draws each polygon using the
draw_coords
plus afill
color fromr.draw_color
. - Conduits: Each row is passed to
draw_conduit(row, draw)
. - Nodes: Each row is passed to
draw_node(row, draw)
.
- Parcels: If provided, draws each polygon using the
-
Annotation:
- If
title
is given, callsannotate_title
. - If
annotation
is given, callsannotate_details
. - Always calls
annotate_timestamp
to add a timestamp in the top-right corner.
- If
-
Saving or Returning the Image:
- If
file_path
is specified, callssave_image(img, file_path)
(which can do an antialias thumbnail and optionally open the file). - Otherwise, returns the
img
object directly—useful in Jupyter notebooks or for further processing in memory.
- If
Typical Use
my_image = draw_model(
model=my_swmm_model,
title="Example Model",
annotation="Beta version",
file_path="example_model.png",
bbox=((2691647, 221073), (2702592, 227171)),
px_width=2048
)
2. create_map
Function
Purpose
Creates an interactive web-based map (HTML + GeoJSON) displaying the SWMM model’s geometry. This approach uses a map template (e.g., from BETTER_BASEMAP_PATH
) where placeholders are replaced with:
- The model’s centroid and bounding box, to position and bound the map.
- The model’s links.geojson and nodes.geojson data (assuming
model
has.geojson
properties).
Arguments
model
: Aswmmio.Model
object that presumably includes.nodes.geojson
and.links.geojson
.filename
: Destination HTML file path. If not provided, the function returns the generated HTML as a string.basemap
: A path to an HTML template with placeholders.
Workflow
- CRS Check: If
model.crs
is known, tries to transform the model coordinates toEPSG:4326
for web mapping. - Compute centroid and bounding box from the model’s
inp.coordinates
(viacentroid_and_bbox_from_coords
). - Read the basemap template file line by line.
- Insert relevant data:
conduits = <geojson dumps of model.links.geojson>
nodes = <geojson dumps of model.nodes.geojson>
map center
from the centroid[lng, lat]
.fitBounds
calls from the bounding box.
- Write the final HTML to the
filename
.- If
filename
isNone
, the result is returned as a string.
- If
Typical Use
html_content = create_map(model=my_swmm_model, filename=None)
# This returns the HTML as a string, which can be displayed in a Jupyter notebook via IFrame or written to file manually
Supporting Elements
_draw_basemap(draw, img, bbox, px_width, shift_ratio)
- Called internally by
draw_model
ifconfig.include_basemap
isTrue
. - Iterates over features in
config.basemap_options['features']
, reads shapefiles, transforms them to pixel coords, and draws lines or polygons. - If columns like
ST_NAME
exist, it callsannotate_streets
to place text.
import
statements
- PIL (
Image, ImageDraw
) for static image creation. - swmmio.graphics.config and swmmio.defs.constants for color definitions and user preferences (like
white
background). px_to_irl_coords
,save_image
fromswmmio.graphics.utils
: handle geometry transformations and final image saving.draw_node
,draw_conduit
fromswmmio.graphics.drawing
: actual shape-drawing functions for SWMM nodes/links.spatial
modules for shapefile reading (spatial.read_shapefile
) and coordinate conversions.centroid_and_bbox_from_coords
for bounding box logic.
Why These Functions Are Useful
-
Versatile Visualization:
draw_model
suits quick static diagrams for reports, screenshots, or docs.create_map
suits interactive exploration—useful for large networks or checking node/link attributes in detail.
-
Easy Integration:
- Because the code references typical SWMM data structures (from
model.nodes()
,model.links()
), it plugs directly into swmmio’s data pipeline.
- Because the code references typical SWMM data structures (from
-
Customizable:
- By adjusting parameters like
px_width
,bbox
, or passing in your own DataFrames, you can refine your map’s resolution and coverage. - The code can also incorporate external shapefiles for background context (streets, administrative boundaries) via
_draw_basemap
.
- By adjusting parameters like
Example End-to-End Usage
- Create/Load a SWMM Model:
from swmmio import Model my_model = Model("example_model.inp")
- Generate a Static PNG:
draw_model( model=my_model, title="My SWMM Model Visualization", annotation="Preliminary results", file_path="my_model_viz.png", px_width=2048 )
- Generate an Interactive Map:
map_html = create_map(my_model, filename="my_model_map.html", auto_open=True) # This writes an HTML file that references the model's geojson data. # If auto_open=True is implemented, it might automatically open in a web browser (depending on OS).
Conclusion
Through draw_model
and create_map
, this code seamlessly visualizes SWMM networks in static or interactive formats:
draw_model
: Renders a color-coded, labeled 2D PNG from a SWMM model or user-supplied DataFrames.create_map
: Creates a Leaflet-style HTML page embedding the model as geojson for dynamic panning/zooming.
These functionalities enhance the analysis workflow by allowing engineers, researchers, and stakeholders to quickly see how a model’s nodes, links, or external shapefile-based layers align, and to share results in either a simple image or an interactive, browsable map.
No comments:
Post a Comment