a-b-street/abstreet · error · anyhow::Error
couldn't find where shape enters map
Error message
couldn't find where shape enters map
What it means
create_route must place the start of a transit route on the map boundary, computed as the first intersection between the raw GTFS route shape and the map's boundary polygon outer ring. If the shape never crosses the boundary, there is no entry point and this error is thrown. It means the route is judged to be entirely inside the map, so no incoming border can be chosen.
Solutions
- Verify the GTFS shape coordinates were projected with the same projection as the map boundary
- Extend or extrapolate the shape beyond the map edge before intersection, or fall back to snapping the first shape point to the nearest incoming border
- Skip such routes with a warning instead of failing the whole transit import
- Re-check the map boundary polygon for gaps or simplification that excludes the shape
Example fix
// before
let entry_pt = *map.boundary_polygon.get_outer_ring().all_intersections(&route.shape).get(0).ok_or_else(|| anyhow!("couldn't find where shape enters map"))?;
// after
let entry_pt = match map.boundary_polygon.get_outer_ring().all_intersections(&route.shape).first() {
Some(pt) => *pt,
None => {
warn!("route {} never crosses the boundary; snapping first shape point to nearest border", route.route_id);
snapper.nearest_incoming_border(&route.shape.first_pt())
}
}; Defensive patterns
Strategy: fallback
Validate before calling
// before finalize_transit
let hits = map.boundary_polygon.get_outer_ring().all_intersections(&route.shape);
if hits.is_empty() {
warn!("route {} shape never touches the boundary", route.route_id);
} Try / catch
match create_route(...) { Err(e) if e.to_string().contains("shape enters map") => { warn!("skipping contained route: {}", e); continue; }, r => r } Prevention
- Use one consistent projection for GTFS shapes and the map boundary
- Extrapolate shapes slightly beyond the boundary before intersecting
- Sanity-check boundary polygon simplification
- Report skipped routes so feed data quality issues surface
When it happens
Trigger: Calling finalize_transit on a GTFS route whose shape polyline does not intersect map.boundary_polygon.get_outer_ring() — all_intersections(&route.shape) returns an empty Vec, so .get(0) is None.
Common situations: Importing a GTFS feed where a route was clipped so its shape stops just inside the boundary; shapes with only a single point inside the map; boundary polygon changed/simplified after shapes were generated; mis-projected shape coordinates.
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
- couldn't find where shape leaves map
- Couldn't find a lane for
- Stop position wasn't close to a sidewalk
- No valid stops
- Couldn't find a border near start
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/544f4047f3f580e7.
Report an issue: GitHub.
Appendix: source
Thrown at map_model/src/make/transit.rs:170
.stops
.iter()
.filter_map(|gtfs_id| gtfs_to_stop_id.get(gtfs_id).cloned())
.collect();
if stops.is_empty() {
bail!("No valid stops");
}
let border_snap_threshold = Distance::meters(30.0);
let start = if map.boundary_polygon.contains_pt(route.shape.first_pt()) {
map.get_ts(stops[0]).driving_pos.lane()
} else {
// Find the first time the route shape hits the map boundary
let entry_pt = *map
.boundary_polygon
.get_outer_ring()
.all_intersections(&route.shape)
.get(0)
.ok_or_else(|| anyhow!("couldn't find where shape enters map"))?;
// Snap that to a border
let borders = if route.route_type == RawTransitType::Bus {
&snapper.bus_incoming_borders
} else {
&snapper.train_incoming_borders
};
match borders.closest_pt(entry_pt, border_snap_threshold) {
Some((l, _)) => l,
None => bail!(
"Couldn't find a {:?} border near start {}",
route.route_type,
entry_pt
),
}
};
let end_border = if map.boundary_polygon.contains_pt(route.shape.last_pt()) {
NoneView on GitHub (pinned to 0964f29315)