Skip to content
GuidesBlogPlaygroundDashboard

Audit Bike Infrastructure in Your Neighborhood

A TypeScript CLI that scores bike-friendliness by finding bike lanes, parking, repair stations, and bike-share docks, then compares two neighborhoods.

How bikeable is your neighborhood? This CLI queries Plaza for actual cycling infrastructure — bike lanes, parking, repair stations, and bike-share docks — scores the area, and lets you compare two neighborhoods head-to-head.

  • Geocoding to resolve neighborhood names to coordinates
  • PlazaQL to query six categories of cycling infrastructure
  • A weighted scoring model that rewards dedicated cycleways and penalizes unprotected busy roads

Six parallel PlazaQL queries cover the infrastructure categories. The interesting one is bike lanes, which distinguishes dedicated cycleways from painted lanes and shared routes:

const query = `
$cycleways = search(way, highway: "cycleway").around(distance: 1000, geometry: point(${lat}, ${lng}));
$lanes = search(way, cycleway: ~"lane|track|shared_lane").around(distance: 1000, geometry: point(${lat}, ${lng}));
$designated = search(way, bicycle: "designated").around(distance: 1000, geometry: point(${lat}, ${lng}));
$$ = $cycleways + $lanes + $designated;
`;
const result = await plaza.query(query);

All six queries run in parallel since they’re independent:

const [lanes, parking, repair, sharing, barriers, signals] =
await Promise.all([
queryBikeLanes(lat, lng),
queryBikeParking(lat, lng),
queryRepair(lat, lng),
queryBikeSharing(lat, lng),
queryBarriers(lat, lng),
querySignals(lat, lng),
]);

The barrier query is the cleverest part — it finds busy roads without bike infrastructure by running two queries and taking the difference:

const busyRoadsQuery = `$$ = search(way, highway: ~"primary|secondary|trunk").around(distance: 1000, geometry: point(${lat}, ${lng}));`;
const busyRoads = await plaza.query(busyRoadsQuery);
const busyWithBikeQuery = `$$ = search(way, highway: ~"primary|secondary|trunk", cycleway: ~"lane|track|shared_lane").around(distance: 1000, geometry: point(${lat}, ${lng}));`;
const busyWithBike = await plaza.query(busyWithBikeQuery);
const unprotected = busyRoads.features.length - busyWithBike.features.length;

Scoring uses diminishing returns per category, with dedicated cycleways weighted highest (35 points max) and a penalty for unprotected busy roads:

// Bike lanes: 35 pts max. 20+ routes = full score
const laneScore = Math.round(Math.min(1, lanes.count / 20) * 35);
// Parking: 20 pts. Repair: 15 pts. Sharing: 15 pts. Signals: 10 pts.
// Penalty: busy roads without bike infra (up to -5)
const penalty = -Math.round(Math.min(1, unprotected / 20) * 5);

When comparing two neighborhoods, both audits run in parallel and a side-by-side table shows which area wins each category.

Six PlazaQL queries cover bike lanes (highway=cycleway, cycleway=lane|track), bike parking (with capacity and covered status), repair access (public stands + shops), bike sharing (amenity=bicycle_rental), barriers (busy roads lacking bike infra), and bike-specific traffic signals.

Scoring weights dedicated cycleways higher than painted lanes, rewards covered parking and repair stations, and penalizes busy roads without bike infrastructure. The total is clamped to 0-100.

The complete TypeScript CLI with types, scoring, and comparison formatting is on GitHub:

plazafyi/example-apps/bike-infrastructure

Stack: TypeScript, Node.js CLI (tsx). Run with npx tsx src/index.ts "Williamsburg, Brooklyn".

Compare cities, not just neighborhoods. Try "Copenhagen" "Houston" for a continental-scale comparison. The results will be dramatic.

Track changes over time. Run this monthly and save the scores. Cities are building bike infrastructure fast — you can watch the numbers climb.

Weight by road classification. A bike lane on a busy arterial is more valuable than one on a quiet residential street. Use the highway tag to weight lanes by road importance.

Export to GeoJSON. The PlazaQL results already have coordinates. Collect the bike lane geometries and write them to a file for visualization on a map.