Search code examples
iosswiftmathcllocation

Get vertical and horizontal components of distance between two coordinates in iOS


I'm trying to create a function in swift that accurately calculates the vertical and horizontal distance of any location from the origin of the Earth (latitude: 0, longitude: 0). I know that iOS has the distanceFromLocation function, but that gives me the direct location. What I'm looking for are the horizontal and vertical components of that direction. I tried coming up with my own solution, but when I test the direct distance based on the horizontal and vertical components I got, it didn't match the actual distance. Here's my function:

func distanceFromOrigin(location:CLLocation) {

    let lat = location.coordinate.latitude
    let lon = location.coordinate.longitude

    let earthOriginLocation = CLLocation(coordinate: CLLocationCoordinate2DMake(0.0, 0.0), altitude: CLLocationDistance(0.0), horizontalAccuracy: kCLLocationAccuracyBestForNavigation, verticalAccuracy: kCLLocationAccuracyBestForNavigation, timestamp: NSDate())

    var horDistance = earthOriginLocation.distanceFromLocation(CLLocation(latitude: 0.0, longitude: location.coordinate.longitude))
    var verDistance = earthOriginLocation.distanceFromLocation(CLLocation(latitude: location.coordinate.latitude, longitude: 0.0))

    let overallDistance = earthOriginLocation.distanceFromLocation(location)

    if lat < 0 {
        print("Object is South of Equator")
        verDistance *= -1
    } else if lat > 0 {
        print("Object is North of Equator")
    } else {
        print("Object is at the Equator")
    }
    if lon < 0 {
        print("Object is West of Prime Meridian")
        horDistance *= -1
    } else if lon > 0 {
        print("Object is East of Prime Meridian")
    } else {
        print("Object is at the Prime Meridian")
    }

    print("Vertical Distance: \(verDistance)")
    print("Horizontal Distance: \(horDistance)")
    print("Overall Distance: \(overallDistance)")

    //Test to see if vertical and horizontal distances are accurate compared to actual distance.
    print("Test: \(sqrt((pow(horDistance, 2.0)) + (pow(verDistance, 2.0))))")

}

Thanks!


Solution

  • Your code is fine, but your test is wrong.

    You miss that the Earth is not flat and so the right-angled triangle you're considering lays on geoid and has hypotenuse greater then squared sides sum.

    I'd recommend you to perform a couple of tests manually to make sure the result looks realistic and not dig deep into this geometry on a curved surface.


    A minor note: your test could pass if the points are pretty close to each other, because in such case the curvature of the Earth surface will have a minimal influence on the calculation.