51 lines
1.2 KiB
Go
51 lines
1.2 KiB
Go
package geo
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"git.leaktechnologies.dev/Leak_Technologies/Skyfeed/internal/config"
|
|
)
|
|
|
|
// FindNearestTown loads the cached towns.json and finds the closest town to given coordinates.
|
|
func FindNearestTown(lat, lon float64) (Town, error) {
|
|
townsPath := filepath.Join(config.DataDir, "towns.json")
|
|
|
|
data, err := os.ReadFile(townsPath)
|
|
if err != nil {
|
|
return Town{}, fmt.Errorf("failed to read town index: %w", err)
|
|
}
|
|
|
|
var towns []Town
|
|
if err := json.Unmarshal(data, &towns); err != nil {
|
|
return Town{}, fmt.Errorf("failed to parse towns.json: %w", err)
|
|
}
|
|
|
|
if len(towns) == 0 {
|
|
return Town{}, fmt.Errorf("no towns found in index")
|
|
}
|
|
|
|
minDist := math.MaxFloat64
|
|
var nearest Town
|
|
|
|
for _, t := range towns {
|
|
d := Haversine(lat, lon, t.Lat, t.Lon)
|
|
if d < minDist {
|
|
minDist = d
|
|
nearest = t
|
|
}
|
|
}
|
|
|
|
if nearest.Name == "" {
|
|
return Town{}, fmt.Errorf("no nearby town found")
|
|
}
|
|
|
|
fmt.Printf("[geo] Nearest town: %s, %s (%.2f km)\n",
|
|
nearest.Name, nearest.Province, minDist)
|
|
|
|
return nearest, nil
|
|
}
|