{"record":{"id":"1de5d2cfad215952","repo":"a-b-street/abstreet","slug":"unexpected-geometry-type-for","errorCode":null,"errorMessage":"Unexpected geometry type for {:?}","messagePattern":"Unexpected geometry type for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"popgetter/src/lib.rs","lineNumber":46,"sourceCode":"}\n\n/// Clips existing TopoJSON files to the given boundary. All polygons are in WGS84.\npub fn clip_zones(\n    topojson_path: &str,\n    boundary: geo::Polygon<f64>,\n) -> Result<Vec<(geo::Polygon<f64>, CensusZone)>> {\n    let gj = load_all_zones_as_geojson(topojson_path)?;\n\n    let start = Instant::now();\n    let mut output = Vec::new();\n    for gj_feature in gj {\n        let geom: geo::Geometry<f64> = gj_feature.clone().try_into()?;\n        if boundary.intersects(&geom) {\n            let polygon = match geom {\n                geo::Geometry::Polygon(p) => p,\n                // TODO What're these, and what should we do with them?\n                geo::Geometry::MultiPolygon(mut mp) => mp.0.remove(0),\n                _ => bail!(\"Unexpected geometry type for {:?}\", gj_feature.properties),\n            };\n            let census_zone = CensusZone {\n                id: gj_feature\n                    .property(\"ID\")\n                    .unwrap()\n                    .as_str()\n                    .unwrap()\n                    .to_string(),\n                cars_0: gj_feature\n                    .property(\"cars_0\")\n                    .unwrap()\n                    .as_u64()\n                    .unwrap()\n                    .try_into()?,\n                cars_1: gj_feature\n                    .property(\"cars_1\")\n                    .unwrap()\n                    .as_u64()","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/popgetter/src/lib.rs#L28-L64","documentation":"clip_zones parses GeoJSON census features into geo::Geometry and only accepts Polygon or MultiPolygon (taking the first polygon of a MultiPolygon). Any other geometry type — e.g. LineString, Point, or GeometryCollection — hits the catch-all bail. It protects downstream polygon clipping, which requires areal geometry.","triggerScenarios":"Calling clip_zones (popgetter/src/lib.rs:46) with an input GeoJSON FeatureCollection whose features contain non-(multi)polygon geometries; the `try_into` succeeds (any geometry is allowed) but the match falls through to `_ => bail!`.","commonSituations":"Census boundary downloads containing point/line features (address points, boundary segments), mixed collections, or TopoJSON conversions producing unusual shapes; TODO in code notes MultiPolygon handling is itself questionable.","solutions":["Filter the FeatureCollection to features whose geometry.type is \"Polygon\" or \"MultiPolygon\" before calling clip_zones.","Inspect the failing feature's properties (printed in the message) and remove/fix that record in the source data.","Buffer points/lines into polygons beforehand if they are legitimate zones.","Patch clip_zones to handle the geometry type (e.g. keep all polygons of a MultiPolygon, skip others)."],"exampleFix":"// before: feed all features\nlet zones = clip_zones(&boundary, gj_str)?;\n// after: pre-filter\nlet kept: Vec<_> = fc.features.into_iter().filter(|f| matches!(f.geometry_type(), \"Polygon\" | \"MultiPolygon\")).collect();","handlingStrategy":"validation","validationCode":"let ok = fc.features.iter().all(|f| {\n    matches!(f.geometry_type(), \"Polygon\" | \"MultiPolygon\")\n});\nif !ok { return Err(\"census data contains non-polygon features\".into()); }","typeGuard":"fn is_areal(f: &GeoJsonFeature) -> bool {\n    matches!(f.geometry_type(), \"Polygon\" | \"MultiPolygon\")\n}","tryCatchPattern":"match clip_zones(&boundary, gj_str) {\n    Err(e) if e.to_string().starts_with(\"Unexpected geometry type\") => {\n        // filter out the offending feature (named in the message) and retry\n    }\n    other => other?,\n}","preventionTips":["Pre-filter census GeoJSON to Polygon/MultiPolygon features.","Check geometry.type in the downloaded dataset before processing.","Buffer or drop point/line features that sneak into boundary datasets."],"tags":["geojson","geometry","popgetter","census"],"backgroundTag":"unsupported-enum-value","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}