Open Concord, NH

Self-directed GIS Platform · 2025–2026 · 165 Layers · MIT Open Source

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.

R PostGIS MapLibre GL Shiny bslib mapgl targets sf arcgislayers tidycensus osmdata httr2 Docker
View on GitHub ↗ ← Back to Portfolio

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
ETL → PostGIS → Shiny frontend. The catalog table self-describes all loaded layers.

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 ArcGIScity~91 layers: parcels, zoning, roads, utilities, treesPublic records
Federal / state ArcGISexternalUSA Structures, FEMA NFHL, conservation, historicPublic domain
OpenStreetMaposmRoads, buildings, POIs, businessesODbL
US Census ACS + TIGERapisDemographics, tracts, school districtsPublic domain
CDC PLACES 2023apisTract-level health indicators (27 measures)Public domain
EPA FRS · USGS · NWSapisFacilities, streamgages, earthquakes, weather alertsPublic domain
GBIF · iNaturalistapisBiodiversity occurrencesCC-BY / CC0
Wikidata · WikipediaknowledgeNotable people, facts, historyCC0 / 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.