When a school closes, two things change for every family in the district:
This walkthrough explains exactly how we answer both questions, step by step. We use Northside Elementary as an illustrative example — but the methodology is identical for all 11 schools.
We start with two public datasets:
The map shows the drive network colored by road type. Major roads (trunks, primaries) carry faster traffic; residential streets are slower but more numerous.
Raw road type alone doesn’t tell us how fast people actually drive. Our model has two components:
| Road Type | Posted (mph) | Friction (mph) | Ratio |
|---|---|---|---|
| Motorway / Freeway | 65 | 59 | 91% |
| Trunk | 55 | 43 | 78% |
| Primary | 45 | 34 | 76% |
| Secondary | 35 | 28 | 80% |
| Tertiary | 30 | 24 | 80% |
| Residential | 25 | 20 | 80% |
| Service / Living street | 15 | 11 | 73% |
Roads on the map are colored by friction speed: darker = faster. Intersection delays are added on top at signalized and stop-controlled nodes.
A single “effective speed” per road type treats a residential segment between two traffic signals the same as one on a quiet cul-de-sac. By separating mid-block friction from intersection control, routes through signalized corridors correctly accumulate more delay than parallel residential streets with fewer intersections.
The analysis covers three travel modes. Walk and bike networks include paths that cars cannot use — sidewalks, greenways, cut-throughs — which makes them larger than the drive network in some areas.
The remaining steps of this walkthrough focus on drive mode for clarity, but the same Dijkstra algorithm runs for all three.
To find travel time from every location to a school, a naïve approach would run one shortest-path search per grid point — over 16,000 runs. Instead, we use the inverted Dijkstra trick:
Run Dijkstra from each school outward to all reachable nodes. Since the road network is bidirectional, driving to a school takes the same time as driving from it. This gives us distances from all ~16,000 grid points using just 11 runs per mode (33 total across drive/walk/bike).
The map shows shortest-path routes from a single household (● blue dot) to all 11 elementary schools. Each road segment is coloured by cumulative travel time from the origin: green (just departed) → yellow (mid-route) → red (arriving at school). This is the core of the inverted Dijkstra trick — each school’s outward search gives us the route from any point back to that school, so one household can reach all 11 schools without running 11 separate searches from that household.
dijkstra_predecessor_and_distance). Produces both
distance and predecessor maps for route reconstruction.
OSMnx downloads a directed graph, but residential streets are overwhelmingly two-way. We add reverse edges for any missing direction, making the graph effectively undirected. This is necessary for the inverted Dijkstra trick to produce correct results and matches how families actually drive.
Grid points don’t sit exactly on road nodes. We snap each point to the nearest road edge (not nearest node), which is more accurate:
The map shows snap lines connecting grid points to their nearest road edges. Yellow dots are grid points; blue dots are the snap positions on the road.
We tile the entire CHCCS district with a 100 m × 100 m grid — roughly 16,000 cells. Each cell represents a potential household location.
The grid uses WGS84-native coordinates with a cosine-latitude correction to keep cells approximately square despite the curvature of longitude lines. At Chapel Hill’s latitude (35.9°N), 100 m ≈ 0.000898° lat and ≈ 0.001109° lon.
Only cells inside the district boundary are kept. The map shows the grid near Northside — zoom in to see how the cells tile the landscape.
Earlier versions used UTM 17N, but the convergence angle introduced slight grid rotation relative to the lat/lon-aligned Leaflet tiles. A WGS84-native grid with cos(lat) correction produces cells that are equally square (to within 0.01%) and align perfectly with the web map.
For each grid point, we take the minimum travel time across all 11 schools. This is the baseline: how long the drive is today, with every school open.
Yellow areas are close to a school (<5 min); orange and red areas are farther (>10 min). Most of the district is within a 10-minute drive.
Now we remove Northside from the calculation and take the minimum across the remaining 10 schools. No recomputation is needed — we simply exclude Northside’s Dijkstra results from the minimum.
The × marks the closed school. Areas near Northside now show longer travel times because families must drive to the next-closest school.
Subtracting baseline from closure gives the delta — how many additional minutes each location would need to drive.
Only the former Northside zone is affected (everywhere else, the nearest school hasn’t changed). The delta ranges from 0 (already near another school) to several minutes for the most isolated points.
The same analysis runs for walk and bike modes. Walking families see the largest absolute increase because at 2.5 mph, every additional mile adds 24 minutes.
The walk-mode delta map often shows a wider and deeper impact zone than drive mode — highlighting that school closures disproportionately affect families without cars.
The remaining steps continue with drive mode for the traffic analysis.
To estimate traffic, we need to know where school-age children live. The U.S. Census Bureau’s American Community Survey (ACS) 5-Year provides population by age at the block group level:
The map shows block groups shaded by total children (ages 0–9). Block groups are the finest geography with reliable age data.
Block groups are too coarse for pixel-level traffic estimation. We downscale children counts in two stages:
The map shows census blocks (outlines) overlaid with residential parcels (shaded). Children are spread across the blue parcels, not the empty areas.
A technique that uses ancillary data (here, parcel boundaries) to distribute population more accurately than simple area-weighted interpolation. First described by Wright (1936) and widely used in environmental justice and transportation planning.
The Dijkstra algorithm produces a predecessor map for each school: for every network node, it records which node comes before it on the shortest path. This lets us reconstruct the exact route from any grid point to any school by walking the predecessor chain backward.
The map shows several example driving routes to Northside, reconstructed from the predecessor map. Each colored line is the shortest-time path from a different part of the district.
For every pixel, we know:
We trace each pixel’s children along their route and accumulate the count on every road segment traversed. The result is an estimate of school-bound traffic volume on each road.
Thicker, redder lines carry more children. Major collectors and arterials near schools naturally accumulate the most traffic.
CHCCS designates walk zones around each school. Children inside a walk zone typically walk rather than drive. We subtract their traffic contribution from the driving estimate.
The map shows walk zone polygons. When a school is open, children inside its walk zone are removed from driving traffic. When a school closes, its walk zone is not masked — those children must now drive to a different school.
We repeat the traffic computation with Northside closed. Children formerly routed to Northside are now sent to their next-nearest school, flowing along new routes and adding traffic to different roads.
The difference between closure and baseline traffic reveals which roads gain traffic (red) and which lose it (blue). Roads near the closed school lose traffic; roads leading to neighboring schools gain it.
The full analysis combines both lenses:
This dual view lets planners see both the household-level access impact and the road-network-level traffic consequences of any hypothetical closure.
Every model makes simplifying assumptions. Here are the most important ones: