--- title: Audit Bike Infrastructure in Your Neighborhood | Plaza Docs description: 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. ## What you’ll use - **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 ## Key code 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. ## How it works **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. ## Full source The complete TypeScript CLI with types, scoring, and comparison formatting is on GitHub: [**plazafyi/example-apps/bike-infrastructure**](https://github.com/plazafyi/example-apps/tree/main/bike-infrastructure) Stack: TypeScript, Node.js CLI (`tsx`). Run with `npx tsx src/index.ts "Williamsburg, Brooklyn"`. ## Variations to try **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.