# Data sources Every value on the map comes from the public datasets below. Nothing is estimated or filled in: if a source has no value for a county, the app shows "no data" and leaves that county out of the top 5 when you've weighted that layer. Processing: `scripts/build_data.py`, then `scripts/counties_geojson.mjs`, `scripts/build_layers_v2.py` and `scripts/build_layers_v3.py`, produce `data/counties.json` and `data/state_tax.json` (also copied to `public/data/`). | Layer / field | Source | Vintage | URL | |---|---|---|---| | County boundaries | us-atlas v3.0.1 (Census Bureau cartographic boundary files, 1:10m) | 2017 boundaries | https://cdn.jsdelivr.net/npm/us-atlas@3.0.1/counties-10m.json | | Median gross rent (`rent`) | US Census Bureau, American Community Survey 5-year, table B25064 (table-based summary file) | 2019–2023 | https://www2.census.gov/programs-surveys/acs/summary_file/2023/table-based-SF/data/5YRData/acsdt5y2023-b25064.dat | | Median household income (`inc`) | ACS 5-year, table B19013 | 2019–2023 | https://www2.census.gov/programs-surveys/acs/summary_file/2023/table-based-SF/data/5YRData/acsdt5y2023-b19013.dat | | Households with broadband of any type (`bb`) = B28002_004 ÷ B28002_001 | ACS 5-year, table B28002 | 2019–2023 | https://www2.census.gov/programs-surveys/acs/summary_file/2023/table-based-SF/data/5YRData/acsdt5y2023-b28002.dat | | Connecticut rent / income / broadband | ACS 5-year 2017–2021 (the last release using CT's 8 legacy counties; 2022+ uses planning regions that don't match the map's boundaries). Labeled per-county in the app. | 2017–2021 | https://www2.census.gov/programs-surveys/acs/summary_file/2021/table-based-SF/data/5YRData/ | | Avg summer high (`tmax`) = mean of Jun/Jul/Aug monthly mean max temp, 1991–2020 | NOAA NCEI nClimDiv county dataset (`climdiv-tmaxcy-v1.0.0-20261006`) | 1991–2020 avg | https://www.ncei.noaa.gov/monitoring-content/data/us/climdiv/monthly/current/ | | Avg winter low (`tmin`) = mean of Dec/Jan/Feb monthly mean min temp, 1991–2020 | NOAA NCEI nClimDiv (`climdiv-tmincy-v1.0.0-20261006`) | 1991–2020 avg | same as above | | Disaster expected annual loss rate, national percentile (`alr` = `ALR_NPCTL`), overall risk score/rating (`risk`, `riskR`), per-hazard risk ratings (hurricane, wildfire, inland flooding, coastal flooding, tornado, earthquake), population (`pop`) | FEMA National Risk Index, county table | v1.20, December 2025 | https://www.fema.gov/about/reports-and-data/openfema/nri/v120/NRI_Table_Counties.zip | | Median home value (`hv`) | ACS 5-year, table B25077 (CT: 2017–2021) | 2019–2023 | https://www2.census.gov/programs-surveys/acs/summary_file/2023/table-based-SF/data/5YRData/acsdt5y2023-b25077.dat | | Summer dew point (`dew`) = mean of the Jun, Jul and Aug 30-year normal mean dew point grids, averaged over the 4 km cells inside each county (cells touching the county for tiny counties), °C converted to °F | PRISM Climate Group, Oregon State University, 30-year normals `tdmean`, 4 km (`prism_tdmean_us_25m_2020{06,07,08}_avg_30y`) | 1991–2020 normals | https://data.prism.oregonstate.edu/normals/us/4km/tdmean/monthly/ | | Annual snowfall (`snow`) = `ANN-SNOW-NORMAL` (inches) averaged over the NOAA stations inside the county. If none, the nearest station within 40 km (station name and distance shown in the app). Trace values count as 0. | NOAA NCEI U.S. Climate Normals, annual/seasonal, by station (v1.0.1) | 1991–2020 normals | https://www.ncei.noaa.gov/data/normals-annualseasonal/1991-2020/archive/us-climate-normals_1991-2020_v1.0.1_annualseasonal_multivariate_by-station_c20230404.tar.gz | | Jobs in your field (`j`): annual average employment summed over all ownerships (federal, state, local, private), and location quotient = (county industry jobs ÷ county total covered jobs) ÷ (same ratio for the US) | BLS Quarterly Census of Employment and Wages (QCEW) open data API, 2025 annual averages. NAICS 21, 22, 31-33, 51, 52, 54, 5415, 61, 62; totals from industry 10 | 2025 | https://data.bls.gov/cew/data/api/2025/a/industry/{code}.csv | | Avg weekly pay in your field (`j[...][2]`) = QCEW total annual wages ÷ annual average employment ÷ 52, summed over the disclosed ownerships. If BLS withholds the industry, the app uses the county's all-industry average weekly wage (`wAll`, industry 10, all ownerships) and marks the county "partial". | BLS QCEW open data API, 2025 annual averages | 2025 | https://data.bls.gov/cew/data/api/2025/a/industry/{code}.csv | | Average commute to work (`com`) = B08013_001 (aggregate travel time to work, minutes) ÷ B08303_001 (workers 16+ who did not work from home) | ACS 5-year (CT: 2017–2021, as with the other ACS fields) | 2019–2023 | https://www2.census.gov/programs-surveys/acs/summary_file/2023/table-based-SF/data/5YRData/acsdt5y2023-b08013.dat and `...-b08303.dat` | | Nearest ski area (`skiMi`, `skiNm`) = great-circle miles from the county's 2020 center of population to the nearest ski area. A ski area is (a) a named OSM `landuse=winter_sports` feature with at least one ski lift (`aerialway` = chair_lift, gondola, t-bar, platter, drag_lift, j-bar, rope_tow, magic_carpet, mixed_lift) within 5 km, or (b) a cluster of 2+ named lifts within 2 km that isn't near a named area (shown as "unnamed ski area (N OSM-mapped lifts)"). Abandoned/disused lifts and water-ski, wake and water-park cables are dropped. 551 ski areas; list in `data/ski_areas.json`. | © OpenStreetMap contributors, Open Database License (ODbL) 1.0, via the Overpass API (downloaded Nov 8, 2026) | Nov 2026 snapshot | https://www.openstreetmap.org/copyright, https://overpass-api.de/ | | Terrain relief (`rel`, feet) = 98th percentile minus 2nd percentile elevation of all DEM cells within 50 km of the county's 2020 center of population (percentiles rather than max/min so a single tower or bad pixel can't set the value) | USGS 3D Elevation Program (3DEP) seamless DEM, resampled by USGS's 3DEPElevation ImageServer to a 0.01° grid (≈1 km) in EPSG:4326; four exports (CONUS west, CONUS east, Alaska at 0.02°, Hawaii). Cells below −90 m treated as no data. Public domain. | Fetched Nov 8, 2026 (3DEP seamless, current) | https://elevation.nationalmap.gov/arcgis/rest/services/3DEPElevation/ImageServer/exportImage | | County centers of population (for ski distance and terrain) | US Census Bureau, 2020 Centers of Population by County (1 county without one, Valdez-Cordova AK, uses its polygon's interior point) | 2020 | https://www2.census.gov/geo/docs/reference/cenpop2020/county/CenPop2020_Mean_CO.txt | | State income tax brackets (single filer) | Tax Foundation, "2026 State Income Tax Rates and Brackets" (rates as of Jan 1, 2026) | 2026 | https://taxfoundation.org/data/all/state/state-income-tax-rates-2026/ | ## Method notes - **Rent vs income** = county median gross rent × 12 ÷ the income you enter. - **State income tax** = the single-filer marginal rate for the bracket your gross income falls in (ignores deductions, credits and local income taxes such as NYC or Ohio municipal taxes). Washington is set to 0% because the Tax Foundation table notes it taxes capital gains only, not wages. - **Disaster loss** uses FEMA's Expected Annual Loss *rate* percentile (loss relative to the value exposed), not the overall Risk Index score, because the overall score scales with how much property a county has, which makes every big metro look "very high risk". - **Fit score** (0–100) = weighted average of per-layer scores: rent 10%→1, 40%→0 of income; summer high 72°F→1, 100°F→0; winter low 40°F→1, 0°F→0; loss-rate percentile 0→1, 100→0; broadband 95%→1, 60%→0; state rate 0%→1, 10%→0. Map colors show your rank among counties still in play. - **Home prices** = median home value ÷ your income (2× → 1, 6× → 0). The dealbreaker is a dollar cap on the county median. - **Winter cold** and **snowfall** each have a direction. Winters: mild (40°F lows → 1, 0°F → 0) or cold (−10°F → 1, 30°F → 0). Snow: less (0 in → 1, 60 in → 0) or more (80+ in → 1, 0 in → 0). - **Humidity** = summer dew point: 50°F → 1, 70°F → 0. - **Jobs** score = 0.6 × location-quotient part (LQ 0.25 → 0, 4 → 1, on a log scale) + 0.4 × job-count part (1 → 0, 100,000 → 1, on a log scale). The dealbreaker is a minimum job count. When BLS suppresses every ownership type for a county, it shows "suppressed" and is treated as missing. When only some are suppressed, the count is a minimum (shown with "+"). A county with no row in the QCEW file has 0 covered jobs in that industry. - **Pay** score: $700/wk → 0, $2,500/wk → 1 (linear). The dealbreaker is a minimum weekly pay. **Ski** score: 0 mi → 1, 150+ mi → 0. **Commute** score: 15 min → 1, 40 min → 0. - **Terrain** score = log(relief ÷ 200 ft) ÷ log(25), clamped: 200 ft or less → 0, 5,000 ft or more → 1. The dealbreaker is a minimum relief (default 2,000 ft). The AI uses terrain for "mountains / hiking / hills" and ski distance only for skiing. Examples: Eagle CO 5,388 ft, Harris TX 202 ft, Miami-Dade FL 10 ft. - **AI daily cap:** the AI box is capped at 35 runs per UTC day for the whole site (plus 30 per visitor per hour). One run is two `@cf/google/gemma-4-26b-a4b-it` calls (9,091 neurons per million input tokens, 27,273 per million output). A typical run is a few dozen neurons, so 35 runs stays well under the 10,000 free neurons per day. The counter is a SQLite Durable Object (Worker `whereshouldimove-cap`, free plan), which counts reliably; KV was tried first but its cached reads let it overcount. When the cap is hit the box says so and the sliders keep working. - **Share:** "Share image" draws a 1200×630 PNG in the browser from the current map, top 5 and title. "Copy link" puts every setting in the URL hash, so the link reopens the same map. - **Not used:** Zillow ZHVI. ACS B25077 covers every county, and I didn't want to redistribute Zillow data without checking their terms. ## Known gaps - Terrain: relief is measured around the population center, so a county with a big range at its far edge can score low. Hawaii uses the island chain's mean center for some counties. A ≈1 km grid smooths out small cliffs. - Ski areas: OSM is volunteer-mapped. Some small hills are missing or only appear as unnamed lift clusters, and some nordic-only centers are left out because they have no lifts. Distances are straight-line, not driving. - Connecticut: no FEMA NRI values (NRI v1.20 uses CT planning regions, not the 8 legacy counties on this map). - Valdez-Cordova, AK (split in 2019), Lexington city, VA and DC: missing in one or more source files. - Hawaii: not covered by nClimDiv temperature data. Alaska and Hawaii: not covered by the PRISM CONUS dew point grid. - Snowfall: 61 counties have no NOAA station normal within 40 km ("no data"). - QCEW 2025 annual averages are the latest BLS release. Small counties are often suppressed for single industries, oil & gas especially.