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
- 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
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
- 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
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
- multipolygon was unexpectedly empty
- Unexpected geometry type for
- parking lot center didn't snap to a sidewalk
- couldn't find where shape enters map
- couldn't find where shape leaves map
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)