如何根据起点longitude、Latitude、角度及距离精准计算终点经纬度(附代码)
计算起点经纬度、方向角与直线距离对应的终点坐标
一、使用MapKit/CoreLocation实现(iOS/macOS平台)
苹果的CoreLocation框架提供了贴合iOS生态的实现方案,无需手动处理复杂球面三角运算,精度符合WGS84坐标系标准。
代码实现(Swift)
import CoreLocation func getDestinationCoordinate(from start: CLLocationCoordinate2D, bearingDegrees: Double, distanceMeters: Double) -> CLLocationCoordinate2D { let startLocation = CLLocation(latitude: start.latitude, longitude: start.longitude) return startLocation.coordinate(withBearing: bearingDegrees, distance: distanceMeters) } // 扩展CLLocation,添加方位角+距离计算坐标的方法 extension CLLocation { func coordinate(withBearing bearing: Double, distance: Double) -> CLLocationCoordinate2D { let bearingRadians = bearing * .pi / 180 let distanceRadians = distance / 6378137 // WGS84椭球长半轴,单位米 let startLatRadians = self.coordinate.latitude * .pi / 180 let startLonRadians = self.coordinate.longitude * .pi / 180 // 计算终点纬度(弧度) let destLatRadians = asin( sin(startLatRadians) * cos(distanceRadians) + cos(startLatRadians) * sin(distanceRadians) * cos(bearingRadians) ) // 计算终点经度(弧度) let destLonRadians = startLonRadians + atan2( sin(bearingRadians) * sin(distanceRadians) * cos(startLatRadians), cos(distanceRadians) - sin(startLatRadians) * sin(destLatRadians) ) // 弧度转角度,修正经度范围至-180~180 let destLat = destLatRadians * 180 / .pi let destLon = destLonRadians * 180 / .pi return CLLocationCoordinate2D(latitude: destLat, longitude: destLon) } }
参数说明
start: 起点经纬度坐标(CLLocationCoordinate2D类型)bearingDegrees: 方位角,以真北为0度,顺时针递增(例如正东为90度、正南为180度)distanceMeters: 起点到终点的直线距离,单位为米
二、不依赖第三方库的纯公式实现(跨平台通用)
如果需要在非苹果平台使用,可基于球面三角公式手动计算,以下是通用Swift实现(可快速转为Java、Python等其他语言):
代码实现
func calculateDestinationManual(lat: Double, lon: Double, bearingDegrees: Double, distanceMeters: Double) -> (latitude: Double, longitude: Double) { let earthRadius = 6378137.0 // WGS84椭球半径,单位米 let bearing = bearingDegrees * .pi / 180.0 let distanceRatio = distanceMeters / earthRadius let lat1 = lat * .pi / 180.0 let lon1 = lon * .pi / 180.0 // 计算终点纬度(弧度) let lat2 = asin( sin(lat1) * cos(distanceRatio) + cos(lat1) * sin(distanceRatio) * cos(bearing) ) // 计算终点经度(弧度) let lon2 = lon1 + atan2( sin(bearing) * sin(distanceRatio) * cos(lat1), cos(distanceRatio) - sin(lat1) * sin(lat2) ) // 弧度转角度,修正经度范围至-180~180 let finalLat = lat2 * 180.0 / .pi var finalLon = lon2 * 180.0 / .pi finalLon = (finalLon + 540).truncatingRemainder(dividingBy: 360) - 180 return (finalLat, finalLon) }
使用示例
// 示例:从北京天安门(39.9042, 116.4074)向正东走1000米 let dest = calculateDestinationManual(lat: 39.9042, lon: 116.4074, bearingDegrees: 90, distanceMeters: 1000) print("终点坐标:纬度\(dest.latitude),经度\(dest.longitude)")
内容的提问来源于stack exchange,提问作者stellus
相关产品推荐
相关产品推荐

