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:
-
Line 1778 should pass driverName = driverName.
-
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")
Summary
morpc.assign_geo_identifiers(points, ["county"])(and["tract"],["zcta"],["place"]) raises a bareRuntimeErroron every call. It computes adriverNamefor the polygon source but never passes it toload_spatial_data(), which then cannot infer a driver for the.zipURL and raises.Version: 0.6.2 (
396e47c).Reproduce
(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_identifierseach supported geography sets a localdriverName, e.g.but the call at line 1778 drops it:
so
load_spatial_datafalls into itsdriverName is Nonebranch, sees.zip, andraise RuntimeError(line 1454-1455).Two things need fixing:
Line 1778 should pass
driverName = driverName.load_spatial_datahas no"Census Shapefile"branch (onlyGPKG/ESRI Shapefile/OpenFileGDB/SQLite, else genericgpd.read_file). So even once passed,"Census Shapefile"would land in the genericelse. That path does happen to work:so either add an explicit
"Census Shapefile"case (→gpd.read_file(sourcePath, engine="pyogrio"), nolayer=), or have the geographies pass a driverload_spatial_dataalready understands.Also
assign_geo_identifiersrenames with"id_{}".format(geography, polyIdField)— the second arg is unused (leftover{1}?), and the sjoin leaves anindex_rightcolumn (onlyfid_*is dropped).Workaround
Point-in-polygon against the TIGER shapefile directly: