Files
thrillwiki_laravel/memory-bank/traits/HasLocation.md

4.3 KiB

HasLocation Trait

Overview

The HasLocation trait provides location management capabilities to Laravel models through a polymorphic relationship with the Location model. It enables models to have associated geographic data, including coordinates, address information, and location-based querying capabilities.

Features

Relationships

  • location() - MorphOne relationship to Location model
  • Automatic location deletion when parent model is deleted

Accessors

  • coordinates - Returns [lat, lng] array
  • formatted_address - Returns formatted address string
  • map_url - Returns Google Maps URL

Location Management

  • updateLocation(array $attributes) - Update or create location
  • setCoordinates(float $lat, float $lng, ?float $elevation) - Set coordinates
  • setAddress(array $components) - Set address components
  • distanceTo($model) - Calculate distance to another model
  • scopeNearby($query, $lat, $lng, $radius) - Find nearby models
  • scopeInBounds($query, $ne, $sw) - Find models within bounds

Usage

Adding Location Support

use App\Traits\HasLocation;

class Park extends Model
{
    use HasLocation;
}

Managing Locations with PostGIS

// Create/update location with PostGIS point
$park->updateLocation([
    'address' => '123 Main St',
    'city' => 'Orlando',
    'state' => 'FL',
    'country' => 'USA',
    'coordinates' => DB::raw("ST_SetSRID(ST_MakePoint(-81.379234, 28.538336), 4326)")
]);

// Set coordinates directly (automatically creates PostGIS point)
$park->setCoordinates(28.538336, -81.379234);

// Access location data (automatically extracts from PostGIS point)
$coordinates = $park->coordinates; // Returns [lat, lng]
$address = $park->formatted_address;
$mapUrl = $park->map_url;

PostGIS Spatial Queries

// Find parks within 50km using ST_DWithin
$nearbyParks = Park::nearby(28.538336, -81.379234, 50)->get();

// Find parks in bounds using ST_MakeEnvelope
$parksInArea = Park::inBounds(
    ['lat' => 28.6, 'lng' => -81.2], // Northeast
    ['lat' => 28.4, 'lng' => -81.4]  // Southwest
)->get();

// Calculate distance using ST_Distance
$distance = $parkA->distanceTo($parkB);

PostGIS Functions Used

  • ST_SetSRID - Set spatial reference system (4326 = WGS 84)
  • ST_MakePoint - Create point geometry from coordinates
  • ST_DWithin - Find points within distance
  • ST_MakeEnvelope - Create bounding box
  • ST_Within - Check if point is within bounds
  • ST_Distance - Calculate distance between points

Integration Points

Models Using Trait

  • Park
  • ParkArea
  • (Future models requiring location)
  • Location model
  • GeocodeService
  • LocationSearchService
  • LocationSelector component
  • LocationDisplay component

Implementation Notes

Design Decisions

  1. Automatic Cleanup

    • Location records are automatically deleted when parent is deleted
    • Prevents orphaned location records
    • Maintains referential integrity
  2. Flexible Updates

    • updateLocation() handles both create and update
    • Reduces code duplication
    • Provides consistent interface
  3. Coordinate Handling

    • Consistent lat/lng format
    • Optional elevation support
    • Null handling for incomplete data
  4. Query Scopes

    • Chainable with other queries
    • Consistent parameter formats
    • Performance-optimized implementation

Performance Considerations

  • Spatial indexing with PostGIS GiST index
  • Native PostGIS distance calculations
  • Geography vs Geometry type selection
    • Geography for accurate distance calculations
    • Geometry for faster bounding box queries
  • Efficient spatial joins using PostGIS functions
  • Eager loading recommended for lists
  • Optimized polymorphic relationships

Security

  • Input validation in setters
  • Coordinate bounds checking
  • Safe SQL distance calculations

Testing Strategy

Unit Tests

  • Relationship management
  • Coordinate handling
  • Address formatting
  • Distance calculations

Integration Tests

  • Location updates
  • Search queries
  • Boundary queries
  • Deletion cleanup

Future Enhancements

  1. Add elevation support
  2. Implement timezone handling
  3. Add boundary polygon support
  4. Create location history tracking
  5. Add batch location updates
  6. Implement geofencing
  7. Add location validation
  8. Create location sharing