mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-22 12:11:17 -05:00
Refactor Location model to integrate PostGIS for spatial data, add legacy coordinate fields for compatibility, and enhance documentation for geocoding service implementation.
This commit is contained in:
156
memory-bank/traits/HasLocation.md
Normal file
156
memory-bank/traits/HasLocation.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user