a-b-street/abstreet · error · anyhow::Error

missing bound rect

Error message

missing bound rect

What it means

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.

Solutions

  1. Check that geo_map_area is non-empty before calling; resolve the census area for the map first
  2. Assert the geometry is valid (non-empty polygon) during import and fail earlier with a clearer message
  3. Verify the map name / area lookup that produced geo_map_area

Example fix

// before
let bounding_rect = geo_map_area.bounding_rect().ok_or_else(|| anyhow!("missing bound rect"))?;
// after
if geo_map_area.bounding_rect().is_none() {
    bail!("census area for this map is empty; cannot compute bounding rect");
}
let bounding_rect = geo_map_area.bounding_rect().unwrap();
Defensive patterns

Strategy: validation

Validate before calling

// before fetch_all_for_map
if geo_map_area.bounding_rect().is_none() {
    bail!("map area geometry is empty; cannot query census data");
}

Type guard

fn has_bounding_rect(g: &geo::Geometry<f64>) -> bool {
    g.bounding_rect().is_some()
}

Try / catch

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 }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/02a001a95de9587a. Report an issue: GitHub.

Appendix: source

Thrown at popdat/src/import_census.rs:24

use crate::CensusArea;

impl CensusArea {
    pub async fn fetch_all_for_map(
        map_area: &Polygon,
        bounds: &GPSBounds,
    ) -> Result<Vec<CensusArea>> {
        use flatgeobuf::HttpFgbReader;
        use geozero::geo_types::GeoWriter;

        let mut geo_map_area: geo::Polygon = map_area.clone().into();
        geo_map_area.map_coords_in_place(|c| {
            let projected = geom::Pt2D::new(c.x, c.y).to_gps(bounds);
            (projected.x(), projected.y()).into()
        });

        let bounding_rect = geo_map_area
            .bounding_rect()
            .ok_or_else(|| anyhow!("missing bound rect"))?;

        // See the import handbook for how to prepare this file.
        let mut fgb = HttpFgbReader::open("https://abstreet.s3.amazonaws.com/population_areas.fgb")
            .await?
            .select_bbox(
                bounding_rect.min().x,
                bounding_rect.min().y,
                bounding_rect.max().x,
                bounding_rect.max().y,
            )
            .await?;

        let mut results = vec![];
        while let Some(feature) = fgb.next().await? {
            use flatgeobuf::FeatureProperties;
            // PERF TODO: how to parse into usize directly? And avoid parsing entire props dict?
            let props = feature.properties()?;
            if !props.contains_key("population") {

View on GitHub (pinned to 0964f29315)