"""
San Francisco livability scoring — hand-encoded geographic primitives.

PROVENANCE TAGS (surfaced in the UI as confidence badges):
  MEASURED  — pulled from an authoritative source this session
  DERIVED   — computed from MEASURED data (chiefly USGS 1m elevation)
  ENCODED   — hand-encoded by Claude from documented public sources; screening quality only

Companion MEASURED files in this directory:
  elevations.csv  USGS 3DEP 1m DEM, 889 grid cells
  parks.csv       DataSF gtr9-ntp6, Rec & Parks properties (252)
  schools.csv     DataSF 7e7j-59qk, public schools (126)
  libraries.csv   DataSF nc68-ngbr, SFPL branches (28)
  businesses.csv  DataSF g8m3-pdis, active businesses by self-reported NAICS (4289)
"""

# ---------------------------------------------------------------------------
# CITY BOUNDARY  (ENCODED)
# Water-facing segments are flagged so distance-to-shore ignores the southern
# county line with San Mateo, which is a land border, not a shoreline.
# ---------------------------------------------------------------------------
SF_BOUNDARY = [
    (-122.5115, 37.7790), (-122.5093, 37.7860), (-122.5060, 37.7900), (-122.4990, 37.7905),
    (-122.4880, 37.7975), (-122.4790, 37.8055), (-122.4720, 37.8100), (-122.4650, 37.8110),
    (-122.4560, 37.8065), (-122.4480, 37.8055), (-122.4400, 37.8085), (-122.4310, 37.8085),
    (-122.4240, 37.8070), (-122.4160, 37.8085), (-122.4060, 37.8080), (-122.4000, 37.8055),
    (-122.3935, 37.7975), (-122.3880, 37.7930), (-122.3830, 37.7860), (-122.3865, 37.7800),
    (-122.3860, 37.7730), (-122.3890, 37.7680), (-122.3860, 37.7600), (-122.3785, 37.7550),
    (-122.3760, 37.7480), (-122.3660, 37.7395), (-122.3555, 37.7240), (-122.3760, 37.7130),
    (-122.3830, 37.7080), (-122.3960, 37.7080), (-122.4080, 37.7085), (-122.4240, 37.7090),
    (-122.4400, 37.7080), (-122.4560, 37.7085), (-122.4680, 37.7060), (-122.4790, 37.7080),
    (-122.4880, 37.7130), (-122.4930, 37.7180), (-122.5040, 37.7250), (-122.5090, 37.7400),
    (-122.5105, 37.7600), (-122.5115, 37.7790),
]
# Vertex index range (inclusive) forming the inland San Mateo county line.
COUNTY_LINE_RANGE = (28, 35)

TREASURE_ISLAND = [
    (-122.3760, 37.8010), (-122.3630, 37.8010), (-122.3610, 37.8280),
    (-122.3730, 37.8290), (-122.3760, 37.8010),
]

# Reference destinations
POWELL_ST = (37.7844, -122.4079)   # Powell St BART/Muni
SFO       = (37.6213, -122.3790)

# ---------------------------------------------------------------------------
# NEIGHBOURHOODS  (centroids ENCODED; crime + 311 counts MEASURED, DataSF)
# violent / property: SFPD incident reports wg3w-h783, calendar 2024+2025
# cases311: 311 street-condition cases vw6y-z8j6, trailing 12 months
# Counts are normalised to per-unit-area in build.py using the grid itself,
# so raw magnitudes here are never compared across unequal-sized neighbourhoods.
# ---------------------------------------------------------------------------
NEIGHBORHOODS = [
    # name,                            lat,      lon,      violent, property, cases311
    ("Bayview Hunters Point",          37.7300, -122.3900,  1534,  4670,  20914),
    ("Bernal Heights",                 37.7400, -122.4160,   505,  2206,   9721),
    ("Castro/Upper Market",            37.7620, -122.4350,   460,  2570,  19596),
    ("Chinatown",                      37.7950, -122.4075,   385,  1541,   7706),
    ("Excelsior",                      37.7240, -122.4270,   464,  1631,   7360),
    ("Financial District/South Beach", 37.7920, -122.3990,  1110,  5385,  13327),
    ("Glen Park",                      37.7340, -122.4340,    61,   531,   2600),
    ("Golden Gate Park",               37.7690, -122.4830,   130,   853,   2643),
    ("Haight Ashbury",                 37.7700, -122.4460,   241,  1403,  17792),
    ("Hayes Valley",                   37.7760, -122.4260,   373,  2494,  24155),
    ("Inner Richmond",                 37.7830, -122.4650,   138,   924,   7374),
    ("Inner Sunset",                   37.7600, -122.4700,   151,  1147,   7534),
    ("Japantown",                      37.7850, -122.4300,   102,   587,   2704),
    ("Lakeshore",                      37.7250, -122.4850,   229,  1607,   1321),
    ("Lincoln Park",                   37.7830, -122.4980,     2,   101,    124),
    ("Lone Mountain/USF",              37.7790, -122.4500,   172,  1176,   7960),
    ("Marina",                         37.8020, -122.4360,   341,  2423,   8682),
    ("McLaren Park",                   37.7190, -122.4180,    43,    73,    470),
    ("Mission",                        37.7600, -122.4150,  3172,  7593,  95692),
    ("Mission Bay",                    37.7700, -122.3930,   433,  1404,   5996),
    ("Nob Hill",                       37.7930, -122.4160,   591,  2674,  23184),
    ("Noe Valley",                     37.7500, -122.4320,   107,  1810,   5291),
    ("North Beach",                    37.8020, -122.4100,   408,  2018,   6683),
    ("Oceanview/Merced/Ingleside",     37.7180, -122.4570,   166,   965,   5480),
    ("Outer Mission",                  37.7230, -122.4440,   338,  1175,   6803),
    ("Outer Richmond",                 37.7780, -122.4890,   251,  1740,  11652),
    ("Pacific Heights",                37.7930, -122.4340,   141,  2078,   7056),
    ("Portola",                        37.7270, -122.4060,   286,  1047,   7725),
    ("Potrero Hill",                   37.7580, -122.4000,   183,  1401,   6226),
    ("Presidio",                       37.7980, -122.4660,    13,    61,    328),
    ("Presidio Heights",               37.7880, -122.4530,    65,   735,   2987),
    ("Russian Hill",                   37.8010, -122.4190,   193,  1646,   7187),
    ("Seacliff",                       37.7870, -122.4890,     5,   134,    274),
    ("South of Market",                37.7780, -122.4080,  2537,  6762,  34968),
    ("Sunset/Parkside",                37.7480, -122.4950,   423,  2879,  12649),
    ("Tenderloin",                     37.7840, -122.4130,  2954,  5423,  34130),
    ("Treasure Island",                37.8230, -122.3700,   103,   294,    113),
    ("Twin Peaks",                     37.7510, -122.4470,    31,   411,   1413),
    ("Visitacion Valley",              37.7140, -122.4070,   259,   739,   3078),
    ("West of Twin Peaks",             37.7350, -122.4600,   281,  1861,   7427),
    ("Western Addition",               37.7800, -122.4340,   688,  3056,  13983),
]

