mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 11:51:11 -05:00
156 lines
4.3 KiB
Markdown
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 |