Skip to content

Instantly share code, notes, and snippets.

@akovalov
Created May 17, 2021 10:07
Show Gist options
  • Save akovalov/b56547fd31cfa0cc307516cd3f1c9903 to your computer and use it in GitHub Desktop.
Save akovalov/b56547fd31cfa0cc307516cd3f1c9903 to your computer and use it in GitHub Desktop.
// Hexagon polygon coordinates
extension TurbulenceItem {
var hexagonCoordinates: [CLLocationCoordinate2D] {
let center = self.coordinate
let lngNorthWest = self.bbox[0] // bbox is 4 points in corners order: left top, right top, right bottom, left bottom
let leftPoint = CLLocationCoordinate2D(
latitude: center.latitude,
longitude: lngNorthWest)
let radius = CLLocation(coordinate: center)
.distance(from: CLLocation(coordinate: leftPoint))
let sidesCount = 6
let shapeCoords = center.polygon(radius: radius, sidesCount: sidesCount)
return shapeCoords
}
}
// Helpers
extension CLLocationCoordinate2D {
// self is center
func polygon(radius: CLLocationDistance,
sidesCount: Int) -> [CLLocationCoordinate2D] {
let stepDegrees: Double = 360 / Double(sidesCount)
var coords: [CLLocationCoordinate2D] = []
for i in 0...sidesCount {
let coord = shift(byDistance: radius,
azimuth: degreesToRadians(degrees: stepDegrees * Double(i)))
coords.append(coord)
}
return coords
}
}
extension CLLocationCoordinate2D {
/// Get coordinate moved from current to `distanceMeters` meters with azimuth `azimuth` [0, Double.pi)
///
/// - Parameters:
/// - distanceMeters: the distance in meters
/// - azimuth: the azimuth (bearing)
/// - Returns: new coordinate
func shift(byDistance distanceMeters: Double, azimuth: Double) -> CLLocationCoordinate2D {
let bearing = azimuth
let origin = self
let distRadians = distanceMeters / (6372797.6) // earth radius in meters
let lat1 = origin.latitude * Double.pi / 180
let lon1 = origin.longitude * Double.pi / 180
let lat2 = asin(sin(lat1) * cos(distRadians) + cos(lat1) * sin(distRadians) * cos(bearing))
let lon2 = lon1 + atan2(sin(bearing) * sin(distRadians) * cos(lat1), cos(distRadians) - sin(lat1) * sin(lat2))
return CLLocationCoordinate2D(latitude: lat2 * 180 / Double.pi, longitude: lon2 * 180 / Double.pi)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment