【问题标题】:How to create an MKMapRect given two points, each specified with a latitude and longitude value?如何在给定两个点的情况下创建一个 MKMapRect,每个点都指定一个纬度和经度值?
【发布时间】:2019-02-04 06:52:27
【问题描述】:

我有一个自定义类,它扩展了NSObject 并实现了MKOverlay 协议。因此,我需要实现协议的boundingMapRect 属性,即MKMapRect。要创建一个MKMapRect,我当然可以使用MKMapRectMake 来创建一个。但是,我不知道如何使用我拥有的数据创建MKMapRect,这是两个点,每个点都由纬度和经度指定。 MKMapRectMake 的文档状态:

MKMapRect MKMapRectMake(
    double x,
    double y,
    double width,
    double height
);

Parameters
x
    The point along the east-west axis of the map projection to use for the origin.
y
    The point along the north-south axis of the map projection to use for the origin.
width
    The width of the rectangle (measured using map points).
height
    The height of the rectangle (measured using map points).
Return Value
    A map rectangle with the specified values.

我必须指定MKMapRect 的纬度和经度值是:

24.7433195, -124.7844079
49.3457868, -66.9513812

因此,目标MKMapRect 需要指定一个看起来像这样的区域:

所以,重申一下,我如何使用我的纬度/经度值来创建一个MKMapRect,我可以将其设置为MKOverlay 协议的@property (nonatomic, readonly) MKMapRect boundingMapRect 属性?

【问题讨论】:

    标签: ios mapkit


    【解决方案1】:

    应该这样做:

    // these are your two lat/long coordinates
    CLLocationCoordinate2D coordinate1 = CLLocationCoordinate2DMake(lat1,long1);
    CLLocationCoordinate2D coordinate2 = CLLocationCoordinate2DMake(lat2,long2);
    
    // convert them to MKMapPoint
    MKMapPoint p1 = MKMapPointForCoordinate (coordinate1);
    MKMapPoint p2 = MKMapPointForCoordinate (coordinate2);
    
    // and make a MKMapRect using mins and spans
    MKMapRect mapRect = MKMapRectMake(fmin(p1.x,p2.x), fmin(p1.y,p2.y), fabs(p1.x-p2.x), fabs(p1.y-p2.y));
    

    这使用两个 x 和 y 坐标中较小的一个作为起点,并计算两个点之间的 x/y 跨度作为宽度和高度。

    【讨论】:

    • 你,我的朋友,是legendboss!谢谢!!
    • 这在 180 经线附近不起作用。验证来源:CLLocationCoordinate2D(纬度:-33.8392932,经度:151.21519799999999) 目的地:CLLocationCoordinate2D(纬度:39.645516999999998,经度:-104.598724)
    【解决方案2】:

    对于任意数量的坐标,在 Swift (4.2) 中:

    // Assuming `coordinates` is of type `[CLLocationCoordinate2D]`
    let rects = coordinates.lazy.map { MKMapRect(origin: MKMapPoint($0), size: MKMapSize()) }
    let fittingRect = rects.reduce(MKMapRect.null) { $0.union($1) }
    

    正如@Abin Baby 所指出的,这不会考虑环绕(在 +/-180 经度和 +/-90 纬度)。结果仍然是正确的,但它不会是可能的最小矩形。

    【讨论】:

    • 非常简短而准确的答案!适用于所有坐标输入。太好了!
    • 这在 180 经线附近不起作用。测试值 来源:CLLocationCoordinate2D(纬度:-33.8392932,经度:151.21519799999999) 目的地:CLLocationCoordinate2D(纬度:39.645516999999998,经度:-104.598724)
    • 这个解决方案效果很好,而且非常简单!我是编码新手,所以我认为唯一的方法是使用for 循环。有什么方法可以解释映射的工作原理以及$ 符号的含义?
    • $0.union($1) 已重命名为 MKMapRectUnion($0,$1)
    • @Zeezer 反过来。
    【解决方案3】:

    根据帕特里克的回答,MKMapRect 上的扩展:

    extension MKMapRect {
        init(coordinates: [CLLocationCoordinate2D]) {
            self = coordinates.map({ MKMapPointForCoordinate($0) }).map({ MKMapRect(origin: $0, size: MKMapSize(width: 0, height: 0)) }).reduce(MKMapRectNull, combine: MKMapRectUnion)
        }
    }
    

    【讨论】:

      【解决方案4】:

      这对我有用。

      即使在 +/-180 经度和 +/-90 纬度之间穿越也没有问题。

      斯威夫特4.2

      func makeRect(coordinates:[CLLocationCoordinate2D]) -> MKMapRect {
          var rect = MKMapRect()
          var coordinates = coordinates
          if !coordinates.isEmpty {
              let first = coordinates.removeFirst()
              var top = first.latitude
              var bottom = first.latitude
              var left = first.longitude
              var right = first.longitude
              coordinates.forEach { coordinate in
                  top = max(top, coordinate.latitude)
                  bottom = min(bottom, coordinate.latitude)
                  left = min(left, coordinate.longitude)
                  right = max(right, coordinate.longitude)
              }
              let topLeft = MKMapPoint(CLLocationCoordinate2D(latitude:top, longitude:left))
              let bottomRight = MKMapPoint(CLLocationCoordinate2D(latitude:bottom, longitude:right))
              rect = MKMapRect(x:topLeft.x, y:topLeft.y,
                               width:bottomRight.x - topLeft.x, height:bottomRight.y - topLeft.y)
          }
          return rect
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-08
        • 1970-01-01
        • 1970-01-01
        • 2019-02-20
        • 1970-01-01
        • 2021-10-17
        相关资源
        最近更新 更多