a-b-street/abstreet · error

study area geojson has

Error message

study area geojson has {} polygons

What it means

load_study_area parses the study area GeoJSON and requires exactly one polygon, since the scenario operates on a single contiguous study area. If the parsed list has any count other than 1, it bails reporting how many polygons were found.

Solutions

  1. Verify the study area geojson contains exactly one polygon fully inside the map's GPS bounds.
  2. Dissolve multiple polygons into one (union in QGIS/GeoPandas) or restrict the study area.
  3. Check the require_in_bounds setting and the map's bounds if features are being silently dropped.

Example fix

// before (two disjoint polygons)
features: [polyA, polyB]
// after (dissolved)
features: [union(polyA, polyB)]
Defensive patterns

Strategy: validation

Validate before calling

let polys = Polygon::from_geojson_bytes(&bytes, gps_bounds, require_in_bounds)?;
if polys.len() != 1 {
    bail!("study area must resolve to exactly 1 in-bounds polygon, got {}", polys.len());
}

Try / catch

match load_study_area(map) {
    Ok(area) => area,
    Err(e) if e.to_string().contains("study area geojson has") => {
        eprintln!("Fix the study area file (empty or multi-polygon): {e}");
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: generate_scenario for a UK map whose study area geojson yields 0 polygons (empty file / out-of-bounds features dropped when require_in_bounds is set) or multiple polygons (disjoint study area).

Common situations: Study area drawn partly outside the map's GPS bounds so in-bounds filtering drops all polygons; exporting a multi-polygon study area instead of dissolving it into one; pointing at a truncated or wrong file.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at importer/src/uk.rs:218

        } else {
            bail!("Input is missing geo_code: {:?}", tags);
        }
    }
    Ok(zones)
}

fn load_study_area(map: &Map) -> Result<Polygon> {
    let require_in_bounds = true;
    let mut list = Polygon::from_geojson_bytes(
        &abstio::slurp_file(abstio::path(format!(
            "system/study_areas/{}.geojson",
            map.get_name().city.city.replace("_", "-")
        )))?,
        map.get_gps_bounds(),
        require_in_bounds,
    )?;
    if list.len() != 1 {
        bail!("study area geojson has {} polygons", list.len());
    }
    Ok(list.pop().unwrap().0)
}

fn check_sensor_data(map: &Map, scenario: &Scenario, sensor_path: &str, timer: &mut Timer) {
    use map_model::PathRequest;

    let requests = scenario
        .all_trips()
        .filter_map(|trip| {
            if trip.mode == TripMode::Drive {
                TripEndpoint::path_req(trip.origin, trip.destination, trip.mode, map)
            } else {
                None
            }
        })
        .collect();
    let deduped = PathRequest::deduplicate(map, requests);

View on GitHub (pinned to 0964f29315)