Skip to content

Instantly share code, notes, and snippets.

@tidwall
Created January 11, 2018 20:30
Show Gist options
  • Save tidwall/efb16b27e3ef87ba96e05ebbb94c6a3b to your computer and use it in GitHub Desktop.
Save tidwall/efb16b27e3ef87ba96e05ebbb94c6a3b to your computer and use it in GitHub Desktop.
Calculate the bounds of geo circle
package bboxbounds
import "math"
func BBoxBounds(lat, lon, meters float64) (latMin, lonMin, latMax, lonMax float64) {
// see http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#Latitude
lat = lat * (math.Pi / 180)
lon = lon * (math.Pi / 180)
r := meters / 6371e3 // angular radius
latMin = lat - r
latMax = lat + r
latT := math.Asin(math.Sin(lat) / math.Cos(r))
lonΔ := math.Acos((math.Cos(r) - math.Sin(latT)*math.Sin(lat)) / (math.Cos(latT) * math.Cos(lat)))
lonMin = lon - lonΔ
lonMax = lon + lonΔ
// Adjust for north poll
if latMax > math.Pi/2 {
lonMin = -math.Pi
latMax = math.Pi / 2
lonMax = math.Pi
}
// Adjust for south poll
if latMin < -math.Pi/2 {
latMin = -math.Pi / 2
lonMin = -math.Pi
lonMax = math.Pi
}
// Adjust for wraparound. Remove this if the commented-out condition below this block is added.
if lonMin < -math.Pi || lonMax > math.Pi {
lonMin = -math.Pi
lonMax = math.Pi
}
lonMin = math.Mod(lonMin+3*math.Pi, 2*math.Pi) - math.Pi // normalise to -180..+180°
lonMax = math.Mod(lonMax+3*math.Pi, 2*math.Pi) - math.Pi
return latMin * (180 / math.Pi), lonMin * (180 / math.Pi),
latMax * (180 / math.Pi), lonMax * (180 / math.Pi)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment