{"record":{"id":"94867a3ff3c50d84","repo":"a-b-street/abstreet","slug":"study-area-geojson-has-polygons","errorCode":null,"errorMessage":"study area geojson has {} polygons","messagePattern":"study area geojson has (.+?) polygons","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"importer/src/uk.rs","lineNumber":218,"sourceCode":"        } else {\n            bail!(\"Input is missing geo_code: {:?}\", tags);\n        }\n    }\n    Ok(zones)\n}\n\nfn load_study_area(map: &Map) -> Result<Polygon> {\n    let require_in_bounds = true;\n    let mut list = Polygon::from_geojson_bytes(\n        &abstio::slurp_file(abstio::path(format!(\n            \"system/study_areas/{}.geojson\",\n            map.get_name().city.city.replace(\"_\", \"-\")\n        )))?,\n        map.get_gps_bounds(),\n        require_in_bounds,\n    )?;\n    if list.len() != 1 {\n        bail!(\"study area geojson has {} polygons\", list.len());\n    }\n    Ok(list.pop().unwrap().0)\n}\n\nfn check_sensor_data(map: &Map, scenario: &Scenario, sensor_path: &str, timer: &mut Timer) {\n    use map_model::PathRequest;\n\n    let requests = scenario\n        .all_trips()\n        .filter_map(|trip| {\n            if trip.mode == TripMode::Drive {\n                TripEndpoint::path_req(trip.origin, trip.destination, trip.mode, map)\n            } else {\n                None\n            }\n        })\n        .collect();\n    let deduped = PathRequest::deduplicate(map, requests);","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/importer/src/uk.rs#L200-L236","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Verify the study area geojson contains exactly one polygon fully inside the map's GPS bounds.","Dissolve multiple polygons into one (union in QGIS/GeoPandas) or restrict the study area.","Check the require_in_bounds setting and the map's bounds if features are being silently dropped."],"exampleFix":"// before (two disjoint polygons)\nfeatures: [polyA, polyB]\n// after (dissolved)\nfeatures: [union(polyA, polyB)]","handlingStrategy":"validation","validationCode":"let polys = Polygon::from_geojson_bytes(&bytes, gps_bounds, require_in_bounds)?;\nif polys.len() != 1 {\n    bail!(\"study area must resolve to exactly 1 in-bounds polygon, got {}\", polys.len());\n}","typeGuard":null,"tryCatchPattern":"match load_study_area(map) {\n    Ok(area) => area,\n    Err(e) if e.to_string().contains(\"study area geojson has\") => {\n        eprintln!(\"Fix the study area file (empty or multi-polygon): {e}\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Ensure the study area polygon lies fully within the map's GPS bounds","Union multiple study-area polygons into one before export","Visually check the study area against the map boundary in QGIS first"],"tags":["geojson","input-validation","importer","uk"],"backgroundTag":"empty-result-set","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"}