30-Mar-2026 — area-map: custom group boundaries and parish footpath observer allocations #201
build 568 — commit 34c780a
area-map: custom group boundaries and parish footpath observer allocations and support ad-hoc shapefile upload for custom group boundaries (#201)
Custom Group Boundaries
- Support ad-hoc shapefile upload for custom group boundary polygons
customGeometryfield onAreaGroupfor per-group GeoJSON polygon overrides- BNG→WGS84 coordinate transform via
proj4for uploaded shapefiles - Features matched to groups by
GROUP_CODE/GROUP_NAMEproperties - Admin UI with upload button, match preview, and per-group clear
Parish Boundary Overlay
- ONS parish boundary proxy at
/api/parishes/queryfetching from Parishes_and_Non_Civil_Parished_Areas_December_2024 ArcGIS FeatureServer - Server-side pagination, bounding box validation, and 24h in-memory cache
with
noCachequery param to force refresh - Parish boundaries clipped to group area polygons using point-in-polygon ray casting, coloured by allocation status (green=allocated, red=vacant)
- Hover highlights with increased opacity, tooltip showing parish name and status
Parish Footpath Observer (PFO) Allocations
- MongoDB
parishAllocationscollection with compound unique index on(groupCode, parishCode)storing per-parish allocated/vacant status - Full CRUD via
/api/database/parish-allocationwith bulk delete endpoint - CSV import at
/api/parishes/importwith upsert logic (matches by parishCode or parishName), per-row error detail reporting, and automatic fallback code generation for parishes without ONS codes - Click-to-toggle admin UI: authenticated admins click a parish on the map to toggle allocated/vacant, saved to MongoDB in real time
Parish Popup with Member Selector
- New
ParishPopupComponentwith ng-select dropdown for assigning members to parishes viaassigneeMemberId - Compact mode for card-based rendering, Escape key closes popup
- Dynamic Angular component creation via
createComponent()replaces HTML-string popups - Members loaded once in
ngOnInit, tooltip suppression while popup is open - Selecting a member auto-sets status to "allocated"; marking vacant clears assignee
Parish Model & Query
- Added
assigneeMemberIdfield toParishAllocationmodel and Mongoose schema - Added
inSR: 4326to ArcGIS API call to fix projection mismatch - CSV import resolves assignee names to member
_idvia database lookup
Admin Settings (Maps Tab)
- Maps tab split into togglable sub-sections using
SectionToggle: Area Groups, Custom Boundaries, Geographic Data, Parish Allocations - Parish Allocations section with:
- Image-cropper-style file dialog (badge button + drag-and-drop zone)
- Sortable/filterable allocations table with status badges
- Clear All Allocations button with bulk delete
- Full error detail display on import failures
- ngx-bootstrap tooltips on custom boundary icons (replacing native
title)
CMS Page Editor
AreaMapDataextended withshowAreas,showParishes, colour pickers (parishAllocatedColor,parishVacantColor,parishBorderColor), andparishFillOpacityslider- Checkboxes for "Show group area overlays" and "Show civil parish boundaries"
- CSV import UI with badge button, drag-and-drop, filename confirmation
Event Group Component
- Added compact input mode (hides "Group" heading on cards)
- Fixed "undefined" group name fallback via API lookup
- Icon and text wrapped in single clickable link with tooltip
- Shows group name even without login (no URL required)
- Removed unused service imports
- Consistent margin spacing in walk view
Data Migration & Housekeeping
- Migration
20260328000000-backfill-area-map-show-areas.tssetsshowAreas: trueon all existing area map rows in pageContent - Extracted repeated MongoDB collection name constants into
server/lib/mongo/migrations/shared/collection-names.ts - Updated 16 migration files to import from shared module
- Fixed
"pagecontent"typo to correct"pageContent"casing - Added
MapsSubTabandParishAllocationSortFieldenums - Removed unused
MarkdownEditorComponentimport from album backgrounds - Suppressed browser focus outline on Leaflet map elements
Summary
Adds the ability to upload ESRI shapefiles containing custom group boundary polygons, replacing the default ONS Local Authority District boundaries on the area map. This produces sharper, more accurate group boundaries that reflect actual walking group territories rather than approximations built from council district polygons.
What's New
Custom Group Boundary Upload
- Upload a shapefile (.zip) via the new "Custom Group Boundaries" section in Admin > System Settings > Area Map
- Shapefile features are automatically matched to configured groups
by
GROUP_CODEorGROUP_NAMEproperties in the .dbf file - Coordinates in British National Grid (OSGB36) are automatically detected and transformed to WGS84
- Geometry is simplified using Turf.js for efficient map rendering
- Upload results show which features matched to groups and which did not, so administrators can verify the import before saving
Per-Group Custom Geometry
- Each group can now have its own
customGeometry(Polygon or MultiPolygon) stored directly in the system configuration - When custom geometry is present, the area map uses it directly instead of looking up and assembling ONS district boundaries
- Groups without custom geometry continue to use ONS districts as before — both sources can be mixed within the same area map
- A green marker icon in the groups table indicates which groups have custom boundaries applied
Clearing Custom Boundaries
- Clear custom geometry from a single group by clicking the clear button next to its custom geometry indicator in the groups table
- Clear all custom boundaries at once with the "Clear All Custom Boundaries" button, reverting all groups to ONS district lookup
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/areas/upload-group-boundaries |
Upload shapefile ZIP |
| DELETE | /api/areas/group-boundary/:groupCode |
Clear one group |
| DELETE | /api/areas/group-boundaries |
Clear all groups |
Technical Details
- New
customGeometryfield onAreaGroupinterface (system.model.ts) - Reusable shapefile parser extracted to
server/lib/map-routes/shapefile-parser.ts - Backend
areas()andbatchAreas()endpoints check forcustomGeometrybefore falling back to ONS district lookup - No changes required to the frontend area map component — it renders whatever GeoJSON the backend returns
- Multer middleware handles file upload on the new route
Context
Kent area coordinator Robert Peel provided a shapefile
(groups_new.zip) with accurate boundary polygons for all 11
geographically-based Kent walking groups. The existing ONS
district-based approach produced boundaries that were imprecise
and visually busy. This feature enables any area to upload their
own authoritative group boundary data.