{"record":{"id":"df37c4c5e1e90606","repo":"a-b-street/abstreet","slug":"no-building-within-100m-of","errorCode":null,"errorMessage":"No building within 100m of {}","messagePattern":"No building within 100m of (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"synthpop/src/external.rs","lineNumber":57,"sourceCode":"    pub fn import(\n        map: &Map,\n        input: Vec<ExternalPerson>,\n        skip_problems: bool,\n    ) -> Result<Vec<PersonSpec>> {\n        let mut closest: FindClosest<TripEndpoint> = FindClosest::new();\n        for b in map.all_buildings() {\n            closest.add_polygon(TripEndpoint::Building(b.id), &b.polygon);\n        }\n        let borders = MapBorders::new(map);\n\n        let lookup_pt = |endpt, is_origin, mode| match endpt {\n            ExternalTripEndpoint::TripEndpoint(endpt) => Ok(endpt),\n            ExternalTripEndpoint::Position(gps) => {\n                let pt = gps.to_pt(map.get_gps_bounds());\n                if map.get_boundary_polygon().contains_pt(pt) {\n                    match closest.closest_pt(pt, Distance::meters(100.0)) {\n                        Some((x, _)) => Ok(x),\n                        None => Err(anyhow!(\"No building within 100m of {}\", gps)),\n                    }\n                } else {\n                    let (incoming, outgoing) = borders.for_mode(mode);\n                    let candidates = if is_origin { incoming } else { outgoing };\n                    Ok(TripEndpoint::Border(\n                        candidates\n                            .iter()\n                            .min_by_key(|border| border.gps_pos.fast_dist(gps))\n                            .ok_or_else(|| anyhow!(\"No border for {}\", mode.ongoing_verb()))?\n                            .i,\n                    ))\n                }\n            }\n        };\n\n        let mut results = Vec::new();\n        for person in input {\n            let mut spec = PersonSpec {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/synthpop/src/external.rs#L39-L75","documentation":"synthpop's import converts an external trip endpoint given as a GPS position into a TripEndpoint. If the GPS point lies inside the map boundary but no building is within 100 meters (per the prebuilt ClosestEdges structure), the conversion fails with this error. It guards against positions too far from any mapped building to snap to.","triggerScenarios":"Importing external trip data (e.g., from a data source like元气city/seattle data) where an origin/destination GPS coordinate is inside the map polygon but more than 100m from the nearest building in closest_pt's index.","commonSituations":"GPS coordinates in parks, water bodies, industrial areas, or newly developed zones with no buildings in the map; maps built with building filtering that removed nearby buildings; slightly-out-of-bounds coordinates that pass the polygon check.","solutions":["Snap such GPS points to the nearest border instead (the code already does this for outside-boundary points).","Increase the 100m search radius in closest_pt when maps have sparse building coverage.","Pre-filter external trip data to drop endpoints far from any building.","Rebuild the map ensuring building extraction covers the area containing the trips."],"exampleFix":"// before\nmatch closest.closest_pt(pt, Distance::meters(100.0)) {\n    Some((x, _)) => Ok(x),\n    None => Err(anyhow!(\"No building within 100m of {}\", gps)),\n}\n// after\nmatch closest.closest_pt(pt, Distance::meters(100.0)).or_else(|| closest.closest_pt(pt, Distance::meters(500.0))) {\n    Some((x, _)) => Ok(x),\n    None => Ok(TripEndpoint::Border(nearest_border)), // fallback\n}","handlingStrategy":"fallback","validationCode":"// Pre-filter external trips before import\nfn snap_ok(gps: &GPS, map: &Map) -> bool {\n    let pt = gps.to_pt(map.get_gps_bounds());\n    !map.get_boundary_polygon().contains_pt(pt) || pt.is_within(<> /* 100m of some building */)\n}","typeGuard":null,"tryCatchPattern":"// Catch and snap to the nearest border instead\nmatch import(...) {\n    Err(e) if e.to_string().starts_with(\"No building within 100m\") => {\n        import_as_border_trip(...)  // reuse outside-boundary logic\n    }\n    other => other,\n}","preventionTips":["Pre-filter GPS points far from buildings before import","Keep the map's building extraction covering the full trip-data extent","Reuse the existing border-snap fallback for inside-boundary misses","Log dropped or re-snapped coordinates to audit data quality"],"tags":["gps","import","synthpop","data-quality"],"backgroundTag":"resource-not-found","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"}