// geodist is a package created by jftuga // Repository: github.com/jftuga/geodist // It is used to calculate distance between latitude/longitude points package geodist import "seekia/internal/helpers" import "errors" import "math" // The below function is adapted from github.com/jftuga/geodist // HaversineDistance returns the distance (in miles) between two points of // a given longitude and latitude relatively accurately (using a spherical // approximation of the Earth) through the Haversin Distance Formula for // great arc distance on a sphere with accuracy for small distances // // Point coordinates are supplied in degrees and converted into rad. // // https://en.wikipedia.org/wiki/Haversine_formula //Outputs: // -float64: Distance in kilometers // -error func GetDistanceBetweenCoordinates(aCoordinateLatitude float64, aCoordinateLongitude float64, bCoordinateLatitude float64, bCoordinateLongitude float64) (float64, error) { aLatitudeIsValid := helpers.VerifyLatitude(aCoordinateLatitude) if (aLatitudeIsValid == false){ return 0, errors.New("GetDistanceBetweenCoordinates called with invalid aCoordinateLatitude.") } aLongitudeIsValid := helpers.VerifyLongitude(aCoordinateLongitude) if (aLongitudeIsValid == false){ return 0, errors.New("GetDistanceBetweenCoordinates called with invalid aCoordinateLongitude.") } bLatitudeIsValid := helpers.VerifyLatitude(bCoordinateLatitude) if (bLatitudeIsValid == false){ return 0, errors.New("GetDistanceBetweenCoordinates called with invalid bCoordinateLatitude.") } bLongitudeIsValid := helpers.VerifyLongitude(bCoordinateLongitude) if (bLongitudeIsValid == false){ return 0, errors.New("GetDistanceBetweenCoordinates called with invalid bCoordinateLongitude.") } // Convert to radians piRad := math.Pi / 180 la1 := aCoordinateLatitude * piRad lo1 := aCoordinateLongitude * piRad la2 := bCoordinateLatitude * piRad lo2 := bCoordinateLongitude * piRad r := float64(6378100) // Earth radius in meters // haversin(θ) function hsin := func(theta float64) float64 { result := math.Pow(math.Sin(theta/2), 2) return result } h := hsin(la2-la1) + math.Cos(la1) * math.Cos(la2) * hsin(lo2-lo1) meters := 2 * r * math.Asin(math.Sqrt(h)) kilometers := meters / 1000 return kilometers, nil }