Below is an extended summary of this code. It explains how each function assists in rendering or transforming geospatial data—particularly SWMM or model elements—to a 2D image (e.g., for plotting or map-making). The code heavily depends on PIL (Pillow) for image manipulation and pandas for DataFrame handling.
Overview
These utility/helper functions are primarily about:
- Coordinate transformations (real-world to pixel space).
- Bounding box manipulations for clipping or placing circles/polygons on an image.
- Calculations like distances between points, midpoints, angles, and bounding boxes.
- Saving rendered images with optional resizing, plus an auto-open feature.
They complement other modules that do the actual drawing of SWMM objects (nodes, conduits, parcels) by giving the tools to convert geospatial or real-world coordinates to the pixel domain, ensuring everything lines up properly on a final image canvas.
Primary Functions
1. save_image(img, img_path, antialias=True, auto_open=False)
- Purpose: Saves a PIL
Image
object to disk. - Key Parameters:
img
: ThePIL.Image
object to save.img_path
: File path (including extension) for saving.antialias
(bool): IfTrue
, shrinks the image (50% thumbnail) using a high-quality resampling filter (LANCZOS).auto_open
(bool): IfTrue
, attempts to open the resulting file via the OS default program (os.startfile
on Windows).
- Usage Example:
save_image(my_image, "output.png", antialias=True, auto_open=True)
2. px_to_irl_coords(df, px_width=4096.0, bbox=None, shift_ratio=None)
- Purpose: Transforms a DataFrame’s
coords
column (which stores real-world or model coordinates) into pixel coordinates for drawing onto an image of widthpx_width
. - Parameters:
df
: A pandas DataFrame that must include acoords
column. Each row’scoords
is a list of(x, y)
tuples.px_width
: Target image width (in pixels).bbox
: Optional bounding box ([(xmin, ymin), (xmax, ymax)]
). If not provided, it’s computed from min and max of the coordinates.shift_ratio
: If provided, it forces a custom scale factor. Otherwise, it’s derived frompx_width / width_of_real_coords
.
- Returns:
- Modified
df
with a new column nameddraw_coords
storing scaled pixel coordinates. - The bounding box used (
bbox
). - Calculated image height in pixels.
- Calculated image width in pixels.
- The final
shift_ratio
.
- Modified
- Key Steps:
- Possibly clip the DataFrame rows to the bounding box (using
clip_to_box
). - Compute a scale factor if
shift_ratio
not specified. - For each row, shift & scale original coords from the real bounding box to pixel space.
- Possibly clip the DataFrame rows to the bounding box (using
3. circle_bbox(coordinates, radius=5)
- Purpose: Returns a PIL-friendly bounding box for an ellipse or circle.
- Parameter:
coordinates
:(x, y)
center point in pixel space.radius
: Circle radius in pixels.
- Returns: A 4-tuple
(x_min, y_min, x_max, y_max)
that PIL uses fordraw.ellipse(...)
.
4. clip_to_box(df, bbox)
- Purpose: Filters rows whose
coords
do not intersect the bounding box. - Implementation:
- For each row’s coordinate set, checks if any point is inside
bbox
. If none are inside, the row is excluded.
- For each row’s coordinate set, checks if any point is inside
- Used to ensure only features within the bounding box are drawn.
5. angle_bw_points(xy1, xy2)
- Purpose: Calculates an angle (in degrees) suitable for rotating text or shapes such that it aligns with a line from
xy1
toxy2
. - Implementation:
- Basic trigonometry with
atan(dx/dy)
, adjusting the angle to transform to typical image coordinates.
- Basic trigonometry with
- Used in label or street annotation to orient text along a line.
6. midpoint(xy1, xy2)
- Purpose: Returns the midpoint
(x, y)
between two coordinates(xy1, xy2)
. - Usage: Often used for placing text or icons along a segment.
7. point_in_box(bbox, point)
- Purpose: Quick test if
point
is within bounding boxbbox = [(xmin, ymin), (xmax, ymax)]
. - Returns:
True
if(x, y)
is inside or on edges of that box.
8. length_bw_coords(upstreamXY, downstreamXY)
- Purpose: Returns Euclidean distance (straight-line) between two points
(x1, y1)
and(x2, y2)
. - Used: Checking the length of lines, e.g., for deciding if some label or circle is too large for a short line segment.
9. rotate_coord_about_point(xy, radians, origin=(0, 0))
- Purpose: Rotates a coordinate
(xy)
around a specifiedorigin
by a given angle in radians. - Implementation:
adjusted_x = x - origin_x adjusted_y = y - origin_y # apply rotation qx = origin_x + cos_rad * adjusted_x + sin_rad * adjusted_y qy = origin_y - sin_rad * adjusted_x + cos_rad * adjusted_y
- Usage: Potentially used when rotating polygons, nodes, or text anchor points around a pivot.
Typical Workflow
- Load model or real-world coordinates into a DataFrame with a
coords
column. - Determine bounding box for the region of interest.
- Convert from real-world coordinates to pixel space with
px_to_irl_coords(...)
. - Initialize a PIL image (e.g.,
Image.new(...)
). - Draw shapes using the transformed
draw_coords
for each element. Possibly usecircle_bbox(...)
for nodes, lines for conduits, etc. - (Optional) Clip data to bounding box with
clip_to_box(...)
. - Save the resulting image with
save_image(...)
, specifying size or antialiasing settings.
Integration & Benefits
- Integration: These functions complement other modules that define color gradients or shapes for SWMM nodes/links.
- Scalability: By separating transformations (px_to_irl_coords) from actual drawing logic, the code remains modular—one part ensures correct coordinate mapping, the other draws specific objects.
- Automated: The bounding box logic and scale factor calculations streamline the process of generating consistent maps, ensuring that model elements fill the image neatly.
- Clarity: Reusable geometry functions (like midpoint, angle_bw_points, length_bw_coords) keep the code DRY and maintainable.
Conclusion
Overall, these are geometry and utility functions supporting 2D image creation from geospatial or SWMM-like data:
- Converts coordinate sets to pixel-based coordinates for rendering.
- Clips data to a bounding box so only relevant features are drawn.
- Enables easy circle bounding boxes and line geometry checks.
- Provides a standard method (
save_image
) to finalize and optionally open the resultant map.
Hence, they form the foundation for constructing dynamic or static visualizations of model networks, flood extents, or any data that can be mapped to x-y coordinates and displayed in a 2D image.
No comments:
Post a Comment