← back to Nationalrealestate
TK-16: add next CA ring — Santa Barbara (06083) + Imperial (06025) + San Bernardino (06071) — pass 8
25d8509c4fd653d84892a6710dec3f9fe6e9dd5b · 2026-08-10 15:58:14 -0700 · Steve Abrams
Radiating out from LA. All COVERAGE-only (AB-1785, priced=0):
- Santa Barbara 06083: 132,504 parcels, richest roll (situs+use text+value+yr/sqft/beds/baths+owner),
lat/lng via geometry+centroid, OID=OBJECTID_1, maxRC 1000.
- Imperial 06025: 88,170, explicit Longitude/Latitude, situs+use code+Land/Imp (string) value, OID=FID.
- San Bernardino 06071: ~839,795 (largest CA county), no situs, comma-string values (anyPrice strips),
owner redacted->null, lat/lng via centroid, maxRC 1000.
Verified e2e vs local usre (2000 each): 100% lat/lng all three, values/owners populated as designed
(06071 owners all redacted->0 by filter; comma-values parsed), priced=0. tsc clean (my files).
Local master, NOT pushed; ring deploy is batched per cadence.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M SOURCES.mdM src/ingest/parcels/arcgis_sales.tsM src/ingest/parcels/engine.tsM src/jobs/hourly_loop.ts
Diff
commit 25d8509c4fd653d84892a6710dec3f9fe6e9dd5b
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Aug 10 15:58:14 2026 -0700
TK-16: add next CA ring — Santa Barbara (06083) + Imperial (06025) + San Bernardino (06071) — pass 8
Radiating out from LA. All COVERAGE-only (AB-1785, priced=0):
- Santa Barbara 06083: 132,504 parcels, richest roll (situs+use text+value+yr/sqft/beds/baths+owner),
lat/lng via geometry+centroid, OID=OBJECTID_1, maxRC 1000.
- Imperial 06025: 88,170, explicit Longitude/Latitude, situs+use code+Land/Imp (string) value, OID=FID.
- San Bernardino 06071: ~839,795 (largest CA county), no situs, comma-string values (anyPrice strips),
owner redacted->null, lat/lng via centroid, maxRC 1000.
Verified e2e vs local usre (2000 each): 100% lat/lng all three, values/owners populated as designed
(06071 owners all redacted->0 by filter; comma-values parsed), priced=0. tsc clean (my files).
Local master, NOT pushed; ring deploy is batched per cadence.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
SOURCES.md | 8 +++++-
src/ingest/parcels/arcgis_sales.ts | 54 ++++++++++++++++++++++++++++++++++++++
src/ingest/parcels/engine.ts | 3 +++
src/jobs/hourly_loop.ts | 3 +++
4 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/SOURCES.md b/SOURCES.md
index 8e58248..4e489da 100644
--- a/SOURCES.md
+++ b/SOURCES.md
@@ -108,7 +108,7 @@ incl. 8 gated/blocked states → `BROKER-COVERAGE.md`. Adapters: `src/ingest/bro
## Free priced-DEED feeds — config-driven ArcGIS (`src/ingest/parcels/arcgis_sales.ts`)
-Each entry is a keyless ArcGIS REST layer that publishes real recorded SALE PRICE; one `SOURCES` config maps a page of features → parcel row + `parcel_event(event_type='sale')` with grantor/grantee/doc + a `source_url` deep-link. Registered in `parcel_source`, paginated over time by the hourly loop (`src/jobs/hourly_loop.ts`, `runSources` = the config's `cursorKey`). Live configs: `oregon-rlis` (41051/67/05), `spokane` (53063), `alameda` (06001), `deschutes` (41017), `crook` (41013), `sonoma` (06097), `colorado` (statewide composite `08*`), `maricopa` (04013), `thurston` (53067), `palm-beach` (12099), `klamath` (41035), `marion` (41047), `yakima` (53077), `lane` (41039), `jackson` (41029), `orange-county` (06059, coverage-only — AB-1785, no price), `ventura-county` (06111, coverage-only — address).
+Each entry is a keyless ArcGIS REST layer that publishes real recorded SALE PRICE; one `SOURCES` config maps a page of features → parcel row + `parcel_event(event_type='sale')` with grantor/grantee/doc + a `source_url` deep-link. Registered in `parcel_source`, paginated over time by the hourly loop (`src/jobs/hourly_loop.ts`, `runSources` = the config's `cursorKey`). Live configs: `oregon-rlis` (41051/67/05), `spokane` (53063), `alameda` (06001), `deschutes` (41017), `crook` (41013), `sonoma` (06097), `colorado` (statewide composite `08*`), `maricopa` (04013), `thurston` (53067), `palm-beach` (12099), `klamath` (41035), `marion` (41047), `yakima` (53077), `lane` (41039), `jackson` (41029), `orange-county` (06059, coverage-only — AB-1785, no price), `ventura-county` (06111, coverage-only — address), `santa-barbara` (06083, coverage), `imperial` (06025, coverage), `san-bernardino` (06071, coverage).
- **Klamath County OR (41035)** — added 2026-07-27 (TK-16). ArcGIS Online FeatureServer `https://services.arcgis.com/H6Mh1bySxR4oHx6x/arcgis/rest/services/KC_ParcelSales/FeatureServer/0` (item `f6314b12b8cc4c35899157172601bf59`, "KC_ParcelSales" = Klamath County Parcel Sales). `where=SALE_PRICE>1000` → **38,796** priced sales. Rich fields: `SALE_PRICE` (int), `SALE_DATE` (epoch-ms), `OWNER_NAME` (→ grantee), `MIN_SITUS_ADDRESS`+`FIRST_CITY_NAME`, `SUM_FINSQFT`/`SUM_BEDRMS`/`SUM_BATH`, `MIN_YRBLT`, `SUM_Tot_Appr` (total appraised → `total_value`), `SALEBK` (→ doc_number, internal double-spaces collapsed by `clean()`), `FIRST_PROP_ID` (→ apn/source_id), `FIRST_PCLCD` (→ use_desc). Server caps pages at 1000. Verified end-to-end against the local `usre` DB (1,000 parcels + 1,000 sale events + links + source registration on first batch).
@@ -123,3 +123,9 @@ Each entry is a keyless ArcGIS REST layer that publishes real recorded SALE PRIC
- **Orange County CA (06059)** — added 2026-08-10 (TK-16, pass 6; first of the "all California, radiating from LA" sweep). OC Public Works ArcGIS `https://ocgis.com/arcpub/rest/services/LegalLotsAttributeOpenData/FeatureServer/0`, **~982,299** parcels. **COVERAGE-ONLY** — CA **AB-1785** suppresses recorded sale price, so like `la-county`/`san-diego-sandag` this config carries NO price/sale-events (`priced=0`); it ingests address + assessed value + centroid lat/lng. Fields: `AssessmentNo` (→ apn/source_id — NOT `LegalLotID`, which repeats across condo units), `SiteAddress`, `SiteCityState` (→ city), `SiteZip5`, `LandVal`/`ImprovedVal`/`AssdAmt` (all `esriFieldTypeString` holding numbers — `num()` parses; `total_value = AssdAmt || LandVal+ImprovedVal` since `AssdAmt` is often null on condo units), `GPLU_DESC`/`ZC_DESCR` (use — almost entirely null, ~1.5k of 982k). lat/lng via the new `centroid:true` Source flag → `returnCentroid=true&outSR=4326` (reads `f.centroid.{x,y}`; native SR is CA State Plane VI feet, so `outSR=4326` is required), which avoids downloading ~982k polygons. `maxRecordCount=2000` (pageSize matched). Verified end-to-end against the local `usre` DB; `tsc` clean.
- **Ventura County CA (06111)** — added 2026-08-10 (TK-16, pass 7; LA-adjacent ring). `https://maps.ventura.org/arcgis/rest/services/DataDownloads/Address/MapServer/0` (HTTPS only — HTTP 301-redirects), **299,739** rows, 100% apn. **COVERAGE-ONLY** — AB-1785 (no price) AND Ventura's public REST exposes no value or characteristics: this is situs-ADDRESS coverage (like `santa-clara`). Fields: `apn` (→ source_id), `fullsitus` (→ address), `city`, `zip`. `maxRecordCount=2000`; the layer's `objectIdField` is declared `None` but `orderByFields=objectid` + `resultOffset` paging works. lat/lng lives on a SEPARATE apn-keyed layer (`DataDownloads/CommonData/MapServer/2` has explicit `lat`/`lon`) — a future join enhancement (the one-layer-per-source engine can't join mid-pass). Verified end-to-end against the local `usre` DB; `tsc` clean.
+
+The next ring out from LA (pass 8, all COVERAGE-only — AB-1785, no price/events):
+
+- **Santa Barbara County CA (06083)** — `https://maps.calagpermits.org/arcgis/rest/services/SantaBarbara/Parcels/MapServer/0`, **132,504** parcels. The richest CA roll: `APN`, `Situs1` (→ address), `SCity`, `SZip`, `LandUse` (text use-desc), `Net_AV` (→ total_value), `YearBuilt`/`SqFootage`/`Bedrooms`/`Bathrooms` (blank as `' '`/`0` on commercial → `num()` nulls), `Owner` (→ owner_name). OID field is `OBJECTID_1`; `maxRecordCount=1000`. lat/lng via `geometry:true` + ring `centroid()` (returnCentroid NOT honored; native SR 3310, `outSR=4326`).
+- **Imperial County CA (06025)** — `https://services7.arcgis.com/RomaVqqozKczDNgd/ArcGIS/rest/services/Parcels_Oct_2023/FeatureServer/0` (the `Parcels_Default_2026` sibling is a 253-row tax-default subset — do NOT use), **88,170** parcels. Explicit `Longitude`/`Latitude` fields (cleanest lat/lng, `geometry:false`). `APN`, `F_Situs1` (→ address), `Sit_Zip`, `LandUse1` (assessor code only), `Land`/`Imp_` (STRING → `anyPrice()` parses; summed → total_value), `Assessee` (→ owner_name). OID field is `FID`; `maxRecordCount=2000`.
+- **San Bernardino County CA (06071)** — `https://services.arcgis.com/aA3snZwJfFkVyDuP/arcgis/rest/services/Parcels_for_San_Bernardino_County/FeatureServer/0`, **~839,795** parcels (largest CA county by area — big coverage win). NO situs address on this roll. `ParcelNumber` (→ apn), `AssessClass` (→ use_desc), `LandValue`/`ImprovementValue` (COMMA-formatted strings `'42,345'` → `anyPrice()` strips commas; plain `Number()` yields NaN — summed → total_value), `OwnerName` (mostly redacted `"Protected Per CA Gov Code 7928.205"` → filtered to null). `maxRecordCount=1000`; lat/lng via `geometry:true` + ring `centroid()`. All three verified end-to-end against the local `usre` DB; `tsc` clean.
diff --git a/src/ingest/parcels/arcgis_sales.ts b/src/ingest/parcels/arcgis_sales.ts
index 8e2e6f3..b3b7901 100644
--- a/src/ingest/parcels/arcgis_sales.ts
+++ b/src/ingest/parcels/arcgis_sales.ts
@@ -401,6 +401,60 @@ const SOURCES: Record<string, Source> = {
toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.apn); if (!apn) return null;
return { fips: '06111', apn, address: clean(a.fullsitus), city: clean(a.city), zip: s(a.zip), raw: a } as Rec; }).filter(Boolean) as Rec[],
},
+ 'santa-barbara': {
+ // Santa Barbara County CA — next ring out from LA. AB-1785 (no sale price) → COVERAGE config,
+ // but the richest CA roll so far: situs + LandUse text + assessed value + full characteristics + owner.
+ // Blanks come as ' '/0 (commercial parcels) → num() nulls them. lat/lng via ring centroid
+ // (returnCentroid unsupported here; native SR 3310, outSR=4326 requested by geometry:true).
+ key: 'santa-barbara', label: 'Santa Barbara County CA', cursorKey: 'santa_barbara',
+ geometry: true, orderBy: 'OBJECTID_1', pageSize: 1000, // OID field is OBJECTID_1 (not OBJECTID); maxRecordCount=1000
+ layer: 'https://maps.calagpermits.org/arcgis/rest/services/SantaBarbara/Parcels/MapServer/0',
+ where: 'APN IS NOT NULL',
+ outFields: 'APN,Situs1,SCity,SZip,LandUse,LandValue,StrImpr,Net_AV,YearBuilt,SqFootage,Bedrooms,Bathrooms,Owner',
+ fieldMap: { source_id: 'APN', address: 'Situs1', city: 'SCity', zip: 'SZip', use_desc: 'LandUse',
+ total_value: 'Net_AV', year_built: 'YearBuilt', sqft: 'SqFootage', beds: 'Bedrooms', baths: 'Bathrooms', owner_name: 'Owner' },
+ toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.APN); if (!apn) return null;
+ const [lng, lat] = centroid(f.geometry);
+ return { fips: '06083', apn, address: clean(a.Situs1), city: clean(a.SCity), zip: s(a.SZip),
+ lat, lng, use: clean(a.LandUse), year: num(a.YearBuilt), sqft: num(a.SqFootage),
+ beds: num(a.Bedrooms), baths: num(a.Bathrooms), totalValue: num(a.Net_AV),
+ grantee: clean(a.Owner), raw: a } as Rec; }).filter(Boolean) as Rec[],
+ },
+ imperial: {
+ // Imperial County CA (Salton Sea / El Centro). AB-1785 → COVERAGE config. Has explicit
+ // Longitude/Latitude fields (cleanest lat/lng — no geometry needed). Land/Imp_ are STRING-typed
+ // (anyPrice strips formatting). LandUse1 is an assessor code only (no long text). No characteristics.
+ key: 'imperial', label: 'Imperial County CA', cursorKey: 'imperial',
+ geometry: false, orderBy: 'FID', pageSize: 2000, // OID field is FID
+ layer: 'https://services7.arcgis.com/RomaVqqozKczDNgd/ArcGIS/rest/services/Parcels_Oct_2023/FeatureServer/0',
+ where: 'APN IS NOT NULL',
+ outFields: 'APN,F_Situs1,Sit_Zip,LandUse1,Land,Imp_,Assessee,Longitude,Latitude',
+ fieldMap: { source_id: 'APN', address: 'F_Situs1', zip: 'Sit_Zip', use_desc: 'LandUse1',
+ total_value: 'Land+Imp_', owner_name: 'Assessee', lat: 'Latitude', lng: 'Longitude' },
+ toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.APN); if (!apn) return null;
+ const land = anyPrice(a.Land), imp = anyPrice(a.Imp_);
+ return { fips: '06025', apn, address: clean(a.F_Situs1), zip: s(a.Sit_Zip), use: clean(a.LandUse1),
+ lat: num(a.Latitude), lng: num(a.Longitude), totalValue: (land || 0) + (imp || 0) || null,
+ grantee: clean(a.Assessee), raw: a } as Rec; }).filter(Boolean) as Rec[],
+ },
+ 'san-bernardino': {
+ // San Bernardino County CA — largest CA county by area, ~840k parcels (huge coverage win).
+ // AB-1785 → COVERAGE config. NO situs address on this roll. Value fields are COMMA-formatted
+ // strings ('42,345') → anyPrice() strips commas; plain num()/Number() would yield NaN. Owner is
+ // mostly redacted ("Protected Per CA Gov Code 7928.205") → filtered to null. lat/lng via ring centroid.
+ key: 'san-bernardino', label: 'San Bernardino County CA', cursorKey: 'san_bernardino',
+ geometry: true, orderBy: 'OBJECTID', pageSize: 1000, // maxRecordCount=1000
+ layer: 'https://services.arcgis.com/aA3snZwJfFkVyDuP/arcgis/rest/services/Parcels_for_San_Bernardino_County/FeatureServer/0',
+ where: 'ParcelNumber IS NOT NULL',
+ outFields: 'ParcelNumber,AssessClass,LandValue,ImprovementValue,OwnerName,Acreage',
+ fieldMap: { source_id: 'ParcelNumber', use_desc: 'AssessClass', total_value: 'LandValue+ImprovementValue', owner_name: 'OwnerName' },
+ toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.ParcelNumber); if (!apn) return null;
+ const [lng, lat] = centroid(f.geometry);
+ const land = anyPrice(a.LandValue), imp = anyPrice(a.ImprovementValue);
+ const own = clean(a.OwnerName); const owner = own && !/^Protected Per/i.test(own) ? own : null;
+ return { fips: '06071', apn, lat, lng, use: clean(a.AssessClass),
+ totalValue: (land || 0) + (imp || 0) || null, grantee: owner, raw: a } as Rec; }).filter(Boolean) as Rec[],
+ },
};
const execFileP = promisify(execFile);
diff --git a/src/ingest/parcels/engine.ts b/src/ingest/parcels/engine.ts
index e8fcdf6..b8fb1ff 100644
--- a/src/ingest/parcels/engine.ts
+++ b/src/ingest/parcels/engine.ts
@@ -41,6 +41,9 @@ const ADAPTERS: Record<string, () => Promise<{ run: () => Promise<{ upserted: nu
jackson: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('jackson') }; },
'orange-county': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('orange-county') }; },
'ventura-county': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('ventura-county') }; },
+ 'santa-barbara': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('santa-barbara') }; },
+ imperial: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('imperial') }; },
+ 'san-bernardino': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('san-bernardino') }; },
};
async function main() {
diff --git a/src/jobs/hourly_loop.ts b/src/jobs/hourly_loop.ts
index 7b36d7a..a8c3b91 100644
--- a/src/jobs/hourly_loop.ts
+++ b/src/jobs/hourly_loop.ts
@@ -77,6 +77,9 @@ const JOBS: Job[] = [
{ name: 'deeds-jackson',script:'src/ingest/parcels/engine.ts', args: ['jackson'], minIntervalHours: 3, runSources: ['jackson'] },
{ name: 'parcels-orange',script:'src/ingest/parcels/engine.ts', args: ['orange-county'], minIntervalHours: 2, runSources: ['orange_county'] },
{ name: 'parcels-ventura',script:'src/ingest/parcels/engine.ts', args: ['ventura-county'], minIntervalHours: 2, runSources: ['ventura_county'] },
+ { name: 'parcels-sb', script: 'src/ingest/parcels/engine.ts', args: ['santa-barbara'], minIntervalHours: 2, runSources: ['santa_barbara'] },
+ { name: 'parcels-imperial',script:'src/ingest/parcels/engine.ts', args: ['imperial'], minIntervalHours: 2, runSources: ['imperial'] },
+ { name: 'parcels-sbd', script: 'src/ingest/parcels/engine.ts', args: ['san-bernardino'], minIntervalHours: 2, runSources: ['san_bernardino'] },
// TK-5: full San Diego County (1.09M) via SANDAG — zoning + assessed value; was in engine but missing from rotation.
{ name: 'parcels-sd-sandag', script: 'src/ingest/parcels/engine.ts', args: ['san-diego-sandag'], minIntervalHours: 2, runSources: ['san_diego_sandag'] },
// TK-5: Santa Clara County CA (San Jose, 493k) — situs address; was in engine but missing from rotation.
← 0386ff5 TK-16: add Ventura County CA (06111) situs-address coverage
·
back to Nationalrealestate
·
auto-data-snapshot: 2026-08-10T16:09:17 (1 data files) — SOU abd259f →