# ---------------------------------------------------------------------------
# FULL-SIZE SUPERMARKETS  (ENCODED list; coordinates snapped in build.py to the
# nearest MEASURED `grocery` business point within 350 m, which corrects drift)
# The MEASURED grocery layer (432 pts) counts every self-reported grocer including
# small markets, so this curated list answers "proper supermarket" specifically.
# ---------------------------------------------------------------------------
SUPERMARKETS = [
    ("Safeway Market St",            37.7688, -122.4287),
    ("Safeway Mission/30th",         37.7434, -122.4222),
    ("Safeway Potrero Center",       37.7660, -122.4088),
    ("Safeway Marina",               37.8060, -122.4320),
    ("Safeway Cathedral Hill",       37.7830, -122.4310),
    ("Safeway Noriega",              37.7538, -122.4855),
    ("Safeway Lakeshore Plaza",      37.7350, -122.4930),
    ("Safeway La Playa",             37.7730, -122.5095),
    ("Safeway Diamond Heights",      37.7430, -122.4400),
    ("Trader Joe's Masonic",         37.7834, -122.4463),
    ("Trader Joe's SoMa",            37.7715, -122.4090),
    ("Trader Joe's North Beach",     37.8055, -122.4120),
    ("Trader Joe's Stonestown",      37.7280, -122.4750),
    ("Whole Foods Haight",           37.7690, -122.4530),
    ("Whole Foods Noe Valley",       37.7513, -122.4320),
    ("Whole Foods Potrero",          37.7645, -122.4030),
    ("Whole Foods SoMa",             37.7810, -122.4005),
    ("Whole Foods California St",    37.7895, -122.4245),
    ("Whole Foods Ocean Ave",        37.7245, -122.4530),
    ("Rainbow Grocery",              37.7686, -122.4152),
    ("Bi-Rite Divisadero",           37.7752, -122.4375),
    ("Gus's Market Mission",         37.7635, -122.4130),
    ("Gus's Market Noriega",         37.7535, -122.4990),
    ("Cal-Mart",                     37.7860, -122.4560),
    ("Mollie Stone's California St", 37.7885, -122.4340),
    ("Mollie Stone's Portola",       37.7440, -122.4560),
    ("Andronico's Irving",           37.7635, -122.4740),
    ("Lucky Ocean Ave",              37.7245, -122.4560),
    ("Foods Co Folsom",              37.7690, -122.4150),
    ("Foods Co Bayview",             37.7305, -122.3990),
    ("Grocery Outlet Potrero",       37.7655, -122.4045),
    ("Canyon Market Glen Park",      37.7335, -122.4335),
    ("Real Food Polk",               37.7955, -122.4225),
    ("Bryan's Fillmore",             37.7860, -122.4540),
    ("Village Market",               37.7845, -122.4700),
    ("New May Wah Clement",          37.7830, -122.4680),
    ("Sunset Super Irving",          37.7635, -122.4830),
    ("22nd & Irving Market",         37.7635, -122.4805),
    ("Duc Loi Mission",              37.7615, -122.4190),
    ("Manila Oriental Market",       37.7335, -122.4235),
    ("Lien Hing Chinatown",          37.7965, -122.4085),
    ("Other Avenues Co-op",          37.7600, -122.5030),
    ("Costco 10th St",               37.7715, -122.4130),
    ("Target Metreon",               37.7855, -122.4045),
]

# ---------------------------------------------------------------------------
# COMMERCIAL CORRIDORS  (ENCODED)
# (name, intensity 0-1, polyline)
# Intensity reflects the liveliness of the corridor: shops open late, foot
# traffic, restaurant/bar mix. Used for the food & nightlife factor and as the
# proximity term for corner-store convenience.
# ---------------------------------------------------------------------------
COMMERCIAL = [
    ("Valencia St",        1.00, [(37.7649, -122.4218), (37.7513, -122.4207)]),
    ("Mission St (Inner)", 0.95, [(37.7663, -122.4194), (37.7510, -122.4184)]),
    ("Castro St",          0.90, [(37.7638, -122.4348), (37.7590, -122.4348)]),
    ("Columbus Ave",       0.90, [(37.7975, -122.4073), (37.8055, -122.4160)]),
    ("Haight St",          0.85, [(37.7699, -122.4530), (37.7702, -122.4380)]),
    ("Hayes St",           0.85, [(37.7763, -122.4300), (37.7763, -122.4200)]),
    ("Divisadero St",      0.85, [(37.7715, -122.4375), (37.7830, -122.4380)]),
    ("Chestnut St",        0.85, [(37.8005, -122.4430), (37.8005, -122.4300)]),
    ("Polk St",            0.85, [(37.7900, -122.4210), (37.7985, -122.4225)]),
    ("Grant/Stockton",     0.85, [(37.7930, -122.4065), (37.8000, -122.4085)]),
    ("Union Square",       0.85, [(37.7875, -122.4075), (37.7885, -122.4045)]),
    ("Market St Downtown", 0.80, [(37.7770, -122.4165), (37.7935, -122.3955)]),
    ("18th St",            0.80, [(37.7610, -122.4370), (37.7615, -122.4150)]),
    ("Union St",           0.80, [(37.7975, -122.4360), (37.7975, -122.4225)]),
    ("Fillmore St",        0.80, [(37.7780, -122.4335), (37.7930, -122.4340)]),
    ("Clement St",         0.80, [(37.7828, -122.4700), (37.7828, -122.4600)]),
    ("24th St (Calle 24)", 0.80, [(37.7523, -122.4230), (37.7523, -122.4090)]),
    ("Irving St",          0.75, [(37.7636, -122.4740), (37.7636, -122.4600)]),
    ("24th St Noe Valley", 0.75, [(37.7513, -122.4370), (37.7513, -122.4270)]),
    ("SoMa Folsom/11th",   0.75, [(37.7715, -122.4145), (37.7810, -122.4040)]),
    ("Mid-Market",         0.70, [(37.7790, -122.4145), (37.7830, -122.4090)]),
    ("Cortland Ave",       0.70, [(37.7390, -122.4200), (37.7390, -122.4120)]),
    ("Japantown",          0.70, [(37.7855, -122.4310), (37.7855, -122.4285)]),
    ("Embarcadero/Ferry",  0.70, [(37.7955, -122.3935), (37.8025, -122.4030)]),
    ("9th Ave Inner Sunset", 0.70, [(37.7635, -122.4665), (37.7665, -122.4665)]),
    ("Geary Blvd Richmond",0.65, [(37.7810, -122.4900), (37.7825, -122.4530)]),
    ("West Portal Ave",    0.65, [(37.7405, -122.4665), (37.7420, -122.4700)]),
    ("Fisherman's Wharf",  0.60, [(37.8080, -122.4180), (37.8085, -122.4100)]),
    ("Cole Valley",        0.60, [(37.7665, -122.4500), (37.7665, -122.4480)]),
    ("Church St / Duboce", 0.60, [(37.7690, -122.4290), (37.7620, -122.4285)]),
    ("Potrero 18th/20th",  0.60, [(37.7615, -122.4010), (37.7590, -122.4010)]),
    ("Dogpatch 3rd/22nd",  0.60, [(37.7580, -122.3885), (37.7545, -122.3880)]),
    ("Excelsior Mission",  0.60, [(37.7280, -122.4320), (37.7200, -122.4380)]),
    ("Taraval St",         0.55, [(37.7425, -122.5030), (37.7425, -122.4670)]),
    ("San Bruno Ave",      0.55, [(37.7300, -122.4045), (37.7215, -122.4030)]),
    ("Ocean Ave",          0.55, [(37.7245, -122.4600), (37.7250, -122.4460)]),
    ("Noriega St",         0.50, [(37.7537, -122.5030), (37.7537, -122.4720)]),
    ("Balboa St",          0.50, [(37.7770, -122.4900), (37.7770, -122.4650)]),
    ("Sacramento St",      0.50, [(37.7880, -122.4570), (37.7880, -122.4430)]),
    ("Laurel Village",     0.50, [(37.7865, -122.4595), (37.7865, -122.4560)]),
    ("3rd St Bayview",     0.45, [(37.7370, -122.3905), (37.7255, -122.3925)]),
    ("Judah St",           0.45, [(37.7615, -122.5060), (37.7615, -122.4700)]),
    ("Visitacion Leland",  0.40, [(37.7125, -122.4090), (37.7125, -122.4030)]),
]

