Planetary-scale answers, unlocked.
A Hands-On Guide for Working with Large-Scale Spatial Data. Learn more.
Authors
I didn’t start this project to build a real risk model, not one that can be used by an insurer tomorrow. But it is a workflow that an insurer can put into practice to create their own risk scores with Wherobots and their own expertise. The idea was simple: what can be done in a day with Wherobots MCP for Claude and the VSCode plugin? It turns out quite a lot, and the barrier to entry is a Claude (or other coding agent) Account and VS Code running on a laptop with access to a Wherobots pro tier connected.
Total costs across tokens and data processing was about $300. This example looks at the Insurance industry and scoring risk on a property and building level. I’ll be following up with additional examples on Drone Delivery hub / nest site selection as well as communication services network connectivity in the coming weeks.
Lets start with the concept.
Insurance works on a basic idea: what is the risk at a given location, and how should it be priced? For a property and casualty carrier that question repeats across every building and property asset in its portfolio. The data to answer it, in many cases, already exists spread across wildfire rasters, hail radar, flood layers, parcels, and road networks. Getting it into one scored, queryable, mappable form, updated on a recurring schedule is usually the hard part, because handling these data types is unsupported and often impossible in other compute environments.
This post walks that process end to end: every Overture building in Colorado, 2,771,126 of them, joined against the Parcels they sit upon from Regrid, and scored across five perils, from a statewide view down to a single rooftop. The data processing engine used is WherobotsDB on Wherobots Cloud in AWS. Our team at Wherobots maintains Apache Sedona, and WherobotsDB is 100% code compatible the OSS, but fully managed with more spatial functions and capabilities, grater performance, and enterprise support options. Three capabilities carry this data pipeline: spatial SQL over raster and vector datasets combined, a spatial operation that prunes on reads time, and PMTiles that WherobotsDB can deliver to enable a snappy browser experience on MapLibre.
The finished map is live on the Wherobots Website here. You can play with it inline below:
The Colorado catastrophe-risk explorer, built with WherobotsDB, Claude Opus 5 & VSCode via agentic app development.
Seven sources feed the app and the data pipeline:
Two structural decisions:
The pipeline is a medallion architecture, and every layer is an Iceberg catalog table you can query on its own.
Bronze, raw as it lands, one table per source:
overture_buildings
noaa_hail
usfs_wildfire
fema_nfhl
fema_nri
regrid_parcels
overture_places
Silver, conformed: clipped to the Colorado boundary, coordinate systems reconciled, geometries validated: buildings, hail_grid, flood_zones, parcels, fire_stations, nri_tracts.
buildings
hail_grid
flood_zones
parcels
fire_stations
nri_tracts
Gold, scored and tile-ready: building_perils (five peril scores per building), hex_rollup (H3 exposure and composite), parcels_scored.
building_perils
hex_rollup
parcels_scored
Update frequency. Hail accumulation and Regrid parcels refresh monthly, so a monthly run keeps the map current. USFS wildfire and the FEMA National Risk Index refresh annually. The pipeline is defined with the Wherobots Python SDK and scheduled with Apache Airflow, one run per medallion stage.
The buildings layer is continental but the analysis is for Colorado. A spatial predicate filter pushdown on the read keeps makes it easy and cheap to run that state only:
-- Silver: every Colorado building footprint, clipped with a pushed-down spatial predicate CREATE TABLE org_catalog.co_pc_risk_silver.buildings AS SELECT b.id, b.geometry FROM wherobots_open_data.overture_maps_foundation.buildings_building b JOIN org_catalog.co_pc_risk_bronze.co_boundary aoi ON ST_Intersects(b.geometry, aoi.geometry);
WherobotsDB pushes ST_Intersects down to the GeoParquet files, reads each file’s bounding-box metadata, and skips the files that fall outside Colorado. Because WherobotsDB can easily index a dataset by proximity using say a Hilbert Curve index, this makes this type of operation even easier.
ST_Intersects
This is a core WherobotsDB capability that this and many other use cases leverage. Wildfire hazard is a 30 m raster. Hail is millions of radar points. Flood is polygons. Buildings are polygons. One set-based query samples and joins all of them, per building:
-- Gold: score each building against the wildfire raster and the hazard vectors. WITH wf AS ( SELECT b.id, MAX(RS_ZonalStats(w.rast, b.geometry, 'max')) AS wildfire_score FROM org_catalog.co_pc_risk_silver.buildings b JOIN org_catalog.co_pc_risk_silver.wildfire w ON RS_Intersects(w.rast, b.geometry) GROUP BY b.id ), hail AS ( SELECT b.id, COUNT(*) AS hail_events, MAX(h.size_in) AS max_hail_in FROM org_catalog.co_pc_risk_silver.buildings b LEFT JOIN org_catalog.co_pc_risk_silver.hail_obs h ON ST_Intersects(b.geometry, h.geometry) GROUP BY b.id ), flood AS ( SELECT b.id, ANY_VALUE(f.zone) AS flood_zone FROM org_catalog.co_pc_risk_silver.buildings b LEFT JOIN org_catalog.co_pc_risk_silver.flood_zones f ON ST_Intersects(b.geometry, f.geometry) GROUP BY b.id ) SELECT b.id, b.geometry, wf.wildfire_score, hail.hail_events, hail.max_hail_in, flood.flood_zone FROM org_catalog.co_pc_risk_silver.buildings b LEFT JOIN wf ON b.id = wf.id LEFT JOIN hail ON b.id = hail.id LEFT JOIN flood ON b.id = flood.id;
RS_ZonalStats reads the raster values under each footprint and returns key statistics. Each peril is computed in its own CTE so the joins stay one-to-many and the counts are exact. WherobotsDB executes RS_Intersects and ST_Intersects as spatial range joins, so the raster-to-building and point-to-building matches avoid a cross product. The run scores the full state in just a few minutes on one WherobotsDB medium runtime.
RS_ZonalStats
RS_Intersects
The fused query gives each building a raw hazard value per peril. Scoring turns those into five small integers on one row, so a building is one comparable object across every hazard. Each peril is scored on its own scale and the five sum to a 0-to-7 composite:
The perils are scored individually. A single blended number would reads like a hazard map while hail dominates the sum, because hail is Colorado’s most costly regular peril. Keeping five columns lets the map user and the copilot switch to one peril at a time and understand them specifically.
The assignment is set-based, one CASE per peril over the fused hazard values:
-- Gold: turn raw hazard values into five 0-based peril scores per building SELECT id, geometry, -- wildfire: USFS hazard under the footprint, banded 0 / 1 / 2 CASE WHEN wildfire_hazard >= hi_break THEN 2 WHEN wildfire_hazard >= lo_break THEN 1 ELSE 0 END AS wf_score, -- hail: largest radar-detected hail size over the building, in inches CASE WHEN max_hail_in >= 2.0 THEN 2 WHEN max_hail_in >= 1.0 THEN 1 ELSE 0 END AS hail_score, -- flood: inside a FEMA Special Flood Hazard Area CASE WHEN in_sfha THEN 1 ELSE 0 END AS flood_score, -- wind / tornado: FEMA National Risk Index rating for the tract CASE WHEN nri_wind_elevated THEN 1 ELSE 0 END AS wind_score, -- access: beyond five road miles (8047 m) of the nearest fire station CASE WHEN road_m IS NULL OR road_m > 8047 THEN 1 ELSE 0 END AS access_score, -- composite: the five summed, domain 0-7 ( CASE WHEN wildfire_hazard >= hi_break THEN 2 WHEN wildfire_hazard >= lo_break THEN 1 ELSE 0 END + CASE WHEN max_hail_in >= 2.0 THEN 2 WHEN max_hail_in >= 1.0 THEN 1 ELSE 0 END + CASE WHEN in_sfha THEN 1 ELSE 0 END + CASE WHEN nri_wind_elevated THEN 1 ELSE 0 END + CASE WHEN road_m IS NULL OR road_m > 8047 THEN 1 ELSE 0 END ) AS composite FROM org_catalog.co_pc_risk_gold.building_hazards;
Two of these bands are exposed in a way worth highlighting.
Wildfire and hail are measured under each footprint; wind and flood are inherited. wf_score reads the USFS raster at the building, and hail_score reads the radar accumulation over it. wind_score comes from a FEMA National Risk Index rating at census-tract resolution, and flood_score from a FEMA zone polygon. A tract or a zone is far coarser than a rooftop, so those two scores are derived from an area where the detections exist, and that coarser grain is labeled in the schema, not intended to represent as a per-structure reading.
wf_score
hail_score
wind_score
flood_score
On access, a NULL distance means furthest, not missing. The access score flags every building beyond five road miles of a fire station. The nearest-station search runs to a 25 km radius; a building with no station inside that radius has a NULL distance and is the most remote in the state, so the rule scores NULL as 1. Writing road_m > 8047 alone drops exactly the worst-access cohort. That is why the score, not the raw distance, drives the map.
road_m > 8047
Run over all 2.77M buildings, the top wildfire band holds 307,679 buildings and the 2 in-and-up hail band holds 790,889. Both counts are floors: a building with no observation for a peril scores 0 for it, and reads as at least that exposed.
The per-building table has fine grained details. A reinsurer often is concerned with concentration risk, and it’s easier to visualize when aggregated, so its helpful to roll the same scores up to an H3 grid:
-- Gold: roll per-building scores up to H3 for the accumulation view SELECT ST_H3CellIDs(geometry, 7, false)[1] AS h3, COUNT(*) AS buildings, SUM(wildfire_score) AS wildfire_exposure, AVG(composite) AS mean_composite FROM org_catalog.co_pc_risk_gold.building_perils GROUP BY ST_H3CellIDs(geometry, 7, false)[1];
The same gold tables drive both the statewide hex view and the street-level building view. Nothing recomputes between zoom levels.
WherobotsDB builds the PMTiles as vector tiles and ships them to object storage, so a hand-written MapLibre GL JS page reads them by their S3 URL. No separate tiling tool, no tile server, no build step in the app.
# WherobotsDB builds and ships the PMTiles for the web app from wherobots import WherobotsJob WherobotsJob(script="s3://.../export_pmtiles.py", name="co-risk-export", runtime="small").submit()
The whole build was authored and shipped with one repeatable stack:
The five scores screen where to look. They are not a calibrated loss model, and nothing here is a determination of insurability. The bands, the floors, and the inherited-grain labels live in the pipeline and again in the copilot’s system prompt, so the map view and the copilot’s answers stay inside the same limits.
Hail is Colorado’s dominant peril, ahead of wildfire. In the top wildfire tier alone, 307,679 buildings screen as elevated: a starting list for where to focus. The access-to-services peril, powered by road-network distance to the nearest fire station, marks the insurability boundary, the cohort beyond a fire department’s reach. A P&C analyst can review all of it by toggling the map.
The Colorado build is a template. Swap the boundary for your state or the whole country, swap the peril rasters and point clouds for the ones on your portfolio, and the pipeline holds: push the spatial predicate on the read, fuse raster and vector in one query, roll up to H3, let WherobotsDB build and ship the tiles down to the property parcel and building layer.
That is the point of an AI Context Engine for the Physical World: the physical-world data, prepared and scored at the scale a portfolio spans, in a form an analyst and an agent can both query.
Start on Wherobots Cloud, connect to the Wherobots Claude MCP, or open the Colorado risk explorer to see what I built, or check out the docs at docs.wherobots.com.
Key takeaways
Building-level catastrophe risk scoring assigns each building in a portfolio a small integer score for each peril (wildfire, hail, flood, wind or tornado, and access to a fire station), plus a composite sum. In this build, every building in Colorado, 2,771,126 of them, is scored across five perils, from a statewide view down to a single rooftop.
Three WherobotsDB capabilities carry this build: spatial SQL over raster and vector in one query, spatial predicate pushdown at read time so the scan touches a fraction of the planetary layer, and PMTiles that WherobotsDB builds and ships to the browser without a tile server. The pipeline is defined with the Wherobots Python SDK and scheduled with Apache Airflow, one run per medallion stage, with Bronze, Silver, and Gold Iceberg catalog tables that are queryable on their own.
No. The five scores screen where to look. They are not a calibrated loss model, and nothing here is a determination of insurability. The workflow is one an insurer runs to create their own risk scores with Wherobots and their own expertise.
Seven layers: Overture Maps building footprints, USFS Wildfire Risk to Communities (30 m raster), NOAA radar hail (403M observations since 2016), FEMA National Flood Hazard Layer, FEMA National Risk Index at tract level for tornado and wind, Regrid parcels for value and land use, and Overture places for fire station locations, with road-network distance computed in the pipeline.
Learning Wherobots by Building a National AI Data Center Suitability Report
This guest post is from a Wherobots user George Chandeep Corea, which covers an exploration of how he used Wherobots MCP with his preferred AI coding tools to build the interactive AI data center site suitability analysis tool below. The following quote is from his own biography. Learning by Doing Below is a working national […]
The Wherobots Spatial AI Assistant is now in the Anthropic Connectors Directory
You can now ask Claude questions about the physical world and get answers grounded in real spatial data. The Wherobots Spatial AI Assistant, now available in the Anthropic Connectors Directory, answers these questions in plain language and returns results, maps, and reports directly in your Claude conversation. Wherobots is the AI context engine for the […]
From the Spokane firestorm to all of Washington: real-time wildfire monitoring for under $50 a pass
The moment a satellite pass lands, this pipeline turns it into a burn-severity map in 14 minutes: real-time wildfire monitoring with Python and Spatial SQL that protects lives and assets, shown on the Spokane firestorm and scaled to the entire state of Washington.
share this article
Awesome that you’d like to share our articles. Where would you like to share it to: