1
votes

I'm trying to find out how to calculate the "west-east-facing" distance and the "north-south-facing" distance between two points respectively given the coordinates of the two points (with latitude and longitude), in order to find out the degree in which the line differs from the northern direction. In short I need to calculate x and y in meters in order to get the degree of alpha, when x and y are given by longitude and latitude.

I know CLLocation has a function to calculate the distance between two points:

distance(from location: CLLocation) -> CLLocationDistance

and I tried to open the source code of that function in order to figure out how to separate the two components but I did not find out how to open that code.

3

3 Answers

1
votes

You can use this

func getDistanceAndAngle(positionA: CLLocation, positionB: CLLocation) -> (Float, Float, Float){

    let distanceInMeters = Float(positionA.distance(from: positionB)) // result is in meters
    print(distanceInMeters)
    //search for the degree
    let angle = bearingFromLocation(fromLocation: positionA.coordinate, toLocation: positionB.coordinate)
    print("ANGLE", angle)
    let xDistance = abs(distanceInMeters * cos(DegreesToRadians(degrees: angle)))
    let yDistance = abs(distanceInMeters * sin(DegreesToRadians(degrees: angle)))

    return (xDistance,yDistance,angle)
}


func bearingFromLocation(fromLocation:CLLocationCoordinate2D, toLocation: CLLocationCoordinate2D)-> Float{

    let lat1 = DegreesToRadians(degrees: Float(fromLocation.latitude))
    let lon1 = DegreesToRadians(degrees: Float(fromLocation.longitude))

    let lat2 = DegreesToRadians(degrees: Float(toLocation.latitude))
    let lon2 = DegreesToRadians(degrees: Float(toLocation.longitude))

    let dLon = lon2 - lon1

    let y = sin(dLon) * cos(lat2)
    let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)
    let radiansBearing = atan2(y, x)
    print("radian", radiansBearing)
    let degreesBearing = RadiansToDegrees(radians: radiansBearing)
    print("deg", degreesBearing)

    if (degreesBearing >= 0) {
        return degreesBearing
    } else {
        return degreesBearing + 360.0
    }
}

func DegreesToRadians(degrees: Float)->Float {return degrees * Float.pi / 180.0}
func RadiansToDegrees(radians: Float)->Float {return radians * 180.0/Float.pi}

notes: the angle is from north to east so north is 0 degree and east is 90 degree. the X and Y is always positive. So if you want to make it negative to the left and down, you can try to put use degree to make it right.

0
votes

You can convert point1 and point2 to MKMapPoint. It's gives you coordinates which is projected map in 2D plane. Then you can eaisily get difference of x's and y's.. And using simple math, you can calculate the alpha value. You can initialize MKMapPoint with CLLocationCoordinate2D.

https://developer.apple.com/documentation/mapkit/mkmappoint

0
votes

Assuming we have:

let locationA = CLLocation(..)
let locationB = CLLocation(..)

I would probably still want to use Apple's provided functions and create new locations that only differ in latitude or longitude. Something like:

let latitudeA = CLLocation(latitude: locationA.latitude, longitude: locationA.longitude)
// notice I use latitude from B but KEEP longitude from A to keep them parallel)
let latitudeB = CLLocation(latitude: locationB.latitude, longitude: locationA.longitude)
let northSouthDistance = latitudeA.distance(from: latitudeB)

etc