# ---------------------------------------------------------------------------
# ARTERIALS  (ENCODED geometry; `hin` column MEASURED)
# (name, traffic weight 0-1, hin_miles, polyline)
# hin_miles = corridor mileage on SFMTA's 2024 Vision Zero High Injury Network
# (DataSF enwt-3u8m). 0.0 means the street does not appear on the HIN.
# ---------------------------------------------------------------------------
ARTERIALS = [
    ("19th Ave / Park Presidio", 1.00, 1.17, [(37.7120, -122.4700), (37.7280, -122.4755), (37.7600, -122.4757), (37.7900, -122.4735), (37.8055, -122.4715)]),
    ("Van Ness Ave",             0.92, 1.22, [(37.7725, -122.4195), (37.7870, -122.4215), (37.8005, -122.4230)]),
    ("Geary Blvd / Geary St",    0.90, 8.06, [(37.7800, -122.5085), (37.7815, -122.4900), (37.7825, -122.4600), (37.7845, -122.4400), (37.7865, -122.4200), (37.7870, -122.4075)]),
    ("Mission St",               0.88,16.07, [(37.7080, -122.4400), (37.7220, -122.4370), (37.7420, -122.4230), (37.7600, -122.4190), (37.7760, -122.4170), (37.7885, -122.4040)]),
    ("Lombard St (US-101)",      0.86, 0.56, [(37.7995, -122.4440), (37.7998, -122.4300), (37.8010, -122.4230)]),
    ("Fell St / Oak St",         0.85, 8.06, [(37.7730, -122.4530), (37.7735, -122.4380), (37.7745, -122.4230), (37.7755, -122.4190)]),
    ("Franklin St / Gough St",   0.85,13.58, [(37.7720, -122.4235), (37.7860, -122.4245), (37.8000, -122.4255)]),
    ("Cesar Chavez St",          0.85, 4.41, [(37.7485, -122.4350), (37.7485, -122.4150), (37.7500, -122.3960)]),
    ("Bayshore Blvd",            0.82, 3.86, [(37.7085, -122.4030), (37.7250, -122.4045), (37.7420, -122.4055)]),
    ("Harrison St / Bryant St",  0.82, 8.34, [(37.7700, -122.4130), (37.7800, -122.4000), (37.7860, -122.3930)]),
    ("Potrero Ave",              0.80, 1.24, [(37.7480, -122.4065), (37.7600, -122.4070), (37.7700, -122.4075)]),
    ("Sloat Blvd",               0.80, 0.00, [(37.7350, -122.5050), (37.7345, -122.4850), (37.7330, -122.4660)]),
    ("Alemany Blvd",             0.80, 0.66, [(37.7270, -122.4600), (37.7275, -122.4400), (37.7300, -122.4130), (37.7350, -122.4050)]),
    ("South Van Ness Ave",       0.80, 1.22, [(37.7520, -122.4165), (37.7650, -122.4170), (37.7740, -122.4175)]),
    ("Folsom St / Howard St",    0.78,21.05, [(37.7690, -122.4145), (37.7800, -122.4010), (37.7870, -122.3935)]),
    ("Junipero Serra Blvd",      0.78, 0.00, [(37.7085, -122.4700), (37.7200, -122.4690), (37.7300, -122.4665)]),
    ("3rd St",                   0.76, 1.35, [(37.7120, -122.3945), (37.7300, -122.3900), (37.7550, -122.3880), (37.7780, -122.3925)]),
    ("Market St",                0.76, 0.00, [(37.7620, -122.4350), (37.7735, -122.4225), (37.7830, -122.4090), (37.7935, -122.3955)]),
    ("Bush St / Pine St",        0.76,12.06, [(37.7890, -122.4330), (37.7900, -122.4150), (37.7910, -122.4020)]),
    ("San Jose Ave",             0.75, 1.19, [(37.7200, -122.4460), (37.7330, -122.4340), (37.7440, -122.4245)]),
    ("7th St / 8th St SoMa",     0.75, 4.06, [(37.7700, -122.4110), (37.7790, -122.4060), (37.7840, -122.4030)]),
    ("Columbus Ave",             0.72, 5.90, [(37.7955, -122.4045), (37.8010, -122.4110), (37.8060, -122.4165)]),
    ("Divisadero St / Castro",   0.72, 2.40, [(37.7615, -122.4348), (37.7715, -122.4375), (37.7860, -122.4385), (37.7990, -122.4395)]),
    ("Masonic Ave",              0.72, 2.61, [(37.7660, -122.4460), (37.7790, -122.4465), (37.7880, -122.4460)]),
    ("Broadway",                 0.72, 3.14, [(37.7975, -122.4230), (37.7980, -122.4090), (37.7985, -122.4000)]),
    ("Guerrero St",              0.70, 0.00, [(37.7500, -122.4235), (37.7640, -122.4235), (37.7700, -122.4240)]),
    ("Ocean Ave",                0.70, 1.28, [(37.7245, -122.4680), (37.7250, -122.4460), (37.7280, -122.4340)]),
    ("Geneva Ave",               0.70, 0.00, [(37.7120, -122.4560), (37.7175, -122.4400), (37.7215, -122.4200), (37.7250, -122.4050)]),
    ("Portola Dr / O'Shaughnessy",0.70,0.79, [(37.7420, -122.4600), (37.7440, -122.4480), (37.7370, -122.4400)]),
    ("Sunset Blvd",              0.70, 0.00, [(37.7270, -122.4945), (37.7450, -122.4945), (37.7620, -122.4945)]),
    ("16th St",                  0.70, 4.97, [(37.7655, -122.4350), (37.7655, -122.4180), (37.7660, -122.3960)]),
    ("9th St / 10th St SoMa",    0.70, 3.99, [(37.7700, -122.4160), (37.7770, -122.4120), (37.7820, -122.4090)]),
    ("Fulton St",                0.68,13.47, [(37.7715, -122.5090), (37.7730, -122.4830), (37.7745, -122.4530), (37.7770, -122.4300), (37.7800, -122.4155)]),
    ("Silver Ave",               0.66, 1.98, [(37.7290, -122.4260), (37.7320, -122.4100), (37.7350, -122.4000)]),
    ("California St",            0.65, 5.36, [(37.7855, -122.4920), (37.7860, -122.4600), (37.7885, -122.4340), (37.7920, -122.4020)]),
    ("Lincoln Way",              0.65, 0.00, [(37.7655, -122.5090), (37.7655, -122.4830), (37.7655, -122.4560)]),
    ("Great Highway",            0.62, 0.00, [(37.7270, -122.5065), (37.7500, -122.5095), (37.7720, -122.5105)]),
    ("Oakdale Ave / Evans Ave",  0.62, 5.61, [(37.7380, -122.4030), (37.7360, -122.3900), (37.7430, -122.3830)]),
    ("Stockton St / Powell St",  0.62, 3.78, [(37.7855, -122.4075), (37.7955, -122.4080), (37.8020, -122.4110)]),
    ("Embarcadero",              0.60, 0.00, [(37.7900, -122.3900), (37.7990, -122.3970), (37.8070, -122.4110)]),
    ("Clement St",               0.52, 0.00, [(37.7828, -122.5060), (37.7828, -122.4800), (37.7828, -122.4600)]),
    ("Taraval St",               0.50, 1.06, [(37.7425, -122.5060), (37.7425, -122.4850), (37.7425, -122.4670)]),
    ("Irving St",                0.50, 0.00, [(37.7636, -122.5060), (37.7636, -122.4830), (37.7636, -122.4600)]),
    ("Noriega St",               0.46, 1.06, [(37.7537, -122.5060), (37.7537, -122.4850), (37.7537, -122.4700)]),
    ("Judah St",                 0.44, 0.94, [(37.7615, -122.5060), (37.7615, -122.4830), (37.7615, -122.4620)]),
    ("Marina Blvd",              0.72, 0.00, [(37.8055, -122.4480), (37.8060, -122.4330), (37.8065, -122.4230)]),
    ("Bay St / North Point",     0.70, 3.50, [(37.8035, -122.4360), (37.8045, -122.4200), (37.8060, -122.4110)]),
    ("Ingalls St / Gilman Ave",  0.66, 6.26, [(37.7250, -122.3900), (37.7180, -122.3890), (37.7130, -122.3930)]),
    ("Persia Ave / Excelsior",   0.58, 0.00, [(37.7240, -122.4330), (37.7250, -122.4200), (37.7265, -122.4100)]),
    ("Skyline Blvd",             0.60, 0.00, [(37.7080, -122.4950), (37.7220, -122.5030), (37.7340, -122.5060)]),
    ("Brotherhood Way",          0.58, 0.00, [(37.7095, -122.4700), (37.7100, -122.4600), (37.7115, -122.4530)]),
    ("Laguna Honda Blvd",        0.55, 0.00, [(37.7450, -122.4690), (37.7530, -122.4640), (37.7580, -122.4580)]),
    ("Arguello Blvd",            0.52, 0.00, [(37.7780, -122.4595), (37.7860, -122.4595), (37.7940, -122.4585)]),
]

# ---------------------------------------------------------------------------
# FREEWAYS  (ENCODED)
# Weight drives both the near-road air pollution surface and the noise surface.
# The near-road literature puts the steep decay inside ~150 m, levelling by
# ~300-500 m; build.py applies that decay curve.
# ---------------------------------------------------------------------------
FREEWAYS = [
    ("US-101 (Bayshore/Central)", 1.00, [
        (37.7080, -122.4020), (37.7180, -122.4040), (37.7320, -122.4050),
        (37.7450, -122.4060), (37.7550, -122.4075), (37.7690, -122.4110),
        (37.7725, -122.4155), (37.7735, -122.4220)]),
    ("I-280", 0.95, [
        (37.7100, -122.4550), (37.7180, -122.4480), (37.7270, -122.4290),
        (37.7350, -122.4060), (37.7450, -122.4000), (37.7580, -122.3950),
        (37.7700, -122.3945), (37.7745, -122.3985)]),
    ("I-80 / Bay Bridge approach", 1.00, [
        (37.7720, -122.4055), (37.7780, -122.3985), (37.7845, -122.3905),
        (37.7900, -122.3835)]),
]

