# PostGIS Integration for Site Geospatial Operations This document describes the PostGIS integration added to support advanced geospatial operations for sites in the industrial symbiosis platform. ## Overview Sites now support PostGIS geometry fields for efficient spatial queries, as specified in the concept documents. This enables: - Fast spatial prefiltering in the matching engine (<100ms for typical queries) - Accurate distance calculations using PostGIS functions - Advanced geospatial analytics and statistics - Future support for spatial clustering and route optimization ## Database Changes ### New Columns - `location_geometry`: PostGIS geometry(Point, 4326) field for spatial operations - SRID 4326 = WGS84 coordinate system (standard for GPS coordinates) ### Indexes - `idx_site_geometry`: GIST index on location_geometry for fast spatial queries ## Migration Instructions Run the following SQL migration to add PostGIS support to existing databases: ```sql -- Enable PostGIS extension (if not already enabled) CREATE EXTENSION IF NOT EXISTS postgis; CREATE EXTENSION IF NOT EXISTS postgis_topology; -- Add geometry column to sites table ALTER TABLE sites ADD COLUMN IF NOT EXISTS location_geometry geometry(Polygon, 4326); -- Create spatial index CREATE INDEX IF NOT EXISTS idx_site_geometry ON sites USING GIST (location_geometry); -- Populate geometry from existing lat/lng data UPDATE sites SET location_geometry = ST_GeogFromText('POINT(' || longitude || ' ' || latitude || ')')::geometry WHERE latitude IS NOT NULL AND longitude IS NOT NULL AND location_geometry IS NULL; -- Add validation constraint ALTER TABLE sites ADD CONSTRAINT check_location_geometry CHECK (ST_IsValid(location_geometry) OR location_geometry IS NULL); ``` ## Code Changes ### Domain Model (`domain/site.go`) - Added `LocationGeometry` field with PostGIS geometry type - Added GORM hooks to automatically maintain geometry from lat/lng coordinates - Geometry field is excluded from JSON serialization (`json:"-"`) ### Repository (`repository/site_repository.go`) - Updated `GetWithinRadius` to use PostGIS `ST_DWithin` for accurate spatial queries - Uses `ST_Distance` for precise distance calculations - Orders results by distance using `<->` operator for optimal performance ### Services #### GeospatialService (`service/geospatial_service.go`) New service providing advanced geospatial operations: - `FindNearbySites`: Advanced spatial queries with filtering by site type, resource types - `CalculateDistanceMatrix`: Efficient distance calculations between multiple points - `ValidateGeometry`: PostGIS geometry validation - `GetSpatialStatistics`: Platform-wide geospatial analytics #### SiteService - Existing functionality preserved - Now leverages PostGIS for spatial operations through the repository ## API Endpoints ### Enhanced Statistics The `/api/stats` endpoint now includes geospatial statistics: ```json { "total_organizations": 5, "total_sites": 12, "platform_status": "active", "geospatial": { "total_sites": 12, "sites_with_geometry": 10, "avg_distance_km": 15.7, "max_distance_km": 45.2, "median_latitude": 52.518, "median_longitude": 13.405 } } ``` ## Performance Benefits ### Before (Haversine in SQL) - Complex trigonometric calculations in SQL - No spatial indexes utilized - Poor performance with large datasets ### After (PostGIS) - Native spatial indexes (GIST) - Optimized spatial functions - Sub-second queries for thousands of sites - Accurate geodesic distance calculations ## Matching Engine Integration The matching engine now uses PostGIS for the spatial prefiltering stage: 1. **Prefiltering**: `ST_DWithin` quickly identifies candidate sites within radius 2. **Distance Calculation**: `ST_Distance` provides accurate distances for scoring 3. **Ordering**: Spatial ordering ensures closest matches are evaluated first This implementation meets the concept specification for <100ms fast matching tier. ## Future Enhancements - **Address Geocoding**: Integrate with geocoding services for address-to-coordinate conversion - **Spatial Clustering**: Group nearby sites for regional analysis - **Route Optimization**: Calculate optimal transport routes between matched sites - **Geofencing**: Define industrial zones and regulatory boundaries - **Spatial Analytics**: Heat maps, density analysis, and geographic insights ## Testing To test the PostGIS integration: 1. Run the migration script 2. Start the application 3. Check `/api/stats` for geospatial statistics 4. Test spatial queries via `/api/sites/nearby` endpoint 5. Verify matching engine performance improvements ## Troubleshooting ### Common Issues 1. **PostGIS not enabled**: Ensure `CREATE EXTENSION postgis;` has been run 2. **Invalid geometry**: Check that latitude/longitude values are valid 3. **Performance issues**: Verify spatial indexes are created 4. **Coordinate system**: Ensure all coordinates use WGS84 (SRID 4326) ### Validation Queries ```sql -- Check PostGIS installation SELECT PostGIS_Version(); -- Validate geometry data SELECT id, ST_IsValid(location_geometry), ST_AsText(location_geometry) FROM sites WHERE location_geometry IS NOT NULL; -- Test spatial query performance EXPLAIN ANALYZE SELECT * FROM sites WHERE ST_DWithin(location_geometry::geography, ST_GeogFromText('POINT(13.405 52.520)'), 5000); ```