3

My app needs to be able to get the user starting location and then calculate lat/long coords specific distances away from that spot (in all directions). Does anyone know how I might accomplish this?

Anthony
  • 303
  • 1
  • 4
  • 15
  • You can use [`distanceFromLocation:`](https://developer.apple.com/library/mac/documentation/CoreLocation/Reference/CLLocation_Class/index.html#//apple_ref/occ/instm/CLLocation/distanceFromLocation:) on `CLLocation` for this. – rckoenes Oct 21 '14 at 15:25
  • That returns the distance, which I already have. I need to get the actual location that function would be called on (the from). – Anthony Oct 21 '14 at 15:26
  • 4
    the question is not clear, do you want an infinite set of locations as output? – Vik Oct 21 '14 at 15:28
  • 1
    Try http://stackoverflow.com/questions/6633850/calculate-new-coordinate-x-meters-and-y-degree-away-from-one-coordinate/6634982#6634982, http://stackoverflow.com/questions/7278094/iphone-moving-a-cllocation-by-x-meters, etc. –  Oct 21 '14 at 15:41
  • @Vik more so just a few that I can specify with a degree. – Anthony Oct 21 '14 at 15:53

2 Answers2

5

I found my answer on this link Moving a CLLocation by x meters and ported it to work with Swift.

func locationWithBearing(bearing:Double, distanceMeters:Double, origin:CLLocationCoordinate2D) -> CLLocationCoordinate2D {
    let distRadians = distanceMeters / (6372797.6) // earth radius in meters

    let lat1 = origin.latitude * M_PI / 180
    let lon1 = origin.longitude * M_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 / M_PI, longitude: lon2 * 180 / M_PI)
}

Morgan Chen wrote this:

All of the math in this method is done in radians. At the start of the method, lon1 and lat1 are converted to radians for this purpose as well. Bearing is in radians too. Keep in mind this method takes into account the curvature of the Earth, which you don't really need to do for small distances.

Community
  • 1
  • 1
Anthony
  • 303
  • 1
  • 4
  • 15
  • All of the math in this method is done in radians. At the start of the method, lon1 and lat1 are converted to radians for this purpose as well. Bearing is in radians too. Keep in mind this method takes into account the curvature of the Earth, which you don't really need to do for small distances. – Morgan Chen Oct 21 '14 at 18:36
3

The set of points a fixed distance from a central point has infinite members, so it's not possible to list out every one. However, given a single point you could check if it is within the set by using the distanceFromLocation: method.

Mathematically, given a radius coordinate (long, lat) and assuming the Earth is flat, the equation of the circle with radius (distance) r would be

r^2 = (x - long)^2 + (y - lat)^2

With the use of some magic, this becomes

x = r cosθ - long; y = r sinθ - lat

So now you can punch in any arbitrary angle and for a known distance/radius get a point on the edge of the circle. In map terms, the angle 0 will give you the point on the circle straight east of the center. Positive angles go counterclockwise around the center.

In code:

-(CLLocation*)locationForAngle:(float)angle fromCenterLocation:(CLLocation *)center withDistance:(float)distance {
    //angle must be in radians
    float longitude = distance * cosf(angle) - center.coordinate.longitude;
    float latitude = distance * sinf(angle) - center.coordinate.latitude;
    return [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
}

Edit: I accidentally dropped a few terms

Stewart Macdonald
  • 2,062
  • 24
  • 27
Morgan Chen
  • 1,137
  • 7
  • 18
  • Your `locationForAngle:` method does not use the given `center` parameter at all, so there must be something wrong ... – Martin R Oct 21 '14 at 16:15
  • I fixed it. I had dropped a few terms absentmindedly – Morgan Chen Oct 21 '14 at 17:18
  • Added as accepted since it's essentially the same thing I posted below but more in depth. – Anthony Oct 22 '14 at 19:28
  • This is a good start, but if you pass in a coordinate in the southern hemisphere, the returned coordinate will be transposed to the northern hemisphere. This answer works better: http://stackoverflow.com/a/20241963/2269574 – Stewart Macdonald Dec 01 '16 at 16:46