354 lines
10 KiB
Markdown

# Map Module
The Map module provides comprehensive location management, geographic organization, volunteer coordination, and door-to-door canvassing capabilities. It combines GIS features with volunteer management for effective ground campaigns.
## Overview
The Map module consists of ten integrated components:
1. **[Locations](locations.md)** - Location database with geocoding
2. **[Geocoding](geocoding.md)** - Multi-provider address → coordinate conversion
3. **[NAR Import](nar-import.md)** - Canadian electoral data import
4. **[Cuts](cuts.md)** - Geographic polygon organization
5. **[Shifts](shifts.md)** - Volunteer shift scheduling
6. **[Canvassing](canvassing.md)** - Door-to-door canvassing system
7. **[Tracking](tracking.md)** - GPS tracking sessions
8. **[Walk Sheets](walk-sheets.md)** - Printable canvass materials
9. **[Data Quality](data-quality.md)** - Geocoding quality monitoring
10. **Map Features Status** - Feature completion tracking
## Features
### Location Management
- Location CRUD with address, coordinates, metadata
- CSV import/export (100,000+ records supported)
- Multi-provider geocoding (6 providers)
- Bulk geocoding with queue
- NAR 2025 server-side import (Canadian electoral data)
- Address standardization
- Visit tracking integration
### Geographic Organization
- Polygon-based geographic cuts
- GeoJSON import/export
- Point-in-polygon queries
- Cut-based location assignment
- Spatial bounds calculation
- Map visualization
### Volunteer Coordination
- Shift scheduling with cut assignment
- Volunteer signup (authenticated + anonymous)
- Email confirmations
- Temp user creation for walk-ins
- Shift capacity tracking
### Canvassing System
- GPS-enabled mobile interface
- Walking route algorithm (nearest-neighbor)
- Visit outcome recording (7 outcomes)
- Session management (start/end/abandon)
- Real-time progress tracking
- Admin monitoring dashboard
- Printable walk sheets with QR codes
### Map Display
- Public interactive Leaflet map
- Color-coded markers by visit status
- Polygon overlays for cuts
- Geolocate button
- Fullscreen mode
- Legend and controls
## User Flow
### Admin Experience
1. **Import Locations** (`/app/map/locations`)
- Upload CSV or NAR data
- Geocode addresses
- Review quality metrics
- Bulk operations
2. **Create Cuts** (`/app/map/cuts`)
- Draw polygons on map
- Name and describe cut
- Assign locations (automatic)
- Export for printing
3. **Schedule Shifts** (`/app/map/shifts`)
- Create shift with cut assignment
- Set date/time/capacity
- Email all volunteers
- Monitor signups
4. **Monitor Canvassing** (`/app/canvass/dashboard`)
- View active sessions
- Track visit progress
- Check leaderboard
- Review activity feed
5. **Print Materials** (`/app/canvass/walk-sheet`)
- Select cut
- Generate walk sheet PDF
- QR codes for quick access
- Browser print
### Volunteer Experience
1. **View Assignments** (`/volunteer/assignments`)
- See upcoming shifts
- Cut information
- Start canvass button
2. **Canvass** (`/volunteer/canvass/:cutId`)
- Full-screen map with GPS
- Follow walking route
- Click markers to record visits
- Select outcomes + notes
- Track progress
3. **Review Activity** (`/volunteer/activity`)
- Visit history
- Outcome breakdown
- Session statistics
### Public Experience
1. **View Map** (`/map`)
- Browse locations
- View cuts
- See visit status (color-coded)
- Geolocate self
2. **Sign Up for Shifts** (`/shifts`)
- Browse available shifts
- Signup with email
- Receive confirmation
## Architecture
### Backend Components
**Modules:**
- `api/src/modules/map/locations/` - Location CRUD + geocoding + NAR import
- `api/src/modules/map/geocoding/` - Multi-provider geocoding service
- `api/src/modules/map/cuts/` - Polygon CRUD + spatial queries
- `api/src/modules/map/shifts/` - Shift CRUD + signups
- `api/src/modules/map/canvass/` - Session + visit tracking
- `api/src/modules/map/tracking/` - GPS tracking (future)
- `api/src/modules/map/settings/` - Map settings singleton
**Services:**
- `api/src/services/geocoding.service.ts` - Geocoding abstraction
- `api/src/services/geocode-queue.service.ts` - Async geocoding
**Utilities:**
- `api/src/utils/spatial.ts` - Point-in-polygon, haversine, bounds, centroid
**Database Models:**
- `Location` - Address, coordinates, metadata, visit tracking
- `Cut` - Name, GeoJSON polygon
- `Shift` - Date/time, cut, capacity, signups
- `CanvassSession` - Session tracking, start/end times
- `CanvassVisit` - Visit outcomes, notes, GPS
- `MapSettings` - Map center/zoom, walk sheet config
### Frontend Components
**Admin Pages:**
- `admin/src/pages/LocationsPage.tsx` - Location management
- `admin/src/pages/CutsPage.tsx` - Cut management
- `admin/src/pages/ShiftsPage.tsx` - Shift management
- `admin/src/pages/CanvassDashboardPage.tsx` - Canvass monitoring
- `admin/src/pages/WalkSheetPage.tsx` - Printable materials
- `admin/src/pages/DataQualityDashboardPage.tsx` - Quality metrics
**Public Pages:**
- `admin/src/pages/public/MapPage.tsx` - Public map
- `admin/src/pages/public/ShiftsPage.tsx` - Shift signup
**Volunteer Pages:**
- `admin/src/pages/volunteer/VolunteerMapPage.tsx` - GPS canvass map
- `admin/src/pages/volunteer/VolunteerShiftsPage.tsx` - Assignments
- `admin/src/pages/volunteer/MyActivityPage.tsx` - Activity history
**Map Components:**
- `admin/src/components/map/MapControls.tsx` - Control buttons
- `admin/src/components/map/AddLocationMode.tsx` - Click-to-add
- `admin/src/components/map/CutDrawingMode.tsx` - Polygon drawing
- `admin/src/components/map/CutOverlays.tsx` - GeoJSON rendering
**Canvass Components:**
- `admin/src/components/canvass/GPSTracker.tsx` - GPS tracking
- `admin/src/components/canvass/WalkingRouteLine.tsx` - Route display
- `admin/src/components/canvass/VisitRecordingForm.tsx` - Outcome form
## Configuration
### Environment Variables
```bash
# Geocoding Providers
MAPBOX_ACCESS_TOKEN=pk_...
GOOGLE_GEOCODE_API_KEY=...
PELIAS_API_URL=http://pelias:4000
# NAR Import
NAR_DATA_DIR=/data # NAR file directory (Docker volume)
# Map Settings
MAP_DEFAULT_LAT=43.65 # Default map center
MAP_DEFAULT_LNG=-79.38
MAP_DEFAULT_ZOOM=12
```
### Map Settings
Configurable via admin UI (`/app/map/settings`):
- Default map center (lat/lng)
- Default zoom level
- Walk sheet header/footer
- Display preferences
## Geocoding
### Supported Providers
1. **Nominatim** (OpenStreetMap) - Free, rate limited
2. **ArcGIS** - Free tier available
3. **Photon** - Free, self-hosted option
4. **Mapbox** - API key required
5. **Google Geocoding** - API key required
6. **Pelias** - Self-hosted option
### Geocoding Strategy
1. Try provider 1 (Nominatim)
2. If fails, try provider 2 (ArcGIS)
3. Continue through providers
4. Cache successful results
5. Track quality metrics
### Bulk Geocoding
- BullMQ queue for async processing
- Batch processing (100 locations/batch)
- Provider rotation to avoid rate limits
- Progress tracking
- Error handling and retry
## NAR Import
Canadian electoral data (NAR 2025 format):
- **Address files** - Civic addresses with coordinates (EPSG:3347)
- **Location files** - Building locations with lat/lng
- **Join on LOC_GUID** - Combine address + coordinates
- **Server-side streaming** - Memory-efficient for large files
- **Filters** - Province, city, postal code, cut, residential-only
**Import Flow:**
1. Scan NAR data directory
2. List available provinces
3. Stream Address + Location files
4. Join on LOC_GUID
5. Transform coordinates (proj4)
6. Filter and insert locations
## Spatial Algorithms
### Point-in-Polygon
Ray-casting algorithm:
- Count ray intersections with polygon edges
- Odd count = inside, even count = outside
- Supports holes in polygons
- Used for cut assignment
### Walking Route
Nearest-neighbor algorithm:
1. Start at closest location to shift start point
2. For each location:
- Find nearest unvisited location
- Add to route
- Mark as visited
3. Return ordered list
### Haversine Distance
Great-circle distance between coordinates:
- Returns distance in kilometers
- Used for proximity sorting
- Route optimization
## API Endpoints
### Locations
```
GET /api/locations # List locations
POST /api/locations # Create location
GET /api/locations/:id # Get location
PATCH /api/locations/:id # Update location
DELETE /api/locations/:id # Delete location
POST /api/locations/import # CSV import
GET /api/locations/export # CSV export
POST /api/locations/geocode # Bulk geocode
```
### Cuts
```
GET /api/cuts # List cuts
POST /api/cuts # Create cut
GET /api/cuts/:id # Get cut
PATCH /api/cuts/:id # Update cut
DELETE /api/cuts/:id # Delete cut
POST /api/cuts/:id/assign-locations # Assign locations
```
### Shifts
```
GET /api/shifts # List shifts
POST /api/shifts # Create shift
GET /api/shifts/:id # Get shift
PATCH /api/shifts/:id # Update shift
DELETE /api/shifts/:id # Delete shift
POST /api/shifts/:id/signup # Signup for shift
```
### Canvassing
```
POST /api/canvass/session/start # Start session
POST /api/canvass/session/end # End session
GET /api/canvass/session # Get active session
POST /api/canvass/visit # Record visit
GET /api/canvass/route/:cutId # Get walking route
GET /api/canvass/dashboard # Dashboard stats
```
## Related Documentation
- [Locations](locations.md)
- [Geocoding](geocoding.md)
- [NAR Import](nar-import.md)
- [Cuts](cuts.md)
- [Shifts](shifts.md)
- [Canvassing](canvassing.md)
- [Walk Sheets](walk-sheets.md)
- [Data Quality](data-quality.md)
- [Backend Locations Module](../../backend/modules/locations.md)
- [Backend Canvass Module](../../backend/modules/canvass.md)
- [Spatial Utilities](../../backend/utilities/index.md)
- [Map Organizer Guide](../../user-guides/map-organizer-guide.md)
- [Volunteer Guide](../../user-guides/volunteer-guide.md)