# 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