# Freeway on-ramps with typical off-peak driving minutes to SFO  (ENCODED)
SFO_RAMPS = [
    ("101 @ Alemany/Bayshore",      37.7275, -122.4045, 14),
    ("280 @ Geneva",                37.7150, -122.4530, 15),
    ("280 @ Alemany",               37.7270, -122.4290, 16),
    ("101 @ Cesar Chavez",          37.7485, -122.4055, 17),
    ("280 @ Cesar Chavez",          37.7500, -122.3960, 18),
    ("101 @ Vermont/Mariposa",      37.7645, -122.4045, 19),
    ("280 @ 6th/Brannan",           37.7745, -122.3985, 21),
    ("101 @ Octavia/Market",        37.7735, -122.4225, 22),
    ("Junipero Serra @ 19th Ave",   37.7150, -122.4700, 20),
    ("Sloat/Skyline to 280",        37.7350, -122.4990, 25),
    ("Bay Bridge / I-80 westbound", 37.7845, -122.3905, 24),
]

# ---------------------------------------------------------------------------
# RAIL  (ENCODED)
# Each line is a list of (lat, lon, minutes_in_vehicle_to_Powell_St).
# BART stations additionally carry minutes to SFO on the SFO/Millbrae line.
# ---------------------------------------------------------------------------
RAIL_LINES = [
    ("BART Market St", "bart", [
        (37.7929, -122.3968,  4), (37.7894, -122.4014,  2),
        (37.7844, -122.4079,  0), (37.7797, -122.4137,  2)]),
    ("BART Mission", "bart", [
        (37.7650, -122.4197,  6), (37.7522, -122.4185,  8),
        (37.7330, -122.4340, 12), (37.7215, -122.4475, 15)]),
    ("Muni N Judah", "metro", [
        (37.7601, -122.5090, 35), (37.7607, -122.4940, 31), (37.7612, -122.4790, 27),
        (37.7622, -122.4665, 23), (37.7630, -122.4530, 20), (37.7690, -122.4330, 14),
        (37.7710, -122.4290, 12), (37.7752, -122.4192,  4)]),
    ("Muni L Taraval", "metro", [
        (37.7425, -122.5060, 38), (37.7425, -122.4900, 33), (37.7425, -122.4760, 28),
        (37.7402, -122.4664, 17), (37.7466, -122.4593, 14), (37.7626, -122.4350,  9)]),
    ("Muni M Ocean View", "metro", [
        (37.7215, -122.4475, 30), (37.7250, -122.4560, 28), (37.7280, -122.4750, 25),
        (37.7330, -122.4740, 23), (37.7402, -122.4664, 17), (37.7466, -122.4593, 14)]),
    ("Muni K Ingleside", "metro", [
        (37.7215, -122.4475, 27), (37.7248, -122.4560, 25), (37.7275, -122.4650, 22),
        (37.7340, -122.4680, 20), (37.7402, -122.4664, 17)]),
    ("Muni T Third / Central Subway", "metro", [
        (37.7125, -122.4045, 40), (37.7255, -122.3925, 34), (37.7370, -122.3905, 29),
        (37.7500, -122.3880, 24), (37.7580, -122.3880, 21), (37.7700, -122.3900, 17),
        (37.7760, -122.3960, 12), (37.7820, -122.4040,  5), (37.7865, -122.4065,  2)]),
    ("Muni J Church", "metro", [
        (37.7420, -122.4235, 22), (37.7513, -122.4270, 19), (37.7600, -122.4285, 15),
        (37.7673, -122.4290,  7), (37.7752, -122.4192,  4)]),
]

# BART stations that serve SFO directly: (lat, lon, minutes to SFO)
BART_TO_SFO = [
    (37.7929, -122.3968, 34), (37.7894, -122.4014, 32), (37.7844, -122.4079, 30),
    (37.7797, -122.4137, 28), (37.7650, -122.4197, 24), (37.7522, -122.4185, 22),
    (37.7330, -122.4340, 18), (37.7215, -122.4475, 15),
]

# ---------------------------------------------------------------------------
# RAPID BUS CORRIDORS  (ENCODED)
# (name, service quality 0-1, polyline of (lat, lon, minutes_to_Powell))
# Quality reflects frequency and reliability; it discounts the effective
# attractiveness of a bus-only trip relative to rail.
# ---------------------------------------------------------------------------
BUS_CORRIDORS = [
    ("38 Geary Rapid",   0.90, [(37.7800, -122.5085, 42), (37.7815, -122.4900, 36),
                                (37.7825, -122.4600, 28), (37.7845, -122.4400, 21),
                                (37.7865, -122.4200,  9), (37.7870, -122.4075,  2)]),
    ("14 Mission Rapid", 0.88, [(37.7080, -122.4400, 45), (37.7220, -122.4370, 38),
                                (37.7420, -122.4230, 28), (37.7600, -122.4190, 18),
                                (37.7760, -122.4170,  8), (37.7885, -122.4040,  3)]),
    ("5 Fulton Rapid",   0.85, [(37.7715, -122.5090, 42), (37.7730, -122.4830, 35),
                                (37.7745, -122.4530, 26), (37.7770, -122.4300, 15),
                                (37.7800, -122.4155,  5)]),
    ("1 California",     0.85, [(37.7855, -122.4920, 38), (37.7860, -122.4600, 29),
                                (37.7885, -122.4340, 18), (37.7920, -122.4020,  4)]),
    ("30 Stockton",      0.80, [(37.8005, -122.4430, 24), (37.8005, -122.4300, 19),
                                (37.7990, -122.4160, 11), (37.7880, -122.4055,  3)]),
    ("49 Van Ness",      0.80, [(37.8005, -122.4230, 17), (37.7870, -122.4215, 11),
                                (37.7735, -122.4200,  6), (37.7600, -122.4185, 14)]),
    ("22 Fillmore",      0.75, [(37.7990, -122.4380, 26), (37.7860, -122.4385, 21),
                                (37.7715, -122.4375, 18), (37.7655, -122.4180, 20)]),
    ("45 Union/Stockton",0.72, [(37.7975, -122.4360, 22), (37.7975, -122.4225, 16),
                                (37.7900, -122.4090,  6)]),
    ("9 San Bruno",      0.70, [(37.7215, -122.4030, 32), (37.7300, -122.4045, 28),
                                (37.7450, -122.4060, 21), (37.7700, -122.4110, 10)]),
    ("8 Bayshore",       0.70, [(37.7125, -122.4090, 38), (37.7300, -122.3960, 30),
                                (37.7500, -122.3960, 24), (37.7930, -122.4080,  4)]),
    ("28 19th Ave",      0.68, [(37.7215, -122.4750, 40), (37.7450, -122.4757, 36),
                                (37.7650, -122.4757, 33), (37.7900, -122.4735, 30)]),
    ("24 Divisadero",    0.65, [(37.7390, -122.4200, 30), (37.7550, -122.4350, 26),
                                (37.7715, -122.4375, 20), (37.7860, -122.4385, 22)]),
    ("29 Sunset",        0.55, [(37.7210, -122.4570, 45), (37.7420, -122.4890, 47),
                                (37.7650, -122.4830, 42), (37.7830, -122.4720, 38)]),
    ("43 Masonic",       0.62, [(37.7280, -122.4550, 38), (37.7480, -122.4520, 33),
                                (37.7660, -122.4460, 28), (37.7880, -122.4460, 26)]),
    ("44 O'Shaughnessy", 0.60, [(37.7340, -122.4340, 30), (37.7440, -122.4480, 32),
                                (37.7620, -122.4580, 34), (37.7790, -122.4680, 36)]),
    ("48 Quintara",      0.52, [(37.7480, -122.5030, 46), (37.7460, -122.4750, 42),
                                (37.7430, -122.4400, 34), (37.7500, -122.3960, 30)]),
    ("54 Felton",        0.50, [(37.7180, -122.4570, 44), (37.7280, -122.4340, 38),
                                (37.7340, -122.4030, 36)]),
]

# ---------------------------------------------------------------------------
# HOSPITALS WITH EMERGENCY DEPARTMENTS  (ENCODED)
# ---------------------------------------------------------------------------
HOSPITALS = [
    ("Zuckerberg SF General",      37.7560, -122.4050),
    ("UCSF Parnassus",             37.7630, -122.4580),
    ("UCSF Mission Bay",           37.7680, -122.3915),
    ("CPMC Van Ness",              37.7855, -122.4225),
    ("CPMC Davies",                37.7690, -122.4370),
    ("St. Mary's Medical Center",  37.7745, -122.4485),
    ("Saint Francis Memorial",     37.7885, -122.4155),
    ("Kaiser SF Geary",            37.7825, -122.4425),
    ("Chinese Hospital",           37.7960, -122.4085),
    ("SF VA Medical Center",       37.7815, -122.5035),
]

# ---------------------------------------------------------------------------
# LIQUEFACTION SUSCEPTIBILITY ZONES  (ENCODED)
# Approximated from the California Geological Survey / SF seismic hazard maps.
# (name, severity 0-1, polygon). Severity 1.0 = engineered bay fill.
# SCREENING QUALITY ONLY — a real purchase decision needs a parcel-level report.
# ---------------------------------------------------------------------------
LIQUEFACTION = [
    ("Marina / Cow Hollow fill", 1.00, [
        (-122.4470, 37.8065), (-122.4300, 37.8070), (-122.4255, 37.8020),
        (-122.4340, 37.7990), (-122.4460, 37.8000)]),
    ("Northern waterfront fill", 1.00, [
        (-122.4230, 37.8085), (-122.4030, 37.8080), (-122.3960, 37.8030),
        (-122.4050, 37.7995), (-122.4200, 37.8020)]),
    ("Financial District / Embarcadero fill", 1.00, [
        (-122.4030, 37.8030), (-122.3900, 37.7960), (-122.3855, 37.7870),
        (-122.3930, 37.7830), (-122.4010, 37.7900), (-122.4060, 37.7970)]),
    ("South Beach / SoMa east fill", 0.95, [
        (-122.3930, 37.7845), (-122.3860, 37.7790), (-122.3890, 37.7715),
        (-122.4010, 37.7745), (-122.4030, 37.7810)]),
    ("Mission Bay / Mission Creek fill", 1.00, [
        (-122.4010, 37.7770), (-122.3880, 37.7720), (-122.3890, 37.7640),
        (-122.4020, 37.7655), (-122.4060, 37.7720)]),
    ("SoMa west / old marsh", 0.75, [
        (-122.4180, 37.7810), (-122.4030, 37.7830), (-122.4010, 37.7735),
        (-122.4160, 37.7715)]),
    ("Mission District creek bed", 0.70, [
        (-122.4260, 37.7730), (-122.4110, 37.7700), (-122.4120, 37.7570),
        (-122.4250, 37.7600)]),
    ("Islais Creek / Bayview flats", 0.95, [
        (-122.4020, 37.7520), (-122.3850, 37.7480), (-122.3830, 37.7370),
        (-122.4010, 37.7400)]),
    ("Hunters Point / Candlestick fill", 1.00, [
        (-122.3900, 37.7360), (-122.3700, 37.7300), (-122.3730, 37.7130),
        (-122.3930, 37.7180)]),
    ("Treasure Island fill", 1.00, [
        (-122.3760, 37.8010), (-122.3630, 37.8010), (-122.3610, 37.8280),
        (-122.3730, 37.8290)]),
    ("Visitacion / Sunnydale creek", 0.65, [
        (-122.4160, 37.7205), (-122.4020, 37.7175), (-122.4040, 37.7095),
        (-122.4170, 37.7120)]),
    ("Lake Merced margins", 0.60, [
        (-122.4980, 37.7300), (-122.4820, 37.7270), (-122.4830, 37.7145),
        (-122.4990, 37.7175)]),
    ("Ocean Beach dune sand", 0.55, [
        (-122.5120, 37.7760), (-122.5020, 37.7755), (-122.5030, 37.7270),
        (-122.5125, 37.7280)]),
    ("Crissy Field / Presidio shore", 0.90, [
        (-122.4720, 37.8085), (-122.4520, 37.8065), (-122.4540, 37.7995),
        (-122.4700, 37.8010)]),
]

# ---------------------------------------------------------------------------
# KNOWN PLUVIAL FLOOD HOTSPOTS  (ENCODED)
# SF's combined sewer backs up in the old creek beds and topographic bowls.
# build.py combines these with a DERIVED topographic-depression term.
# (name, severity 0-1, lat, lon, radius_m)
# ---------------------------------------------------------------------------
FLOOD_HOTSPOTS = [
    ("Folsom/17th–Mission bowl",  1.00, 37.7645, -122.4160, 550),
    ("Cayuga / Alemany bowl",     0.90, 37.7245, -122.4360, 500),
    ("West Portal / Sloat bowl",  0.85, 37.7395, -122.4665, 450),
    ("15th & Wawona / Laguna Honda", 0.70, 37.7440, -122.4680, 350),
    ("Islais Creek / Alemany",    0.80, 37.7370, -122.4090, 500),
    ("Lower Haight / Duboce",     0.65, 37.7690, -122.4300, 350),
    ("Yosemite / Bayview flats",  0.75, 37.7325, -122.3970, 450),
    ("Sunnydale / Visitacion",    0.70, 37.7130, -122.4110, 400),
    ("Cesar Chavez / Bryant",     0.70, 37.7495, -122.4110, 400),
    ("Ocean/Phelan (CCSF)",       0.60, 37.7255, -122.4520, 350),
]

# ---------------------------------------------------------------------------
# MICROCLIMATE / FOG MODEL  (ENCODED)
# SF's fog gradient is the single largest daily-quality-of-life differentiator
# and runs mostly west-to-east, sharply modulated by the Twin Peaks ridge,
# which shelters the Mission/Bernal "banana belt", and by the Golden Gate gap,
# which funnels marine air inland across the northern waterfront.
# ---------------------------------------------------------------------------
FOG = {
    "west_edge_lon": -122.5130,   # Pacific shore reference
    "decay_deg": 0.0400,          # e-folding scale of fog influence eastward
    "ridge_lon": -122.4470,       # Twin Peaks / Mt Sutro / Mt Davidson spine
    "lee_bonus": 0.16,            # extra sun east of the ridge in its lee
    "lee_lat_range": (37.7330, 37.7790),
    "gate_penalty": 0.13,         # marine funnel across the northern edge
    "gate_lat": 37.7960,
    "coast_penalty": 0.10,        # direct exposure within ~1 km of open ocean
    "coast_lon": -122.4960,
}

# ---------------------------------------------------------------------------
# ROAD TRAFFIC VOLUME  —  vehicles per day
#
# Emission and noise strength scale with volume, so exposure weight is derived
# as AADT/100,000 rather than from the hand-set 0-1 weights above (which are
# retained only for basemap line thickness).
#
# "caltrans" values are MEASURED: Caltrans 2023 Traffic Volumes AADT, San
# Francisco County, via the CHhighway/Traffic_AADT feature service. Where a
# route varies along its length the through-volume at the heaviest count
# location in the city is used.
#
# NOTE — a real correction from this data: 19th Ave is commonly cited at
# 90-110k vehicles/day, but Caltrans puts 19th Ave proper (Winston Dr to Lake
# St) at 61-69k. The 85-94k readings are on Junipero Serra south of it. The
# earlier hand-set weight of 1.00 for 19th Ave, equal to the Bay Bridge, was
# roughly 3.5x too high.
#
# "est" values are ESTIMATED: Caltrans has no jurisdiction over city arterials
# and DataSF publishes no vehicle counts, so these are banded by road role
# (major arterial / arterial / collector / commercial street) and are not
# precise figures. They are deliberately given round numbers to signal that.
# ---------------------------------------------------------------------------
ROAD_AADT = {
    # --- freeways: MEASURED, Caltrans 2023 ---
    "I-80 / Bay Bridge approach":  (236000, "caltrans"),
    "US-101 (Bayshore/Central)":   (225000, "caltrans"),
    "I-280":                       (168000, "caltrans"),
    # --- state routes: MEASURED, Caltrans 2023 ---
    "19th Ave / Park Presidio":     (69000, "caltrans"),
    "Junipero Serra Blvd":          (94000, "caltrans"),
    "Skyline Blvd":                 (33500, "caltrans"),
    "Brotherhood Way":              (89000, "caltrans"),
    "Van Ness Ave":                 (45000, "caltrans"),
    "Lombard St (US-101)":          (50000, "caltrans"),
    "Bayshore Blvd":                (28000, "caltrans"),
    # --- city arterials: ESTIMATED, banded by role ---
    "Geary Blvd / Geary St":        (45000, "est"),
    "Mission St":                   (30000, "est"),
    "Market St":                    (25000, "est"),
    "Fell St / Oak St":             (40000, "est"),
    "Franklin St / Gough St":       (40000, "est"),
    "Cesar Chavez St":              (32000, "est"),
    "Harrison St / Bryant St":      (35000, "est"),
    "Potrero Ave":                  (30000, "est"),
    "Sloat Blvd":                   (30000, "est"),
    "Alemany Blvd":                 (32000, "est"),
    "South Van Ness Ave":           (28000, "est"),
    "Folsom St / Howard St":        (28000, "est"),
    "3rd St":                       (25000, "est"),
    "Bush St / Pine St":            (25000, "est"),
    "San Jose Ave":                 (25000, "est"),
    "7th St / 8th St SoMa":         (25000, "est"),
    "9th St / 10th St SoMa":        (25000, "est"),
    "Columbus Ave":                 (20000, "est"),
    "Divisadero St / Castro":       (22000, "est"),
    "Masonic Ave":                  (22000, "est"),
    "Broadway":                     (20000, "est"),
    "Guerrero St":                  (20000, "est"),
    "Ocean Ave":                    (20000, "est"),
    "Geneva Ave":                   (20000, "est"),
    "Portola Dr / O'Shaughnessy":   (22000, "est"),
    "Sunset Blvd":                  (22000, "est"),
    "16th St":                      (20000, "est"),
    "Fulton St":                    (18000, "est"),
    "Silver Ave":                   (16000, "est"),
    "California St":                (16000, "est"),
    "Lincoln Way":                  (16000, "est"),
    "Great Highway":                (14000, "est"),
    "Oakdale Ave / Evans Ave":      (15000, "est"),
    "Stockton St / Powell St":      (15000, "est"),
    "Embarcadero":                  (15000, "est"),
    "Marina Blvd":                  (18000, "est"),
    "Bay St / North Point":         (16000, "est"),
    "Ingalls St / Gilman Ave":      (12000, "est"),
    "Persia Ave / Excelsior":       (11000, "est"),
    "Laguna Honda Blvd":            (13000, "est"),
    "Arguello Blvd":                (12000, "est"),
    "Clement St":                   (11000, "est"),
    "Taraval St":                    (9000, "est"),
    "Irving St":                     (9000, "est"),
    "Noriega St":                    (8000, "est"),
    "Judah St":                      (8000, "est"),
}

# ---------------------------------------------------------------------------
# FACTOR REGISTRY
# Drives the UI: label, group, provenance badge, default weight, and whether a
# high raw value is good (+1) or bad (-1). Defaults lean toward the user's
# stated priorities; every weight is adjustable live in the map.
# ---------------------------------------------------------------------------
FACTORS = [
    # key, label, group, provenance, default weight, native resolution, source note
    ("air", "Air quality", "Environment", "DERIVED", 9, "corridor",
     "Near-road decay from real road geometry; emission strength from Caltrans 2023 AADT on state routes, banded estimates on city arterials."),
    ("noise", "Quiet (low noise)", "Environment", "DERIVED", 8, "corridor",
     "Same road model as air quality, plus a term for commercial-corridor activity."),
    ("microclimate", "Sun vs. fog", "Environment", "ENCODED", 6, "model",
     "Analytic fog model: west-to-east gradient, Twin Peaks lee bonus, Golden Gate marine funnel. No measured fog raster was obtainable."),
    ("slope", "Flat terrain", "Environment", "MEASURED", 4, "1 m DEM",
     "Gradient computed from the USGS 3DEP 1-metre elevation model."),
    ("liquefaction", "Liquefaction safety", "Hazards", "MEASURED", 7, "regulatory zone",
     "California Geological Survey regulatory Seismic Hazard Zone for liquefaction — the statutory Zone of Required Investigation. Binary in/out, not graded susceptibility."),
    ("tsunami", "Tsunami safety", "Hazards", "MEASURED", 4, "inundation model",
     "CGS / Cal OES Tsunami Hazard Area, maximum-considered tsunami, roughly 975-year return period."),
    ("slr", "Sea level rise safety", "Hazards", "DERIVED", 6, "1 m DEM",
     "Elevation and distance-to-shore from the 1 m DEM. The published BCDC 66-inch layer could not be retrieved; this is the same method those layers use."),
    ("flood", "Flood safety", "Hazards", "DERIVED", 4, "1 m DEM + hotspots",
     "Topographic sink detection on the 1 m DEM, plus encoded known combined-sewer flood hotspots."),
    ("landslide", "Landslide safety", "Hazards", "DERIVED", 3, "1 m DEM",
     "Slope-threshold model on the 1 m DEM. Soil and colluvium are not factored in."),
    ("transit_dt", "Transit to downtown", "Access", "ENCODED", 9, "corridor",
     "Walk time to the nearest rail stop or rapid bus corridor plus encoded in-vehicle minutes to Powell St. No routing engine or GTFS feed was reachable, so treat as plus or minus 5 minutes."),
    ("transit_sfo", "Transit to SFO", "Access", "ENCODED", 4, "corridor",
     "Best of walking to a BART station on the SFO line, or riding to the Market St corridor and transferring."),
    ("drive_sfo", "Drive to SFO", "Access", "ENCODED", 3, "corridor",
     "Surface-street time to the nearest freeway ramp plus encoded ramp-to-airport minutes."),
    ("walkability", "Walkability", "Access", "MEASURED", 8, "point",
     "Distance-weighted density of 4,289 active businesses by NAICS code. Computed the way Walk Score works rather than copied from it."),
    ("bikeability", "Bikeability", "Access", "DERIVED", 5, "1 m DEM + point",
     "Real slope against errand density, penalised by proximity to the high-injury network."),
    ("transit_score", "Transit stop access", "Access", "MEASURED", 6, "point",
     "3,260 real SFMTA stop locations plus the 8 SF BART stations. The dataset carries no route or mode field, so all Muni stops are weighted equally."),
    ("street_calm", "Quiet streets", "Streets", "DERIVED", 7, "corridor",
     "Traffic-volume-weighted road proximity. Fronting one big arterial is penalised separately from being ringed by several."),
    ("ped_safety", "Pedestrian safety", "Streets", "MEASURED", 6, "corridor",
     "Proximity to SFMTA's 2024 Vision Zero High Injury Network, weighted by each corridor's injury mileage."),
    ("supermarket_walk", "Supermarket — walkable", "Daily life", "ENCODED", 7, "point",
     "Distance to a full-size supermarket on a walking decay: strong inside 500 m, gone past roughly 1.2 km."),
    ("supermarket_drive", "Supermarket — 5 min drive", "Daily life", "ENCODED", 5, "point",
     "Whether a full-size supermarket is inside an estimated 5-minute drive, modelled at city surface-street speeds. Estimated: no routing engine was available."),
    ("corner_store", "Corner store within 2 blocks", "Daily life", "MEASURED", 5, "point",
     "Density of convenience stores and small grocers within about 250 m, roughly two SF blocks."),
    ("parks", "Park proximity", "Daily life", "MEASURED", 8, "polygon",
     "242 parks: 219 city Rec & Parks properties plus 23 federal and state units from the California Protected Areas Database. Measured to the park boundary, not its centroid. 65% distance to the nearest park, 35% weighted parkland abundance."),
    ("food_nightlife", "Food & nightlife", "Daily life", "MEASURED", 7, "point",
     "3,347 restaurants and 396 bars, distance-weighted. Counted as a positive."),
    ("crime_violent", "Low violent crime", "Safety", "MEASURED", 7, "neighbourhood",
     "Two years of SFPD incident reports, area-normalised and smoothed between neighbourhood centroids. Native resolution is 41 areas, not 200 m."),
    ("crime_property", "Low property crime", "Safety", "MEASURED", 5, "neighbourhood",
     "Same source and the same 41-area resolution caveat."),
    ("street_cond", "Street cleanliness (311)", "Safety", "MEASURED", 5, "neighbourhood",
     "One year of 311 street-condition cases — encampments, cleaning, graffiti, illegal postings. 41-area resolution."),
    ("schools", "School proximity", "Family", "MEASURED", 3, "point",
     "126 public schools. Weighted low on purpose: SFUSD still runs citywide choice with an attendance-area tiebreaker."),
    ("playgrounds", "Playground proximity", "Family", "MEASURED", 4, "polygon",
     "Playgrounds and neighbourhood parks, separated from regional open space."),
    ("library", "Library proximity", "Family", "MEASURED", 2, "point",
     "28 SFPL branches."),
    ("hospital", "Hospital / ER proximity", "Family", "ENCODED", 2, "point",
     "10 hospitals with emergency departments, hand-encoded."),
]
