Skip to content

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 - Location database with geocoding
  2. Geocoding - Multi-provider address → coordinate conversion
  3. NAR Import - Canadian electoral data import
  4. Cuts - Geographic polygon organization
  5. Shifts - Volunteer shift scheduling
  6. Canvassing - Door-to-door canvassing system
  7. Tracking - GPS tracking sessions
  8. Walk Sheets - Printable canvass materials
  9. Data Quality - 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)
  2. Upload CSV or NAR data
  3. Geocode addresses
  4. Review quality metrics
  5. Bulk operations

  6. Create Cuts (/app/map/cuts)

  7. Draw polygons on map
  8. Name and describe cut
  9. Assign locations (automatic)
  10. Export for printing

  11. Schedule Shifts (/app/map/shifts)

  12. Create shift with cut assignment
  13. Set date/time/capacity
  14. Email all volunteers
  15. Monitor signups

  16. Monitor Canvassing (/app/canvass/dashboard)

  17. View active sessions
  18. Track visit progress
  19. Check leaderboard
  20. Review activity feed

  21. Print Materials (/app/canvass/walk-sheet)

  22. Select cut
  23. Generate walk sheet PDF
  24. QR codes for quick access
  25. Browser print

Volunteer Experience

  1. View Assignments (/volunteer/assignments)
  2. See upcoming shifts
  3. Cut information
  4. Start canvass button

  5. Canvass (/volunteer/canvass/:cutId)

  6. Full-screen map with GPS
  7. Follow walking route
  8. Click markers to record visits
  9. Select outcomes + notes
  10. Track progress

  11. Review Activity (/volunteer/activity)

  12. Visit history
  13. Outcome breakdown
  14. Session statistics

Public Experience

  1. View Map (/map)
  2. Browse locations
  3. View cuts
  4. See visit status (color-coded)
  5. Geolocate self

  6. Sign Up for Shifts (/shifts)

  7. Browse available shifts
  8. Signup with email
  9. 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

# 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