# 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 ### Distance & Search - `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 ```php use App\Traits\HasLocation; class Park extends Model { use HasLocation; } ``` ### Managing Locations with PostGIS ```php // 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 ```php // 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) ### Related Components - 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