Skip to main content

PRD: Google Maps Integration for Project Address

📋 Parent Issue: Issue #227 - Project Metadata Management - Phase 1

Overview

This PRD defines the requirements for integrating Google Maps services into the Project Settings UI to enhance the address entry and visualization experience. This is a Phase 1.5 enhancement that builds on top of the completed Phase 1 metadata management implementation.

Problem Statement

Current State

  • ✅ Project metadata editing is implemented (Issue #227 - Phase 1)
  • ✅ Address fields are editable (street, city, state, postal code, country)
  • ✅ Chrome browser autocomplete works for address fields (native HTML behavior)
  • ❌ No intelligent address suggestions from Google Places database
  • ❌ No visual confirmation of project location on a map
  • ❌ Users must manually enter complete, correctly formatted addresses

User Pain Points

  1. Manual Address Entry: Users must type complete addresses without intelligent suggestions
  2. No Address Validation: System doesn't validate if an address actually exists
  3. No Visual Confirmation: Users can't see where the project is located on a map
  4. Ambiguous Addresses: No way to disambiguate similar street names or addresses
  5. Poor Mobile Experience: Chrome autocomplete alone isn't sufficient on mobile devices

Goals

Primary Goals

  1. Intelligent Address Autocomplete: Provide Google Places-powered address suggestions as users type
  2. Visual Location Confirmation: Display project location on an interactive Google Map
  3. Preserve Existing Behavior: Keep Chrome's native autocomplete alongside Google suggestions
  4. Mobile-Friendly: Ensure excellent experience on tablets and mobile devices

Secondary Goals

  1. Address Validation: Validate addresses against Google Places database
  2. Geocoding: Store latitude/longitude for projects with addresses
  3. Future-Ready: Foundation for location-based features (nearby projects, jurisdiction lookup)

Non-Goals

  • Address history or favorites
  • Bulk address updates
  • Custom map markers or overlays
  • Directions or routing features
  • Street View integration
  • Multiple project location markers on one map

User Stories

Story 1: Google Places Address Autocomplete

As a project owner
I want to see address suggestions from Google Places as I type
So that I can quickly enter accurate, validated addresses

Acceptance Criteria:

  • Google Places Autocomplete dropdown appears below the street address field when typing
  • Suggestions appear after typing 3+ characters
  • Suggestions are restricted to USA addresses (configurable by country field)
  • Selecting a suggestion auto-fills street, city, state, and postal code fields
  • Chrome's native autocomplete remains functional and doesn't conflict
  • Autocomplete respects Material Design styling
  • Works on desktop, tablet, and mobile devices
  • API errors are handled gracefully with fallback to manual entry

Story 2: Interactive Map Widget

As a project owner
I want to see my project location on a map
So that I can visually confirm the project address is correct

Acceptance Criteria:

  • Map card appears to the right of Project Metadata card (responsive layout)
  • Map displays project location if address is complete and geocodable
  • Map shows "Address not available" state if no address is set
  • Map shows "Unable to geocode address" state if address is invalid
  • Map marker is centered on the project address
  • Map is interactive (pan, zoom) but read-only (no dragging marker)
  • Map uses appropriate zoom level (default: street level ~15-17)
  • Map respects Material Design card styling
  • Map loads asynchronously and shows loading indicator

Story 3: Address Geocoding

As a system
I want to automatically geocode project addresses
So that I can store precise location data for future features

Acceptance Criteria:

  • When user selects a Google Places suggestion, store the place_id
  • Automatically geocode the address using Google Geocoding API
  • Store latitude and longitude in project metadata
  • Store formatted address from Google (for consistency)
  • Geocoding happens in background (non-blocking UI)
  • Failed geocoding doesn't block metadata save
  • Geocoding result is cached (don't re-geocode on every page load)
  • Re-geocode when address is edited

Technical Design

📘 Implementation Details: This section provides a high-level technical overview suitable for product planning. For detailed implementation code, component architecture, and testing strategies, see the Technical Design Document (TDD).

Google Maps APIs Required

  1. Places Autocomplete API

    • Service: https://maps.googleapis.com/maps/api/js?key=API_KEY&libraries=places
    • Purpose: Address suggestions as user types
    • Pricing: $2.83 per 1,000 sessions (first 100k sessions free)
  2. Maps JavaScript API

    • Service: https://maps.googleapis.com/maps/api/js?key=API_KEY
    • Purpose: Display interactive map
    • Pricing: $7.00 per 1,000 loads (first 28k loads free)
  3. Geocoding API (optional - can use Places Geocoder)

    • Service: Client-side via Maps JavaScript API
    • Purpose: Convert address to lat/lng
    • Pricing: Included in Places API quota

Proto Schema Changes

Update ProjectAddress message in src/main/proto/api.proto:

// Message representing project address
message ProjectAddress {
string street = 1;
string city = 2;
string state = 3;
string postal_code = 4;
string country = 5; // Default: "USA"

// Google Maps metadata (optional)
string google_place_id = 6; // Google Places ID for validation
double latitude = 7; // Geocoded latitude
double longitude = 8; // Geocoded longitude
string formatted_address = 9; // Google's formatted address
}

Frontend Implementation

📘 Detailed Implementation: See Technical Design Document for complete code examples.

Component Architecture

New Components:

  1. GoogleMapsService - Centralized service for Google Maps API interactions

    • Loads Google Maps JavaScript API using @googlemaps/js-api-loader
    • Creates Places Autocomplete instances
    • Provides geocoding utilities
    • Handles API errors gracefully
  2. ProjectLocationMapComponent - Standalone map widget

    • Displays interactive Google Map
    • Shows project location marker
    • Handles loading, error, and "no address" states
    • Responsive Material Design card

Enhanced Components: 3. ProjectSettingsComponent - Integrates autocomplete and map

  • Attaches Google Places Autocomplete to street address input
  • Parses place selection and auto-fills form fields
  • Geocodes address on save
  • Updates map display after metadata changes

User Experience Flow

Address Entry Workflow:

  1. User clicks "Edit" on Project Metadata card
  2. Google Places Autocomplete attaches to street address input
  3. User types address → sees dropdown suggestions from Google Places
  4. User selects suggestion → form fields auto-populate (city, state, zip)
  5. User clicks "Save" → address geocoded if not already done
  6. Map widget updates to show new location

Key UX Considerations:

  • Dual Autocomplete: Chrome's native autocomplete AND Google Places work together
  • Graceful Degradation: If Google Maps API fails, users can still enter addresses manually
  • Non-Blocking Geocoding: Failed geocoding doesn't prevent metadata save
  • Responsive Layout: Two-column grid on desktop, stacks vertically on mobile

UI Layout Structure

Desktop Layout (Two-Column Grid):

┌──────────────────────┐  ┌──────────────────────┐
│ Project Metadata │ │ Project Location │
│ Card │ │ Map Widget │
│ │ │ │
│ [Edit Address] │ │ [Google Map] │
│ Street: [Input] │ │ • Marker │
│ ↓ autocomplete │ │ • Interactive │
│ [Auto-filled] │ │ • Pan/Zoom │
│ [Save] │ └──────────────────────┘
└──────────────────────┘

Mobile Layout (Stacked):

┌──────────────────────┐
│ Project Metadata │
│ Card │
└──────────────────────┘
┌──────────────────────┐
│ Project Location │
│ Map Widget │
└──────────────────────┘

Environment Configuration

Location: web-ng-m3/src/environments/environment.ts

export const environment = {
production: false,
googleMapsApiKey: 'YOUR_GOOGLE_MAPS_API_KEY_HERE',
// ... other environment variables
};

Location: web-ng-m3/src/environments/environment.prod.ts

export const environment = {
production: true,
googleMapsApiKey: 'YOUR_PRODUCTION_GOOGLE_MAPS_API_KEY',
// ... other environment variables
};

Backend Changes (Minimal)

The backend already supports the ProjectAddress message. Only need to add the new optional fields:

  1. Update ProjectAddress proto message (shown above)
  2. No changes to ProjectMetadataService - fields are optional and automatically handled
  3. Update project-metadata.json schema documentation

Chrome Autocomplete Coexistence

How It Works:

  • Street address input retains HTML5 autocomplete="street-address" attribute for Chrome
  • Google Places Autocomplete overlays its own dropdown
  • Chrome's native dropdown appears if Google Places API is unavailable
  • Both autocomplete methods can coexist without conflicts
  • Perfect graceful degradation for API failures

Benefits:

  • Users always have address suggestions (either Google or Chrome)
  • No breaking changes to existing HTML form semantics
  • Works offline with Chrome's saved addresses

API Key Management

Setup Steps

  1. Create Google Cloud Project

  2. Enable APIs

    • Enable Maps JavaScript API
    • Enable Places API (includes Autocomplete and Geocoding)
  3. Create API Key

    • Generate restricted API key
    • Set application restrictions (HTTP referrers)
    • Set API restrictions (only Maps JavaScript API and Places API)
  4. Set Usage Quotas

    • Set daily quota limits to control costs
    • Enable billing alerts
  5. Store Securely

    • Add to Secret Manager (production)
    • Add to environment variables (development)
    • Never commit to version control

Pricing Estimate

Assumptions:

  • 1,000 active projects per month
  • Each project visited 5 times/month
  • Address edited 2 times per project lifetime

Monthly Costs:

  • Places Autocomplete: 2,000 sessions × $2.83/1,000 = $5.66
  • Maps JavaScript API: 5,000 loads × $7.00/1,000 = $35.00
  • Total: ~$40/month

Free Tier:

  • First $200/month is free with Google Cloud credits
  • Result: $0/month for current usage

Testing Strategy

📘 Detailed Test Code: For complete unit test examples, integration test scripts, and E2E test specifications, see the Technical Design Document.

Testing Scope

Unit Tests (3 components):

  • GoogleMapsService - API loader, autocomplete creation, geocoding
  • ProjectLocationMapComponent - Map initialization, marker placement, state handling
  • ProjectSettingsComponent - Autocomplete integration, place selection, geocoding

Integration Tests:

  • End-to-end address entry flow (autocomplete → save → map update)
  • Fallback scenarios (API unavailable, network errors, geocoding failures)
  • Cross-browser compatibility (Chrome, Safari, Firefox, Edge)

Manual Testing Checklist:

  • Autocomplete appears on desktop Chrome
  • Autocomplete appears on mobile Safari
  • Chrome native autocomplete still works
  • Selecting suggestion fills all fields
  • Map displays after address is saved
  • Map shows correct location
  • Map is interactive (pan/zoom)
  • Map handles invalid addresses gracefully
  • Layout is responsive on tablet
  • Layout is responsive on mobile
  • API errors don't break the UI

Success Metrics

User Engagement

  • % of projects with complete addresses (target: 80%+)
  • % of address entries using Google Places (target: 60%+)
  • Average time to enter address (target: < 30 seconds)

System Performance

  • Map load time (target: < 2 seconds)
  • Autocomplete response time (target: < 300ms)
  • Geocoding success rate (target: > 95%)

API Usage

  • Daily Places API calls
  • Daily Maps API calls
  • Monthly cost vs. budget

Security Considerations

  1. API Key Security

    • Restrict API key to specific domains
    • Use separate keys for dev/staging/prod
    • Rotate keys periodically
    • Monitor for unauthorized usage
  2. Data Privacy

    • Don't send sensitive data to Google
    • Follow Google Maps Platform terms of service
    • Inform users about Google Maps usage (privacy policy)
  3. Input Validation

    • Validate all address components before saving
    • Sanitize user input
    • Prevent injection attacks

Future Enhancements

Phase 2: Enhanced Visualization Widgets

1. 3D Flyover Widget (High Priority)

Description: Add a Google Earth-style 3D aerial view widget as an additional card

User Value:

  • Understand site terrain and topography
  • See surrounding buildings and context
  • Visualize elevation changes and site access
  • Better spatial awareness for construction planning

Technical Approach:

  • Use Google Maps JavaScript API with tilt and heading parameters
  • Alternative: Embed Google Earth Web with Earth Engine API
  • Display in third card below/beside the 2D map
  • Allow interactive rotation and tilt control
  • Default to 45° tilt, aerial perspective

API Requirements:

  • Google Maps JavaScript API (already enabled)
  • Or: Google Earth Engine API (separate setup)
  • Pricing: Within existing Maps API quota

Example Use Cases:

  • Hillside construction projects (see slope)
  • Urban infill projects (see neighboring buildings)
  • Site access planning (see driveways, streets)
  • Solar panel planning (see roof orientation)

Layout:

┌────────────────────┐  ┌────────────────────┐
│ Project Metadata │ │ 2D Map (Current) │
└────────────────────┘ └────────────────────┘

┌─────────────────────────────────────────────┐
│ 3D Flyover View (Google Earth Style) │
│ • 45° aerial perspective │
│ • Interactive rotation │
│ • Terrain elevation display │
└─────────────────────────────────────────────┘

Implementation Complexity: Medium (3-5 days)

2. Street View Widget (Medium Priority)

Description: Add Google Street View widget as an additional card

User Value:

  • Ground-level view of project site
  • See street access and parking
  • Understand neighborhood character
  • Verify address location visually

Technical Approach:

  • Use Google Street View Service API
  • Display in fourth card (below 3D flyover)
  • Check Street View availability before displaying
  • Allow panning and rotation
  • Show "Street View unavailable" for rural/new areas

API Requirements:

  • Street View Service (included in Maps JavaScript API)
  • Pricing: Within existing Maps API quota

Layout:

┌────────────────────┐  ┌────────────────────┐
│ Project Metadata │ │ 2D Map │
└────────────────────┘ └────────────────────┘

┌─────────────────────────────────────────────┐
│ 3D Flyover View │
└─────────────────────────────────────────────┘

┌─────────────────────────────────────────────┐
│ Street View │
│ • Ground-level perspective │
│ • Interactive pan/rotate │
│ • Historical imagery (date selector) │
└─────────────────────────────────────────────┘

Implementation Complexity: Low-Medium (2-3 days)

Responsive Behavior:

  • Desktop: All widgets visible in grid
  • Tablet: Stack vertically, 2D map first
  • Mobile: Collapsible cards with 2D map as default

Phase 3: Smart Location Features (Server-Side Integration)

Note: These features may require a separate server-side API key with IP address restrictions (not domain referrer restrictions).

  1. Batch Geocoding: Retroactively geocode existing project addresses

    • Server-side: Process hundreds of addresses via backend
    • Requires: Server API key with Secret Manager + Cloud Run integration
  2. Jurisdiction Lookup: Auto-populate jurisdiction based on address

    • Server-side: Reverse geocode to determine AHJ (Authority Having Jurisdiction)
    • Could use Google Civic Information API or Places API
  3. Building Code Lookup: Suggest applicable building codes by location

    • Server-side: Cross-reference address with building code database
    • Combine with jurisdiction data
  4. Nearby Projects: Show other projects in the same area

    • Server-side: Distance calculations using Geocoding API
    • Display projects within X miles radius
  5. Address Validation: Server-side address validation before save

    • Backend validates address exists via Geocoding API
    • Prevents invalid addresses from being saved
  6. Address History: Remember recent addresses for quick selection

    • Client-side: Store in browser localStorage
    • No API key needed
  7. Custom Map Markers: Differentiate project types with custom icons

    • Client-side: Use existing browser API key
    • No additional setup needed

Server-Side API Key TODO:

When implementing server-side features, create a second API key with:

  • Display name: "Google Maps API Key - ${ENV} - Backend"
  • Restrictions: IP address restrictions (Cloud Run egress IPs)
  • Storage: Secret Manager with Cloud Run service account access
  • Mount: Environment variable in Cloud Run service

See TDD Section "Future Server-Side Considerations" for setup commands.

Phase 4: Advanced Planning Tools (Client-Side)

  1. Drawing Tools: Allow users to draw lot boundaries on map

    • Client-side: Google Maps Drawing Library
    • Use existing browser API key
  2. Distance Measurement: Measure distances and areas on map

    • Client-side: Geometry library calculations
    • Use existing browser API key
  3. Sun Path Visualization: Show sun angles and shadows (for solar/daylighting)

    • Client-side: SunCalc library + map overlay
    • Use existing browser API key
  4. Flood Zone Overlay: Display FEMA flood zones

    • Client-side: Load FEMA GeoJSON data
    • Overlay on existing map
  5. Zoning Overlay: Display zoning boundaries (if available)

    • Server-side: Fetch zoning data from local AHJ APIs
    • Client-side: Render on map

Open Questions

  1. Should we batch-geocode existing projects without lat/lng?
  2. Should we show a warning if address changes significantly?
  3. Should we cache geocoding results to reduce API calls?
  4. Should we add a "Verify Address" button separate from save?
  5. Should we support international addresses beyond USA?

References