Skip to content

assign_geo_identifiers raises RuntimeError: driverName computed but not passed to load_spatial_data #189

Description

@jinskeep-morpc

Summary

morpc.assign_geo_identifiers(points, ["county"]) (and ["tract"], ["zcta"], ["place"]) raises a bare RuntimeError on every call. It computes a driverName for the polygon source but never passes it to load_spatial_data(), which then cannot infer a driver for the .zip URL and raises.

Version: 0.6.2 (396e47c).

Reproduce

import morpc, geopandas as gpd
pts = gpd.GeoDataFrame({"id": [1]},
                       geometry=gpd.points_from_xy([-83.0007], [39.9612]), crs="EPSG:4326")
morpc.assign_geo_identifiers(pts, ["county"])
File ".../morpc/morpc.py", line 1778, in assign_geo_identifiers
    polys = load_spatial_data(sourcePath = filePath, layerName = layerName, verbose=False)
File ".../morpc/morpc.py", line 1455, in load_spatial_data
    raise RuntimeError
RuntimeError:

(preceded by: File extension is unsupported: .zip. It is possible to load zipped spatial data, but you must specify the driver name.)

Cause

In assign_geo_identifiers each supported geography sets a local driverName, e.g.

# morpc/morpc.py ~1730-1755
if(geography == "county"):
    filePath = "https://www2.census.gov/geo/tiger/TIGER2020PL/LAYER/COUNTY/2020/tl_2020_39_county20.zip"
    layerName = None
    driverName = "Census Shapefile"   # Custom driver name for load_spatial_data
    polyIdField = "GEOID20"

but the call at line 1778 drops it:

polys = load_spatial_data(sourcePath = filePath, layerName = layerName, verbose=False)
#                                                                       ^ no driverName=

so load_spatial_data falls into its driverName is None branch, sees .zip, and raise RuntimeError (line 1454-1455).

Two things need fixing:

  1. Line 1778 should pass driverName = driverName.

  2. load_spatial_data has no "Census Shapefile" branch (only GPKG / ESRI Shapefile / OpenFileGDB / SQLite, else generic gpd.read_file). So even once passed, "Census Shapefile" would land in the generic else. That path does happen to work:

    >>> gpd.read_file("https://www2.census.gov/geo/tiger/TIGER2020PL/LAYER/COUNTY/2020/tl_2020_39_county20.zip")
    # 88 rows, EPSG:4269, ~2s

    so either add an explicit "Census Shapefile" case (→ gpd.read_file(sourcePath, engine="pyogrio"), no layer=), or have the geographies pass a driver load_spatial_data already understands.

Also

assign_geo_identifiers renames with "id_{}".format(geography, polyIdField) — the second arg is unused (leftover {1}?), and the sjoin leaves an index_right column (only fid_* is dropped).

Workaround

Point-in-polygon against the TIGER shapefile directly:

counties = gpd.read_file(COUNTY_ZIP_URL)[["GEOID20", "geometry"]].to_crs(pts.crs)
pts.sjoin(counties, how="left", predicate="within")

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions