Open Concord, NH
Open Concord is a full-stack geospatial data platform for Concord, New Hampshire,
built entirely in R. A {targets} ETL pipeline acquires every public
dataset touching the city — the municipal ArcGIS REST server (~91 layers: parcels,
zoning, roads, utilities), federal and state ArcGIS services (USA Structures, FEMA
NFHL, conservation lands, historic districts), OpenStreetMap, US Census ACS 2023,
CDC PLACES health indicators, EPA FRS, USGS streamgages, GBIF biodiversity
occurrences, and Wikidata/Wikipedia knowledge — and loads each into a self-hosted
PostGIS database tagged as map+db (rendered on the map) or db
(joined reference table).
The frontend is an R Shiny app (bslib + mapgl) that queries PostGIS live. It ships with four capability panels: a searchable layer accordion, a thematic choropleth picker (ACS income, population, rent; CDC mental health), an analysis toolset (Nominatim geocoder, SQL filter builder, draw-to-measure, GeoJSON/CSV export), and a Knowledge tab surfacing Wikidata facts and notable people for Concord. Click any feature and a right-side inspector opens with the full attribute table and Wikipedia cross-links.
Architecture
The pipeline is a three-stage system: acquire, store, serve. Eight target groups
(concord, external, osm, apis,
schools, knowledge, business, web)
run under targets::tar_make() with full dependency tracking — rerunning
only what changed. Every load writes to a named PostGIS schema and upserts a row in
public.catalog, which the Shiny app reads on startup to discover available
layers.
Self-hosting runs via docker compose: PostGIS + Shiny Server + Caddy TLS
on a VPS, with the app served at concord.maxwellhowegis.com. Optional
--profile api adds pg_tileserv and
pg_featureserv for vector-tile performance at scale.
R package (openconcord) live queries R Shiny app
┌─────────────────────┐ ┌──────────────┐ ┌──────────────────┐
│ targets::tar_make() │──►│ PostGIS │◄─│ shiny/app.R │
│ oc_load_concord() │ETL│ + catalog │ │ bslib + mapgl │
│ oc_load_external() │ │ 165 layers │ │ (MapLibre GL) │
│ oc_load_apis() ... │ └──────────────┘ └────────┬─────────┘
└─────────────────────┘ │ Caddy TLS
concord.maxwellhowegis.com
What the Map Can Do
The Shiny app sidebar carries four tabs. Each is server-rendered from live PostGIS data — no bundled GeoJSON, no static tiles.
Layers
Searchable accordion grouped by schema (city, external, osm, apis, schools, knowledge). Each layer shows a live feature count, color-coded dot, and a checkbox. Toggle-all per group. 3D building extrusion toggle for ~15,500 LiDAR-height footprints.
Thematic
Choropleth picker for census tracts: ACS median income, total population, median rent, and CDC PLACES mental-health prevalence. Data-driven step expression via MapLibre, with a live color-ramp legend and break labels.
Tools
Nominatim geocoder (no API key). SQL filter builder with column picker from PostGIS information_schema. Draw toolbar: polygon → area (acres), perimeter (ft), per-layer feature counts via ST_Intersects. GeoJSON & CSV export.
Knowledge
Wikidata facts about Concord (Q28249) displayed as a property table. Notable people chips linked to Wikipedia. Click any feature on the map and a right-panel inspector shows the full attribute table with Wikipedia cross-links for knowledge-layer features.
Data Sources
| Source | Schema | What | License |
|---|---|---|---|
| City of Concord ArcGIS | city | ~91 layers: parcels, zoning, roads, utilities, trees | Public records |
| Federal / state ArcGIS | external | USA Structures, FEMA NFHL, conservation, historic | Public domain |
| OpenStreetMap | osm | Roads, buildings, POIs, businesses | ODbL |
| US Census ACS + TIGER | apis | Demographics, tracts, school districts | Public domain |
| CDC PLACES 2023 | apis | Tract-level health indicators (27 measures) | Public domain |
| EPA FRS · USGS · NWS | apis | Facilities, streamgages, earthquakes, weather alerts | Public domain |
| GBIF · iNaturalist | apis | Biodiversity occurrences | CC-BY / CC0 |
| Wikidata · Wikipedia | knowledge | Notable people, facts, history | CC0 / CC-BY-SA |
The {targets} Pipeline
The ETL is structured as a {targets} pipeline with nine named targets, each corresponding to a source family. Running targets::tar_make() on a fresh PostGIS instance downloads and loads every layer in order, skipping any target whose inputs haven't changed. Every load records itself in public.catalog with a validated flag that gets flipped after the per-dataset visual QA check.
Helper functions handle the cross-cutting concerns: oc_arc_layer() pages through ArcGIS REST with a bounding-box filter; oc_write_layer() upserts to PostGIS with consistent SRID 4326 enforcement and catalog registration; oc_connect() uses libpq env vars so no credentials live in source control.
In Development
The R codebase is complete and all ETL functions are written against known package APIs. The Shiny v3 interface has been fully implemented with all four capability panels. The live deployment to concord.maxwellhowegis.com — first run of tar_make() on the VPS, per-dataset validation, and Caddy TLS setup — is the next step.
A GitHub Actions CI workflow runs on every push: R source syntax checks, offline config unit tests (no DB required), and lintr style linting.