agentsclimarketplace

Run2 multipart geometry handling

Skill cxcscmu/SkillLearnBench/skills/b2-self-feedback-claude-haiku-4-5/earthquake-plate-calculation/run2_multipart-geometry-handling

Work with MultiPolygon and MultiLineString geometries from real plate boundary datasets.From its SKILL.md

Install
npx -y skills add cxcscmu/SkillLearnBench --skill run2_multipart-geometry-handling

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

3.7 KB, 835 tokens by cl100k_base, as published. Nobody here has run it

MultiPart Geometry Handling

Installation

pip install geopandas shapely pandas

Overview

Real-world plate boundary data consists of disconnected LineString segments (MultiLineString) that need special handling for distance calculations. Similarly, plates can be represented as MultiPolygons.

Understanding MultiPart Geometries

MultiLineString (Plate Boundaries)

from shapely.geometry import MultiLineString, LineString

# Boundaries may be stored as multiple LineString objects
boundary_geom = boundaries.geometry.unary_union
print(f"Type: {type(boundary_geom)}")  # MultiLineString

# Access individual parts
if isinstance(boundary_geom, MultiLineString):
    for i, line in enumerate(boundary_geom.geoms):
        print(f"Segment {i}: {len(line.coords)} points")

MultiPolygon (Plate Regions)

# Pacific plate might consist of multiple disconnected polygons
pacific_geom = pacific_plates.geometry.unary_union
print(f"Type: {type(pacific_geom)}")  # MultiPolygon

# Access individual polygons
if isinstance(pacific_geom, MultiPolygon):
    for i, poly in enumerate(pacific_geom.geoms):
        print(f"Polygon {i}: {len(poly.exterior.coords)} boundary points")

Distance Calculation with MultiLineString

The Shapely .distance() method automatically handles MultiLineString:

  • Computes distance to nearest segment
  • Works efficiently with large multipart geometries
# This works correctly even if boundary_geom is MultiLineString
distances = points_gdf.geometry.distance(boundary_geom)

# Find minimum distance for each point
min_distance = distances.min()  # Distance to nearest boundary segment

Point-in-MultiPolygon

GeoPandas' .within() method also handles MultiPolygon correctly:

# Find points within any part of multipolygon
within_mask = earthquakes.geometry.within(pacific_geom)
earthquakes_within = earthquakes[within_mask]

# Result: includes points in any of the disconnected polygon parts

Validation: Verify Coverage

import geopandas as gpd

# Sanity check: are boundaries actually on plate edges?
boundaries_gdf = boundaries.to_crs('EPSG:3857')
plate_gdf = pacific_plates.to_crs('EPSG:3857')

# Sample some boundary points
boundary_geom = boundaries_gdf.geometry.unary_union
plate_geom = plate_gdf.geometry.unary_union

# Get points along boundary
def sample_points_on_line(line, num_points=100):
    distances = [i/num_points for i in range(num_points)]
    return [line.interpolate(d, normalized=True) for d in distances]

sample_pts = sample_points_on_line(boundary_geom, 100)

# Verify most boundary points are near plate edge
# (some may be outside, some inside - this is expected for plate boundaries)

Common Operations

Flatten MultiPart to Single Collection

# Get all individual parts
all_parts = list(boundary_geom.geoms)  # For MultiLineString
print(f"Total boundary segments: {len(all_parts)}")

# Recreate as single geometry (useful for visualization)
from shapely.geometry import LineString
if len(all_parts) > 1:
    flat_line = LineString([pt for line in all_parts for pt in line.coords])

Measure Boundary Lengths

# Total length of all boundary segments
if hasattr(boundary_geom, 'length'):
    total_length = boundary_geom.length
    print(f"Total boundary length: {total_length / 1000:.0f} km")

Important Notes

  • .unary_union automatically handles combining multiple geometries
  • Distance calculations with MultiLineString return distance to nearest segment
  • Point-in-polygon tests work correctly with MultiPolygon
  • Shapely 2.0+ has improved performance for multipart operations

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.