← Home

City Streets

What this is

Every number here is computed from OpenStreetMap street networks plus a global elevation model. The unifying idea: a city's streets define a probability measure over directions in 3D, and the order of the street plan, the shape of the terrain, and much of a city's "character" are properties of that measure and the network it comes from. Methodology extends Boeing, "Urban spatial order: street network orientation, configuration, and entropy," Applied Network Science 4:67 (2019).

What area is analyzed (the comparison window)

Each city is fetched as a disc around its center (default 6 km, grown automatically to cover any registered neighborhood). Comparing raw discs would mix downtowns with suburbs, so analysis is restricted to the urban core: intersections are counted on a 400 m grid, cells under 25 intersections/km² are dropped (a deliberately permissive threshold — proper city fabric like Pittsburgh's North Side stays; genuine low-density fringe goes), and the mask is the connected dense region around the center. Sparse cells ringed by dense fabric (≥4 of 8 neighbors) are bridged, so rivers, parks, and rail yards don't sever the city. The region map on each city page shows exactly this: shaded cells = analyzed core, outer ring = fetch disc, small circles = neighborhoods. The same absolute rule for every city makes "the urban core" a comparable object.

Bearing, the rose, and entropy H₂D

Each street segment has a compass bearing; streets are bidirectional, so every segment contributes its bearing and the opposite direction. Binning length-weighted bearings into 36 wedges of 10° gives the rose (see the gallery); its Shannon entropy measures directional spread:

H = −Σ pᵢ ln pᵢ   ∈ [ln 4 ≈ 1.386 (single perfect grid), ln 36 ≈ 3.584 (uniform)]

Orientation order φ

φ = 1 − ((H − ln 4)/(ln 36 − ln 4))²

φ = 1: one perfect grid (Chicago ≈ 0.9, Manhattan ≈ 0.91). φ = 0: streets point every which way. Note φ measures single-grid alignment: a city made of several differently-rotated grids (Los Angeles, Lima) scores low even though each patch is locally gridded.

The direction measure on the sphere (and why the band)

The 3D extension: each segment's full direction — bearing and grade angle — is a unit vector d = (cos g sin b, cos g cos b, sin g). Reversing the street negates it, so directions live on the projective plane ℝP² = S²/{±1}: each city is an empirical probability measure μ = Σ wᵢ δ[dᵢ], weights ∝ street length. A flat grid collapses to 4 points on the equator; a hilly, disordered city smears over the sphere.

Real streets rarely exceed ~50% grade (26.6°), so the measure is binned on the band |sin g| ≤ 0.447 with equal-area tiles — the tile sphere and unrolled heatmap on each city page. Steeper mass (sanitized at 60%) collects in the top band ("grade ≥ …%+"). H sphere is this binned measure's normalized entropy: 0 = one tile, 1 = uniform over the band.

Orientation tensor: vertical fraction & sphericity

Binning-free counterparts from the second moment T = Σ wᵢ dᵢdᵢᵀ / Σ wᵢ, eigenvalues τ₁ ≥ τ₂ ≥ τ₃ (sum 1): vertical % = T₃₃, the mean squared vertical component of street direction (exactly 0 for a flat city); sphericity = τ₃/τ₁ (0 = directions concentrate on a line, → 1 = isotropic disorder).

Grid angle θ*

The phase of the 4-fold circular moment Σ wᵢ e^{4iθᵢ} of the bearing measure — "which way the dominant grid is rotated," in [0°, 90°). Manhattan's famous ~29° falls straight out.

Curviness (turn rate) & block length

Circuity says a road wanders; turn rate says how sharply. Chains are maximal paths through street-degree-2 nodes of the whole network — the same-road definition: it heals OSM way-splits (a road chopped at every speed-limit change keeps its turns) and breaks at intersections (a dogleg at a 4-way is a routing maneuver, not road curvature). Ramps (highway=*_link) and roundabouts are excluded as junction infrastructure. Turn rate = degrees of mid-road turning per 100 m of road: platted grids sit near 0 (plus their genuine perimeter corners), Pittsburgh's healed switchbacks beat San Francisco's, Kathmandu's lanes exceed 60. curvy share = fraction of length on chains (≥100 m) turning ≥15°/100 m. The chains double as blocks: mean block length is the average chain length between intersections. (Resampling finer than OSM's own shape points would add nothing — between points the road is recorded straight.)

Hilliness

Per-segment grade = rise/run from a 30 m-class elevation model (AWS terrarium tiles), with hygiene: bridges/tunnels excluded (the model sees terrain, not the roadway), segments shorter than a pixel (~15 m) excluded, implausible values (>60%) dropped. hilly % = length-weighted mean |grade|; >8% len = share of length steeper than 8%; each city page shows the full distribution as the hill fan (wedges at their true inclination from horizontal, mirrored like the axial measure) and the elevation-angle marginal.

Walkability & staircases

Computed on the pedestrian network. A staircase's grade comes from its tagged step count (≈0.17 m/step) or the elevation model — never rise/run of its tiny footprint. walk hilly % is the mean |grade| a pedestrian faces, staircases included.

Counting staircases honestly: a "staircase" is a connected component of steps segments — one staircase split into several OSM ways counts once. Cities also differ in what they map: San Francisco records thousands of short entrance flights (mean ≈16 m); Pittsburgh's fame rests on long municipal stairway-streets (mean ≈31 m). A major staircase is a component ≥30 m — the civic stairway-street phenomenon, not an entrance flight. The same ≥30 m rule is applied on every continent.

Comparing across cities. Raw counts are the most honest ranking: by major stairs Pittsburgh (≈400) is America's staircase capital and 4th worldwide, behind only La Paz, Valparaíso, and Prague. Turning that into a density needs care, because the analyzed window differs by extent (see below): a per-km² figure divides by area, so a boundary city measured over its whole footprint (Pittsburgh, 131 km²) looks far sparser than a disc city measured over just its dense 6 km core (Valparaíso, 38 km²) — an artifact, not a real gap. We therefore headline major stairs / km of walkable street, which normalizes by the pedestrian fabric itself and stays comparable across disc and boundary cities; the area-based per-km² figure remains on each city page, flagged as extent-sensitive. Coverage caveat: some regions (e.g. South Asia) rarely tag steps at all.

Network character: signals, one-way, bridges, connectivity

signals/km² — traffic signals (highway=traffic_signals nodes) per km² of urban core; signals/intersection normalizes by intersection count. one-way share and bridge share are length-weighted shares of the drive network. 4-way % (the grid hallmark), dead-end share, mean streets/intersection, and circuity (street length ÷ straight-line distance, ≥1) complete the connectivity picture.

Population & density

Population and land area are approximate city-proper figures entered as registry data — labels, not measurements — chosen as a consistent pair (the same administrative unit), so pop/km² = population ÷ city-proper land area is honest (Manhattan ≈ 27,600/km²). We deliberately do not divide by the analyzed-core area: the core mask can flood across municipal lines (Manhattan's crosses into Brooklyn and Jersey City), which would mismatch numerator and denominator. Computed densities over the core — intersections/km², street km/km² — are separate, fully-measured metrics.

Mobility: OSM infrastructure shares vs Walk Score®

Two distinct families. OSM infra shares — sidewalk / bike-infra / transit-lane share of tagged street length — are transparent, global, computed from our own data; they measure infrastructure presence and undercount where tagging is sparse. Walk Score® / Bike Score® / Transit Score® (shown when fetched) are the official amenity-proximity indices from walkscore.com (Redfin): point-based, so a city's value is the mean over sampled urban-core points and a neighborhood's is its center point; coverage US/Canada (elsewhere "—"). Fetch with your free key: julia --project=. scripts/fetch_walkscores.jl YOUR_KEY. Scores courtesy of Walk Score.

Traffic proxy (betweenness)

Real traffic volumes are proprietary or US-only; we use sampled betweenness centrality on the routing graph — how many shortest paths cross each street — as an honest through-traffic model. Weighting the direction measure by it asks "which way does the through-traffic point?" It's a model, not a measurement, disc-clipping biases it toward the center, and it can be toggled off everywhere.

Why Wasserstein and not KL divergence?

Raw KL divergence is unsuitable for direction measures: asymmetric, infinite whenever one city has mass in a bin the other leaves empty, and geometry-blind — a grid shifted by one bin-width is as KL-far from itself as from uniform noise. Wasserstein is built on the sphere's metric, so nearby directions cost little — which is what "similar street plans" should mean. The repaired form of KL — Jensen–Shannon divergence (symmetric, finite, ∈[0,1]), minimized over rotations — is the "JS divergence" option: it measures overlap, a deliberately different question from the work to morph. High JS + low W₂ = different exact directions, similar overall shape.

City similarity: the distances

Normalization: each kind lives on a ground space with its own diameter (π/2 on the projective sphere; 90° on the bearing circle; 26.6° on the grade interval). Every matrix is divided by that diameter, so all distances read as a fraction of the maximum possible transport, in [0,1], comparable across kinds (JS by its bound ln 2). The MDS embedding places cities in the plane so pairwise distances are respected as well as possible — clusters are families of similarly-built cities; each city page lists nearest neighbors under every distance. In compare overlays, each rose is drawn as a stepped outline in absolute √proportions (weights sum to 1 per city), so directional concentration compares directly across cities.

Neighborhoods

Any registered neighborhood (one line in data/neighborhoods.toml; the fetch disc grows automatically to cover it) gets the same measures at neighborhood scale — rose card, φ, turn rate, hilliness, staircases, mobility shares, Walk Score® when fetched — sliced from the city's cached network at zero download cost. The per-city sortable table makes intra-city contrasts visible: Nob Hill's perfect grid on 7% grades, Squirrel Hill as Pittsburgh's curviest quarter, the Loop vs Wicker Park.

Sources & reproducibility

Street networks: OpenStreetMap via Overpass (drive + walk discs; admin boundaries for flagship cities as sensitivity checks). Elevation: AWS Terrain Tiles (terrarium; SRTM-class 30 m, US 10 m), bilinearly sampled, cached locally. Basemap: Carto/OpenStreetMap (attribution on the map). Methodology: Boeing (2019) extended to ℝP²; circular OT per Rabin–Delon–Gousseau (2011) / Delon–Salomon–Sobolevski (2010). Everything is cached and incremental — adding a city is one command (~5 min); this dashboard reads only precomputed JSON. Built in Julia.