// Package geo turns a timezone or an IP into a point on the globe and picks // the nearest of a set of AWS regions (nearest-region spec ยง6). It holds // points only for the length of one call: nothing here stores, logs or // returns a caller's coordinates. package geo import "math" // Point is a latitude and longitude in degrees. type Point struct{ Lat, Lon float64 } // earthRadiusKm is the IUGG mean Earth radius. const earthRadiusKm = 6371.0088 // DistanceKm is the great-circle (haversine) distance between a and b. func DistanceKm(a, b Point) float64 { rad := func(d float64) float64 { return d * math.Pi / 180 } dLat := rad(b.Lat - a.Lat) dLon := rad(b.Lon - a.Lon) h := math.Sin(dLat/2)*math.Sin(dLat/2) + math.Cos(rad(a.Lat))*math.Cos(rad(b.Lat))*math.Sin(dLon/2)*math.Sin(dLon/2) return 2 * earthRadiusKm * math.Asin(math.Sqrt(h)) }