NJ Hazard Vulnerability Dashboard
One parcel core, 5 hazard scenarios, and a vulnerability score you can take apart.
- 3,477,980Parcels screened per scenario
- 5Hazard scenarios scored
- 17.4MParcel-scenario score rows
- 11/11QA gates re-derived from published data
Problem
The NJ Parcel Flood Risk Dashboard answers an underwriter’s question: how exposed is this property, today, on one number. Planners ask a different one. They need to know how the answer changes — which parcels screen clean under today’s FEMA map and badly under sea-level rise, where a Category 3 surge reaches that a Category 1 does not, and whether the places that come out worst are also the places least able to absorb the loss.
That is not a variation on the same product. Same parcel backbone, different score, different audience: state, county, and municipal resilience staff comparing exposure across scenarios, not underwriters pricing a single policy.

Approach
Every parcel is scored once per scenario on a state-resilience-aligned framework rather than a single-hazard finance score:
V = round(100 × (0.45·E + 0.30·S + 0.25·C))
- Exposure (E) — how much of the parcel intersects the hazard zone under this scenario, with a presence floor and a small bonus for parcels exposed across three or more scenarios at once.
- Sensitivity (S) — how consequential exposure is for this parcel’s use: locked class weights (critical and community-serving 1.00, residential 0.85, commercial 0.60, vacant 0.15) plus its improvement-to-total value ratio.
- Consequence context (C) — CDC social vulnerability percentile, NJDEP Overburdened Community status, and tax-base concentration.
The five scenarios are current FEMA flood at the 1% and 0.2% annual chance (S1, S2), sea-level rise of five feet (S3), and SLOSH hurricane storm surge at Categories 1 and 3 (S5, S6).

Results
| Scenario | Parcels screened | % exposed | Mean V | Assessed value exposed |
|---|---|---|---|---|
| S1 — Current SFHA (1%) | 3,477,980 | 13.0% | 34.8 | $286.7B |
| S2 — Current 0.2% shaded X | 3,477,980 | 5.2% | 31.8 | $127.3B |
| S3 — SLR +5 ft (coastal) | 2,852,337 | 18.7% | 37.8 | $306.3B |
| S5 — Storm surge Cat 1 | 3,117,435 | 10.9% | 34.9 | $216.2B |
| S6 — Storm surge Cat 3 | 3,117,435 | 19.7% | 38.6 | $330.1B |
The spread is the finding. A parcel screening clean under today’s FEMA map can screen at real risk under sea-level rise or a Category 3 surge: S3 and S6 each expose roughly 50% more of the state’s assessed value than S1 does, precisely because they model conditions beyond what current infrastructure and flood control protect against. A dashboard that showed only S1 would be quietly reassuring and wrong.


Calibration, and the miss that stayed in
Nine municipalities with well-documented hazard history must rank top-quartile under S1 and S3. 14 of 18 checks pass. The other four are the interesting part:
- Three are correctly
not screened. Bound Brook, Manville, and Wayne sit in non-coastal counties that S3 has no data footprint for at all. The distinction between “no data here” and “safe here” is load-bearing, and the dashboard never collapses it. - One is a genuine miss. Ventnor under S1. Investigated rather than waved through: its built parcels really do sit outside FEMA’s current mapped flood zone, confirmed against the live FEMA service directly. The same town passes cleanly under S3, at 99.9% exposed, once sea-level rise is modelled past existing dune protection. Documented, not tuned away — the rule against adjusting weights to force a calibration pass is absolute.
Technical detail — pipeline scale, and four bugs worth naming
Five scenarios across 3,477,980 parcels is 17,389,900 fact rows, published as 585 summary JSON files, a 518.1 MB parcel tileset, a 2.1 MB boundaries tileset, and 564 search shards. The heaviest stage — the parcel × hazard × scenario intersection — ran 18.79 hours wall-clock, parallelised across five worker processes. Per-county cost tracks hazard-layer vertex density far more than parcel count: Cape May’s 143,206 parcels took 6.58 hours against Ocean County’s 421,548 in 13.30. A first statewide attempt was killed partway through by an unrelated session teardown and resumed cleanly from county checkpoints — no completed county was lost, only wall-clock time.
Four bugs are worth naming because of how each was caught:
- A statistical bug caught by an independent gate, not by inspection. The statewide KPI
rollup understated
% exposedfor every partial-coverage scenario by 10–18%, because the summary function’s “coverage is uniform within a group” assumption — true at county and municipality grain by construction — silently broke at state grain, where counties differ in scenario coverage. Caught by a rollup-invariant gate that re-derives the state total from the published county files rather than trusting either number. - A bug the aggregate count caught and the individual gate missed. A QA gate’s own
bounds check used a pandas
.all()chain, which returnsnumpy.bool_rather than a Pythonbool. It printed PASS per-gate and silently failed the summary’s identity check, undercounting passes with no gate ever marked FAIL. Caught because the total did not match the number of PASS lines printed. - A privacy-audit false positive, verified rather than assumed. A scan for owner-identity
fields flagged seven search-index files. All false positives: “Downer Way,” “Pitman Downer
Rd,” and “Downer Avenue” all contain the substring
owner. Confirmed by inspecting every flagged file before concluding it was a false alarm, then fixed with word-boundary anchoring. - A suspected upstream bug, correctly ruled out. A suspected ~80% completeness gap in the sibling project’s flood-zone data turned out to be a bounding-box mistake in the investigation itself, confirmed by re-testing against the live FEMA service with the correct county boundary. The false lead is documented so a later session does not repeat it.
A genuine upstream artifact did survive all this: 742 duplicate MOD-IV PINs statewide (0.02%), which crashed the fact table’s grain-uniqueness assertion on the first attempt and turned out to explain a previously unexplained 742-parcel discrepancy against the shared parcel core’s canonical count.
Architecture
The parcel core is shared with the sibling project, read-only. Everything downstream is this project’s own: hazard-layer normalisation, the scenario intersection, E/S/C scoring, summaries and calibration, tiles, and 11 QA gates — all re-derived fresh from published data rather than trusted from any earlier stage’s self-report.
The web app is React 19, Vite, Tailwind v4, and MapLibre across four views, and it is deliberately differentiated from its sibling in the interface as well as the analysis: a left sidebar with the scenario selector as a persistent control rather than a top nav bar, warm amber chrome against a cool colourblind-safe severity ramp (the sibling inverts both), sharper corners, a different icon mark. Two dashboards on one backbone should not be mistakable for each other at a glance.
Hosting is static — Cloudflare Pages and R2, the same zero-backend shape as the sibling.
Data sources
| Dataset | Source |
|---|---|
| Parcel core | NJ MOD-IV, shared with the NJ Parcel Flood Risk Dashboard |
| Current flood zones | FEMA National Flood Hazard Layer |
| Sea-level rise | NJDEP CAFE |
| Storm surge | NOAA SLOSH MOM, via Rutgers |
| Social vulnerability | CDC/ATSDR SVI 2022 |
| Environmental justice | NJDEP Overburdened Communities |
Screening tool, not a determination. Results are for hazard screening and prioritisation research; parcels must not be targeted for action without full analytical and policy review.
Share this page
https://abdulkalam.pages.dev/projects/nj-hazard-vulnerability/
Scan to open this page. Download the SVG for print.