- Local development authoritative boundary store:
./var/boundaries/ - Production authoritative boundary store:
/srv/berkeleymapper-data/boundaries/ - Configuration knob for both:
SPATIAL_DATA_DIR
Use the same internal layout under both roots so scripts and config stay portable:
${SPATIAL_DATA_DIR}/
source/
gadm/
usa/
gadm41_USA.gpkg
world/
gadm_410-levels.gpkg
census/
usa/
cb_2024_us_county_500k.gpkg
derived/
geojson/
usa/
counties_simplified.geojson
shapefile/
usa/
counties/
counties.shp
counties.shx
counties.dbf
counties.prj
cache/
manifests/
- Source of truth:
GeoPackage (.gpkg) - Display layer format:
GeoJSON - Legacy Java intersection fallback:
Shapefile
Why:
GeoPackageis the best authoring and storage format for boundary data. It is a single file, cleaner than shapefile sidecar sets, and works well with GADM, QGIS, GDAL, and PostGIS import workflows.GeoJSONis the best format for BerkeleyMapper online display because the current app loads remoteGeoJSON,KML, andKMZdirectly.Shapefileshould only be kept as a derived export for the old Java spatial-intersection code, because that code currently reads shapefiles from disk.
- Do not store the full production admin-boundary corpus in git.
- Keep only:
- scripts
- manifests
- small fixtures
- tiny test datasets
- Keep real downloaded boundary files under
SPATIAL_DATA_DIR, outside normal source control.
- Global admin boundaries:
GADMas GeoPackage - US states/counties:
US Census Cartographic Boundary Files - Remote display-only option:
geoBoundariessimplified GeoJSON
- Current React app:
- use remote or proxied
GeoJSONfor display layers
- use remote or proxied
- Legacy Java spatial intersection:
- use a local shapefile export derived from the authoritative
GeoPackage
- use a local shapefile export derived from the authoritative
- Preferred future direction:
- move spatial intersection into the Node server
- use derived local
GeoJSONas the Node runtime format
- Add
SPATIAL_DATA_DIRsupport for local and server deployments. - Add a download/build script:
scripts/fetch-boundaries.sh
- Add a derivation script:
- export simplified
GeoJSONfor display - export
Shapefilefor legacy spatial intersections
- export simplified
- Add
.gitignoreentries for:var/boundaries/- other local boundary cache directories
- Keep only small sample boundary fixtures in-repo for tests and examples.
- Add a Node spatial-intersection endpoint.
- Load derived boundary
GeoJSONin the Node process and cache it in memory. - Add bbox or spatial indexing before point-in-polygon checks.
- Use Node runtime boundaries for:
- point-in-polygon statistics
- county/state/admin joins where polygon containment is preferred over centroid lookup
If only one authoritative dataset is chosen:
- Use
GeoPackageunder${SPATIAL_DATA_DIR}/source/... - Derive:
GeoJSONfor map displayShapefileonly where the legacy intersection code still requires it
- Yes, spatial intersection should be implemented in Node for this codebase.
- Recommended runtime path:
- authoritative source on disk:
GeoPackage - derived runtime format for Node:
GeoJSON - optional legacy compatibility export:
Shapefile
- authoritative source on disk:
This is the practical split:
GeoPackageis best for storage and update workflows.GeoJSONis best for the current BerkeleyMapper JavaScript stack and can support both display and server-side intersection.Shapefileshould be treated as a compatibility artifact, not the primary storage format.
- US counties/states or single-country ADM1/ADM2:
- Node intersection is practical
- Large global admin datasets:
- Node can still work with indexing and simplification
- move to
PostGISif dataset size or query volume grows