Created
May 17, 2021 10:07
-
-
Save akovalov/b56547fd31cfa0cc307516cd3f1c9903 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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