// Bearing takes two points and finds the geographic bearing between them. func Bearing(point1, point2 *Point) float64 { lat1 := turfgoMath.DegreeToRad(point1.Lat) lat2 := turfgoMath.DegreeToRad(point2.Lat) lon1 := turfgoMath.DegreeToRad(point1.Lng) lon2 := turfgoMath.DegreeToRad(point2.Lng) a := math.Sin(lon2-lon1) * math.Cos(lat2) b := math.Cos(lat1)*math.Sin(lat2) - math.Sin(lat1)*math.Cos(lat2)*math.Cos(lon2-lon1) return turfgoMath.RadToDegree(math.Atan2(a, b)) }
// Distance calculates the distance between two points in degress, radians, miles, or // kilometers. This uses the Haversine formula to account for global curvature. func Distance(point1 *Point, point2 *Point, unit string) (float64, error) { radius, ok := R[unit] if !ok { return 0, fmt.Errorf(unitError, unit) } dLat := turfgoMath.DegreeToRad(point2.Lat - point1.Lat) dLon := turfgoMath.DegreeToRad(point2.Lng - point1.Lng) latRad1 := turfgoMath.DegreeToRad(point1.Lat) latRad2 := turfgoMath.DegreeToRad(point2.Lat) a := math.Sin(dLat/2)*math.Sin(dLat/2) + math.Sin(dLon/2)*math.Sin(dLon/2)*math.Cos(latRad1)*math.Cos(latRad2) c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a)) return radius * c, nil }
// Destination takes a Point and calculates the location of a destination point // given a distance in degrees, radians, miles, or kilometers; and bearing in // degrees. This uses the Haversine formula to account for global curvature. func Destination(startingPoint *Point, distance float64, bearing float64, unit string) (*Point, error) { radius, ok := R[unit] if !ok { return nil, fmt.Errorf(unitError, unit) } lat := turfgoMath.DegreeToRad(startingPoint.Lat) lon := turfgoMath.DegreeToRad(startingPoint.Lng) bearingRad := turfgoMath.DegreeToRad(bearing) destLat := math.Asin(math.Sin(lat)*math.Cos(distance/radius) + math.Cos(lat)*math.Sin(distance/radius)*math.Cos(bearingRad)) destLon := lon + math.Atan2(math.Sin(bearingRad)*math.Sin(distance/radius)*math.Cos(lat), math.Cos(distance/radius)-math.Sin(lat)*math.Sin(destLat)) return &Point{turfgoMath.RadToDegree(destLat), turfgoMath.RadToDegree(destLon)}, nil }
func translate(point *Point, horizontalDisplacement float64, verticalDisplacement float64) *Point { latDisplacementRad := verticalDisplacement / R["m"] longDisplacementRad := horizontalDisplacement / (R["m"] * math.Cos(turfgoMath.DegreeToRad(point.Lat))) latDisplacement := turfgoMath.RadToDegree(latDisplacementRad) longDisplacement := turfgoMath.RadToDegree(longDisplacementRad) translatedPoint := NewPoint(point.Lat+latDisplacement, point.Lng+longDisplacement) return translatedPoint }