{"record":{"id":"02a001a95de9587a","repo":"a-b-street/abstreet","slug":"missing-bound-rect","errorCode":null,"errorMessage":"missing bound rect","messagePattern":"missing bound rect","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"popdat/src/import_census.rs","lineNumber":24,"sourceCode":"use crate::CensusArea;\n\nimpl CensusArea {\n    pub async fn fetch_all_for_map(\n        map_area: &Polygon,\n        bounds: &GPSBounds,\n    ) -> Result<Vec<CensusArea>> {\n        use flatgeobuf::HttpFgbReader;\n        use geozero::geo_types::GeoWriter;\n\n        let mut geo_map_area: geo::Polygon = map_area.clone().into();\n        geo_map_area.map_coords_in_place(|c| {\n            let projected = geom::Pt2D::new(c.x, c.y).to_gps(bounds);\n            (projected.x(), projected.y()).into()\n        });\n\n        let bounding_rect = geo_map_area\n            .bounding_rect()\n            .ok_or_else(|| anyhow!(\"missing bound rect\"))?;\n\n        // See the import handbook for how to prepare this file.\n        let mut fgb = HttpFgbReader::open(\"https://abstreet.s3.amazonaws.com/population_areas.fgb\")\n            .await?\n            .select_bbox(\n                bounding_rect.min().x,\n                bounding_rect.min().y,\n                bounding_rect.max().x,\n                bounding_rect.max().y,\n            )\n            .await?;\n\n        let mut results = vec![];\n        while let Some(feature) = fgb.next().await? {\n            use flatgeobuf::FeatureProperties;\n            // PERF TODO: how to parse into usize directly? And avoid parsing entire props dict?\n            let props = feature.properties()?;\n            if !props.contains_key(\"population\") {","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/popdat/src/import_census.rs#L6-L42","documentation":"fetch_all_for_map projects the map area geometry and requires its axis-aligned bounding rect to open a spatial query against the remote flatgeobuf population_areas file. geo's Geometry::bounding_rect returns Option and is None for an empty/invalid geometry, so this error is thrown before any network request is made.","triggerScenarios":"Calling fetch_all_for_map with a geo_map_area whose bounding_rect() is None — an empty MultiPolygon/geometry, or a degenerate area with no points, typically from the census area lookup returning nothing for the map.","commonSituations":"Importing population data for a map whose census area geometry failed to resolve; passing an empty geometry after a failed FGB feature fetch upstream; misconfigured map name that matches no area.","solutions":["Check that geo_map_area is non-empty before calling; resolve the census area for the map first","Assert the geometry is valid (non-empty polygon) during import and fail earlier with a clearer message","Verify the map name / area lookup that produced geo_map_area"],"exampleFix":"// before\nlet bounding_rect = geo_map_area.bounding_rect().ok_or_else(|| anyhow!(\"missing bound rect\"))?;\n// after\nif geo_map_area.bounding_rect().is_none() {\n    bail!(\"census area for this map is empty; cannot compute bounding rect\");\n}\nlet bounding_rect = geo_map_area.bounding_rect().unwrap();","handlingStrategy":"validation","validationCode":"// before fetch_all_for_map\nif geo_map_area.bounding_rect().is_none() {\n    bail!(\"map area geometry is empty; cannot query census data\");\n}","typeGuard":"fn has_bounding_rect(g: &geo::Geometry<f64>) -> bool {\n    g.bounding_rect().is_some()\n}","tryCatchPattern":"match fetch_all_for_map(map).await { Err(e) if e.to_string() == \"missing bound rect\" => Err(anyhow!(\"census area unresolved for {}; check import step\", map.get_name())), r => r }","preventionTips":["Verify the census-area lookup succeeds before computing bounds","Fail early with context naming the map/area","Validate geometry non-emptiness right after it is produced","Cover the lookup with an import-time integration test"],"tags":["gis","census","import","geometry"],"backgroundTag":"empty-required-field","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"}