30-Mar-2026 — area-map: custom group boundaries and parish footpath observer allocations #201
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
customGeometry field on AreaGroup for per-group GeoJSON polygon overrides
- BNG→WGS84 coordinate transform via
proj4 for uploaded shapefiles
- Features matched to groups by
GROUP_CODE/GROUP_NAME properties
- Admin UI with upload button, match preview, and per-group clear
Parish Boundary Overlay
- ONS parish boundary proxy at
/api/parishes/query fetching from
Parishes_and_Non_Civil_Parished_Areas_December_2024 ArcGIS FeatureServer
- Server-side pagination, bounding box validation, and 24h in-memory cache
with
noCache query 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
parishAllocations collection with compound unique index on
(groupCode, parishCode) storing per-parish allocated/vacant status
- Full CRUD via
/api/database/parish-allocation with bulk delete endpoint
- CSV import at
/api/parishes/import with 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
ParishPopupComponent with ng-select dropdown for assigning members
to parishes via assigneeMemberId
- 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
assigneeMemberId field to ParishAllocation model and Mongoose schema
- Added
inSR: 4326 to ArcGIS API call to fix projection mismatch
- CSV import resolves assignee names to member
_id via 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
AreaMapData extended with showAreas, showParishes, colour pickers
(parishAllocatedColor, parishVacantColor, parishBorderColor),
and parishFillOpacity slider
- 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.ts sets
showAreas: true on 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
MapsSubTab and ParishAllocationSortField enums
- Removed unused
MarkdownEditorComponent import 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_CODE or GROUP_NAME properties 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
customGeometry field on AreaGroup interface
(system.model.ts)
- Reusable shapefile parser extracted to
server/lib/map-routes/shapefile-parser.ts
- Backend
areas() and batchAreas() endpoints check for
customGeometry before 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.