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

156 lines
4.3 KiB
Markdown

# 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