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:
Orientation order φ
φ = 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
- sphere W₂ — 3D: full street-plan shape (bearing × grade), minimized over all rotations about the vertical axis (two identical grids at different orientations are distance ≈ 0); Sinkhorn-computed on a coarsened measure for speed;
- grid W₂ — 2D: orientation only (bearing marginal, no elevation), rotation-aligned circular Wasserstein — purely "how similar are the grids";
- elevation W₂: 1D Wasserstein between grade-angle distributions — a pure hilliness distance, blind to orientation;
- JS divergence: rotation-aligned measure overlap (see above).
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.