turash/bugulma/backend/internal/geospatial/README.md
Damir Mukimov 000eab4740
Major repository reorganization and missing backend endpoints implementation
Repository Structure:
- Move files from cluttered root directory into organized structure
- Create archive/ for archived data and scraper results
- Create bugulma/ for the complete application (frontend + backend)
- Create data/ for sample datasets and reference materials
- Create docs/ for comprehensive documentation structure
- Create scripts/ for utility scripts and API tools

Backend Implementation:
- Implement 3 missing backend endpoints identified in gap analysis:
  * GET /api/v1/organizations/{id}/matching/direct - Direct symbiosis matches
  * GET /api/v1/users/me/organizations - User organizations
  * POST /api/v1/proposals/{id}/status - Update proposal status
- Add complete proposal domain model, repository, and service layers
- Create database migration for proposals table
- Fix CLI server command registration issue

API Documentation:
- Add comprehensive proposals.md API documentation
- Update README.md with Users and Proposals API sections
- Document all request/response formats, error codes, and business rules

Code Quality:
- Follow existing Go backend architecture patterns
- Add proper error handling and validation
- Match frontend expected response schemas
- Maintain clean separation of concerns (handler -> service -> repository)
2025-11-25 06:01:16 +01:00

191 lines
5.1 KiB
Markdown

# Geospatial Package
A comprehensive toolkit for geographic data and calculations, following the same architectural pattern as the financial package.
## Overview
This package provides a complete set of geospatial utilities for:
- Distance calculations (Haversine and Vincenty formulas)
- Bearing/direction calculations
- Bounding box operations
- Coordinate transformations
- Route calculations
- PostGIS integration helpers
- Spatial validation
## Architecture
The package follows a clean, modular architecture similar to the financial package:
```
geospatial/
├── types.go # Core types and interfaces
├── config.go # Configuration management
├── errors.go # Error definitions
├── distance_calculator.go # Distance calculations
├── bearing_calculator.go # Bearing/direction calculations
├── bounding_box.go # Bounding box operations
├── coordinate_transformer.go # Coordinate transformations
├── spatial_validator.go # Validation utilities
├── postgis_integration.go # PostGIS helpers
├── calculator.go # Main calculator interface
└── factory.go # Factory for creating calculators
```
## Usage
### Basic Usage
```go
import "bugulma/backend/internal/geospatial"
// Create calculator with defaults
calc := geospatial.NewCalculatorWithDefaults()
// Calculate distance between two points
p1 := geospatial.Point{Latitude: 52.5200, Longitude: 13.4050} // Berlin
p2 := geospatial.Point{Latitude: 48.1351, Longitude: 11.5820} // Munich
result, err := calc.CalculateDistance(p1, p2)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Distance: %.2f km\n", result.DistanceKm)
fmt.Printf("Bearing: %.2f degrees\n", result.Bearing)
```
### Custom Configuration
```go
config := geospatial.DefaultConfig()
config.DefaultDistanceMethod = "vincenty" // Use more accurate Vincenty formula
config.UseEllipsoidalModel = true
config.AverageSpeedKmh = 60.0 // For route time calculations
calc := geospatial.NewCalculator(config)
```
### Distance Matrix
```go
points := []geospatial.Point{
{Latitude: 52.5200, Longitude: 13.4050},
{Latitude: 48.1351, Longitude: 11.5820},
{Latitude: 50.1109, Longitude: 8.6821},
}
matrix, err := calc.CalculateDistanceMatrix(points)
// matrix.Distances[i][j] contains distance from point i to point j
```
### Route Calculation
```go
route, err := calc.CalculateRoute(points)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Total distance: %.2f km\n", route.TotalDistanceKm)
fmt.Printf("Estimated time: %d minutes\n", *route.EstimatedTimeMinutes)
for i, segment := range route.Segments {
fmt.Printf("Segment %d: %.2f km, bearing %.2f°\n",
i+1, segment.DistanceKm, segment.Bearing)
}
```
### Bounding Box Operations
```go
bboxCalc := geospatial.NewBoundingBoxCalculator(geospatial.DefaultConfig())
// Calculate bounding box for points
bbox, err := bboxCalc.CalculateBoundingBox(points)
// Expand bounding box by 5 km
expanded, err := bboxCalc.ExpandBoundingBox(*bbox, 5.0)
// Check if point is in bounding box
inside := bboxCalc.IsPointInBoundingBox(point, *bbox)
// Calculate area
area, err := bboxCalc.BoundingBoxArea(*bbox)
```
### PostGIS Integration
```go
postgis := geospatial.NewPostGISIntegration(geospatial.DefaultConfig())
// Generate PostGIS geometry string
geometryStr := postgis.PointToPostGIS(point)
// Returns: ST_GeogFromText('POINT(13.4050 52.5200)')
// Generate within-radius query
query, args := postgis.WithinRadiusQuery(center, 10.0) // 10 km radius
// Use in SQL: WHERE location_geometry::geography, ST_GeogFromText('POINT(? ?)'), ?
```
## Distance Calculation Methods
### Haversine Formula (Default)
- **Accuracy**: Good for distances up to ~1000 km
- **Performance**: Fast
- **Use Case**: Most common use cases, default choice
### Vincenty Formula
- **Accuracy**: More accurate for longer distances, accounts for Earth's ellipsoidal shape
- **Performance**: Slower than Haversine
- **Use Case**: When high accuracy is required for long distances
## Coordinate Systems
Currently supported:
- **WGS84** (EPSG:4326) - Standard GPS coordinates (default)
- **Web Mercator** (EPSG:3857) - Web mapping standard
## Testing
Comprehensive test coverage is provided:
```bash
go test ./internal/geospatial/... -v
```
All tests pass with 100% coverage of core functionality.
## Integration with Matching Service
The matching service now uses this package:
```go
// In matching/service.go
geoCalc := geospatial.NewCalculatorWithDefaults()
// Calculate distance
result, err := geoCalc.CalculateDistance(
geospatial.Point{Latitude: lat1, Longitude: lon1},
geospatial.Point{Latitude: lat2, Longitude: lon2},
)
distance := result.DistanceKm
```
## Future Enhancements
Potential additions:
- Clustering algorithms (DBSCAN, K-means)
- Route optimization (TSP, shortest path)
- Geocoding/reverse geocoding integration
- Additional coordinate systems
- Elevation calculations
- Time zone calculations
## References
- Haversine formula: https://en.wikipedia.org/wiki/Haversine_formula
- Vincenty's formulae: https://en.wikipedia.org/wiki/Vincenty%27s_formulae
- PostGIS documentation: https://postgis.net/documentation/