iOS Google Maps Utils中PolyUtils.distanceToLine等效函数查询
寻找iOS版Google Maps Utils中对应Android PolyUtils.distanceToLine的函数
我之前也碰到过这个痛点!确实iOS版的Google Maps Utils库目前没有提供和Android端PolyUtils.distanceToLine完全等效的现成函数——这个函数的核心是计算点到线段的最短距离(区别于点到无限直线的距离,会判断投影点是否在线段范围内)。
不过别担心,我们可以参照Android端PolyUtils.distanceToLine的算法逻辑,自己用Swift实现一个,效果和官方函数一致:
import GoogleMaps func distanceToLine(point: CLLocationCoordinate2D, lineStart: CLLocationCoordinate2D, lineEnd: CLLocationCoordinate2D) -> CLLocationDistance { // 将坐标转换为球面墨卡托投影的平面坐标,降低球面计算误差 let pointProjected = GMSProjection.sphericalMercator().project(point) let startProjected = GMSProjection.sphericalMercator().project(lineStart) let endProjected = GMSProjection.sphericalMercator().project(lineEnd) let x0 = pointProjected.x let y0 = pointProjected.y let x1 = startProjected.x let y1 = startProjected.y let x2 = endProjected.x let y2 = endProjected.y // 计算线段长度的平方,避免开根号运算 let lineLengthSquared = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) if lineLengthSquared == 0 { // 线段起点和终点重合,直接返回点到点的球面距离 return point.distance(from: lineStart) } // 计算投影点在线段上的比例参数t,限制t在[0,1]区间内确保投影点在线段上 let t = max(0, min(1, ((x0 - x1) * (x2 - x1) + (y0 - y1) * (y2 - y1)) / lineLengthSquared)) // 计算投影点的平面坐标 let projectionX = x1 + t * (x2 - x1) let projectionY = y1 + t * (y2 - y1) // 将投影点转回经纬度,计算目标点到投影点的球面距离 let projectionCoordinate = GMSProjection.sphericalMercator().coordinate(for: CGPoint(x: projectionX, y: projectionY)) return point.distance(from: projectionCoordinate) }
简单说明下实现逻辑:
- 先把经纬度转成Google Maps的球面墨卡托平面坐标,避免直接球面计算带来的误差;
- 先判断线段是否为单点(起点终点重合),这种情况直接返回点到点的距离;
- 通过参数
t限制投影点在线段范围内,避免出现投影点超出线段两端的情况; - 最后把投影点转回经纬度,计算真实的球面距离。
这个实现完全对齐Android端PolyUtils.distanceToLine的行为,你可以直接集成到项目里使用。
内容的提问来源于stack exchange,提问作者Mihir Oza
相关产品推荐
相关产品推荐

