3

I've run into an issue with the Geopandas explode method. When I run the explode method, multi-polygons which originally had holes are filled inexplicably. I need to expolode the multi-polygons in a geodataframe which represent jurisdictional boundaries prior to running a spatial overlay process in which I hope to assign jurisdiction to polygons in another geodataframe.

Here is my code:

jurs_url = os.path.join(
    "https://",
    "services3.arcgis.com",
    "i2dkYWmb4wHvYPda",
    "arcgis",
    "rest",
    "services",
    "region_jurisdiction_clp",
    "FeatureServer",
    "0",
    "query?outFields=*&where=1%3D1&f=geojson",
)

jurs_gdf = gpd.read_file(jurs_url).to_crs("EPSG:26910")
jurs_explode_gdf = jurs_gdf.explode(index_parts=True)

Here is a visualization of the issue using a subset of the geodataframe:

Visualization of original gdf

jurs_gdf[jurs_gdf['jurname'] == 'Unincorporated Sonoma'].explore()

holes

Visualization of the exploded gdf

(
    jurs_gdf[jurs_gdf["jurname"] == "Unincorporated Sonoma"].explode(
        index_parts=True
    )
).explore()

enter image description here

I tried to set indexing parts to false and also attempted to ignore the index when I ran the explode method but this did not seem to make a difference. How can I avoid this unintended behavior when running the explode method?

1
  • It could be an issue with malformed geometries. Running is_valid returns a bunch of geometries that fail this test.
    – ako
    Mar 2, 2023 at 21:55

1 Answer 1

3

If geometries are checked and fixed beforehand, the explode method appears well-behaved. Shapely has a function for enforcing validity, addressing self-intersections and other infractions. Here's a working example:

from shapely.validation import explain_validity, make_valid

jurs_url = os.path.join(
    "https://",
    "services3.arcgis.com",
    "i2dkYWmb4wHvYPda",
    "arcgis",
    "rest",
    "services",
    "region_jurisdiction_clp",
    "FeatureServer",
    "0",
    "query?outFields=*&where=1%3D1&f=geojson",
)

juris_gdf = gpd.read_file(jurs_url).to_crs("EPSG:26910")

print("Before: Invalid geoms", juris_gdf[~juris_gdf.is_valid].shape[0])

print(juris_gdf.geometry.apply(explain_validity).value_counts())

juris_gdf['geometry_new'] = juris_gdf.geometry.apply(make_valid)
juris_gdf = juris_gdf.set_geometry('geometry_new')

print("After: Invalid geoms", juris_gdf[~juris_gdf.is_valid].shape[0])

jurs_explode_gdf = juris_gdf.explode(index_parts=True).reset_index().rename(
    columns={'level_0': 'orig_id', 'level_1': 'orig_id_component'})

(
    jurs_explode_gdf[jurs_explode_gdf["jurname"] == "Unincorporated Sonoma"]
).explore()

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.