【问题标题】:Calculate bearing in MKMapView gives wrong value while crossing 180 meridian在 MKMapView 中计算方位在穿过 180 条子午线时给出错误值
【发布时间】:2018-10-31 00:40:49
【问题描述】:

我需要画线来展示苹果地图上的货物运输。为了明确起点和终点,我在目的地侧画了一个小箭头。箭头是单独绘制的,但在一种情况下是颠倒的。

>-->-->-->- 

而不是

<--<--<--<-

我正在使用 MKMapView 和 MKPolyline 来绘制线条。我正在使用 MKOverlay 添加方向箭头。我遵循的步骤是,

  1. 计算方位

    来源:CLLocationCoordinate2D(纬度:-33.8392932,经度:151.21519799999999) 目的地:CLLocationCoordinate2D(纬度:39.645516999999998,经度:-104.598724)

    使用以下函数

    open static func getDirectionOf( _ supplyLineWithCoordinates: [CLLocationCoordinate2D]) -> CGFloat {
    guard let sourceCoordniate = supplyLineWithCoordinates.first,
        let destinationCoordniate = supplyLineWithCoordinates.last  else {
            fatalError("Coordinates of supply line not found")
    }
    let sourcePoint: MKMapPoint = MKMapPointForCoordinate(sourceCoordniate)
    let destinationPoint: MKMapPoint = MKMapPointForCoordinate(destinationCoordniate)
    let x: Double = destinationPoint.x - sourcePoint.x
    let y: Double = destinationPoint.y - sourcePoint.y
    var arrowDirection = CGFloat(fmod(atan2(y, x), 360.0))
    if arrowDirection < 0.0 {
        arrowDirection += 2 * .pi
    }
    return arrowDirection 
    

    }

  2. 旋转箭头图像并将其添加为地图叠加层。在大多数情况下,方向计算正确,但是,当我选择下面显示的线时,方向显示 180 相反。起点为澳大利亚悉尼,终点美国丹佛

当试图在mapView.setVisibleMapRect 中显示这两个位置的区域时,这些区域不会显示,mapview 会尝试显示从悉尼(澳大利亚)到丹佛(美国)通过亚洲和欧洲的区域,而它应该显示地图我在上面附上的区域。如果您有优化建议,请随时提出。

我认为这可能是原因,方向应该沿着红线计算,但它是沿着绿线计算的。两条线都是通过连接地图中相同的位置坐标来绘制的。任何已知的解决方法?

【问题讨论】:

  • 这个fmod(atan2(y, x), 360.0)) // in radians 向我提出了两个问题:1)评论说弧度,但 360.0 显然是度数; 2) 表达式看起来好像会返回 0 到 360 之间的值,但您可能想要 -180 到 180 吗?另外,箭头不应该与线一起吗?在您的示例图片中,它们指向其他地方。
  • 抱歉,in radians 的评论有误,我删除了。由于线可以在任何方向,所以 0 到 360 将是首选。箭头应该沿着这条线走,这是我正在寻求解决方案的错误:) 它显示了确切的方向,并且在所有其他情况下都与这条线一致。
  • 我会添加调试打印输出,显示 sourcePoint、destinationPoint 和 arrowDirection 的值。
  • 我尝试打印值,但我没有注意到任何东西,因为它计算了所有其他 MKPolylines 的正确方向。我已为问题添加了更多信息
  • 在发生错误时仔细查看用于计算的值是调试的重要部分。您必须能够注意到错误值的计算方式。

标签: ios swift mapkit mkmapview


【解决方案1】:

我通过将坐标转换为 CGPoint 然后计算点之间的方位以一种肮脏的方式解决了它。

let destinationPoint = mapView.convert(destination, toPointTo: nil)
let sourcePoint = mapView.convert(source, toPointTo: nil)

let bearing = atan2(sourcePoint.y - destinationPoint.y, sourcePoint.x - destinationPoint.x) - .pi

注意:地图旋转时计算会出错

【讨论】:

    猜你喜欢
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2016-12-13
    • 2019-12-06
    • 1970-01-01
    相关资源
    最近更新 更多