10 KiB

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)

    • 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

# 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