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
- Manual Address Entry: Users must type complete addresses without intelligent suggestions
- No Address Validation: System doesn't validate if an address actually exists
- No Visual Confirmation: Users can't see where the project is located on a map
- Ambiguous Addresses: No way to disambiguate similar street names or addresses
- Poor Mobile Experience: Chrome autocomplete alone isn't sufficient on mobile devices
Goals
Primary Goals
- Intelligent Address Autocomplete: Provide Google Places-powered address suggestions as users type
- Visual Location Confirmation: Display project location on an interactive Google Map
- Preserve Existing Behavior: Keep Chrome's native autocomplete alongside Google suggestions
- Mobile-Friendly: Ensure excellent experience on tablets and mobile devices
Secondary Goals
- Address Validation: Validate addresses against Google Places database
- Geocoding: Store latitude/longitude for projects with addresses
- 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
-
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)
- Service:
-
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)
- Service:
-
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:
-
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
- Loads Google Maps JavaScript API using
-
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:
- User clicks "Edit" on Project Metadata card
- Google Places Autocomplete attaches to street address input
- User types address → sees dropdown suggestions from Google Places
- User selects suggestion → form fields auto-populate (city, state, zip)
- User clicks "Save" → address geocoded if not already done
- 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:
- Update
ProjectAddressproto message (shown above) - No changes to
ProjectMetadataService- fields are optional and automatically handled - Update
project-metadata.jsonschema 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
-
Create Google Cloud Project
- Go to Google Cloud Console
- Create new project: "CodeProof Maps Integration"
-
Enable APIs
- Enable Maps JavaScript API
- Enable Places API (includes Autocomplete and Geocoding)
-
Create API Key
- Generate restricted API key
- Set application restrictions (HTTP referrers)
- Set API restrictions (only Maps JavaScript API and Places API)
-
Set Usage Quotas
- Set daily quota limits to control costs
- Enable billing alerts
-
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
-
API Key Security
- Restrict API key to specific domains
- Use separate keys for dev/staging/prod
- Rotate keys periodically
- Monitor for unauthorized usage
-
Data Privacy
- Don't send sensitive data to Google
- Follow Google Maps Platform terms of service
- Inform users about Google Maps usage (privacy policy)
-
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
tiltandheadingparameters - 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).
-
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
-
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
-
Building Code Lookup: Suggest applicable building codes by location
- Server-side: Cross-reference address with building code database
- Combine with jurisdiction data
-
Nearby Projects: Show other projects in the same area
- Server-side: Distance calculations using Geocoding API
- Display projects within X miles radius
-
Address Validation: Server-side address validation before save
- Backend validates address exists via Geocoding API
- Prevents invalid addresses from being saved
-
Address History: Remember recent addresses for quick selection
- Client-side: Store in browser localStorage
- No API key needed
-
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)
-
Drawing Tools: Allow users to draw lot boundaries on map
- Client-side: Google Maps Drawing Library
- Use existing browser API key
-
Distance Measurement: Measure distances and areas on map
- Client-side: Geometry library calculations
- Use existing browser API key
-
Sun Path Visualization: Show sun angles and shadows (for solar/daylighting)
- Client-side: SunCalc library + map overlay
- Use existing browser API key
-
Flood Zone Overlay: Display FEMA flood zones
- Client-side: Load FEMA GeoJSON data
- Overlay on existing map
-
Zoning Overlay: Display zoning boundaries (if available)
- Server-side: Fetch zoning data from local AHJ APIs
- Client-side: Render on map
Open Questions
- Should we batch-geocode existing projects without lat/lng?
- Should we show a warning if address changes significantly?
- Should we cache geocoding results to reduce API calls?
- Should we add a "Verify Address" button separate from save?
- Should we support international addresses beyond USA?