turash/bugulma/backend/internal/geospatial
2025-12-14 00:10:20 +01:00
..
bearing_calculator_test.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
bearing_calculator.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
bounding_box_test.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
bounding_box.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
calculator_test.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
calculator.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
config_test.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
config.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
coordinate_transformer.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
distance_calculator_test.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
distance_calculator.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
errors.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
factory.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
geo_helper_test.go Remove Turash brand identity and guidelines document 2025-12-14 00:10:20 +01:00
geo_helper.go Remove Turash brand identity and guidelines document 2025-12-14 00:10:20 +01:00
postgis_integration.go Remove Turash brand identity and guidelines document 2025-12-14 00:10:20 +01:00
README.md Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
spatial_validator.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00
types.go Major repository reorganization and missing backend endpoints implementation 2025-11-25 06:01:16 +01:00

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

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

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

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

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

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

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:

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:

// 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