MKPolygon 面积计算 Swift

Posted

技术标签:

【中文标题】MKPolygon 面积计算 Swift【英文标题】:MKPolygon Area Calculation Swift 【发布时间】:2015-12-11 00:19:30 【问题描述】:

我一直在尝试计算 MKPolygon,并且我已经按照这里的几个链接进行了相应的调整。我似乎无法正确计算平方米。如果需要,我可以提供更多信息

这是我的代码

func polygonArea() -> Double
    var area: Double = 0
    var kEarthRadius:Double = 6378137
    var coord: NSArray = self.coordinates()
    if (coord.count > 2)
        var p1, p2, p3 : CLLocationCoordinate2D

        var lowerIndex, middleIndex, upperIndex: Int
        for var i = 0; i < points.count - 1; i++ 
            if (i == (points.count - 2))
                lowerIndex = points.count - 2
                middleIndex = points.count - 1
                upperIndex = 0
            else if (i == points.count - 1)
                lowerIndex = points.count - 1
                middleIndex = 0
                upperIndex = 1;

            else
                lowerIndex = i
                middleIndex = i + 1
                upperIndex = i + 2
            
            p1 = points[lowerIndex]
            p2 = points[middleIndex]
            p3 = points[upperIndex]
            area +=  degreesToRadians(p2.longitude - p1.longitude) * (2 + sin(degreesToRadians(p1.latitude)) + sin(degreesToRadians(p2.latitude)))

        
        area = area * kEarthRadius * kEarthRadius / 2

    
    return area
    measureLabel.text = "\(area)"

我专门关注了这个链接 MKPolygon area calculation

【问题讨论】:

polygonArea() 当前返回的是什么? 另外,return area 之后的行将永远不会被执行。您应该将它移到 return 语句上方。 什么意思它返回什么?喜欢价值?我将删除最后一行。我知道号码是关闭的。例如,现在它返回 382838.399394838。也感谢您的回复! 是的,价值。你期望什么价值?不客气! 1439064387.63392 是我在 13816 米的实际面积上得到的,而且我看到 var p3 没有被使用,但我在我提到的链接的计算中也没有看到它。 【参考方案1】:

这是 Objective-C 版本。您可以毫无问题地在代码中使用它。

#define kEarthRadius 6378137
@implementation MKPolygon (AreaCalculation)

- (double) area 
  double area = 0;
  NSMutableArray *coords = [[self coordinates] mutableCopy];
  [coords addObject:[coords firstObject]];

  if (coords.count > 2) 
    CLLocationCoordinate2D p1, p2;
    for (int i = 0; i < coords.count - 1; i++) 
      p1 = [coords[i] MKCoordinateValue];
      p2 = [coords[i + 1] MKCoordinateValue];
      area += degreesToRadians(p2.longitude - p1.longitude) * (2 + sinf(degreesToRadians(p1.latitude)) + sinf(degreesToRadians(p2.latitude)));
    

    area = - (area * kEarthRadius * kEarthRadius / 2);
  
  return area;

- (NSArray *)coordinates 
  NSMutableArray *points = [NSMutableArray arrayWithCapacity:self.pointCount];
  for (int i = 0; i < self.pointCount; i++) 
    MKMapPoint *point = &self.points[i];
    [points addObject:[NSValue valueWithMKCoordinate:MKCoordinateForMapPoint(* point)]];
  
  return points.copy;


double degreesToRadians(double radius) 
  return radius * M_PI / 180;

编辑:更新后,计算也将线上的一个点视为多边形内部。

【讨论】:

我会继续努力。真的很接近我要设置一些坐标并匹配它们。在将其标记为答案之前,我想确定一下。非常感谢! 我偏离了 124-125 米。关于为什么的任何想法。我试图比较并把我以前的一些公式放在一起 因为常数 - 地球的半径不是常数。地球不是一个完美的球体。我认为大约 15x15 米的 125 米区域可以忽略不计。【参考方案2】:

我试图解决同样的问题,除了使用 UTM 而不是 long/lat。经过大量搜索后,我一直在找到与您上面相同的代码,但这对我不起作用。

然而,我确实发现了一个简单的 C 函数,当它转换为 Swift 时,它似乎工作得很好。对于大约 1600 米的计算,我的计算只差了大约 4 米,这可能是地球曲线。

class func polygonArea(points: Array<GAPaddockPoint>) -> Double 

    var area:Double = 0.0
    var j = points.count - 1
    for var i=0; i<points.count; i++ 
        area = area + ( (points[j].easting + points[i].easting) * (points[j].northing - points[i].northing) )
        j=i
    

    return area * 0.5

【讨论】:

我要去看看它是如何工作的。感谢您的时间和回应。我会尽快通知你的! 这不起作用,但我试图了解点数的差异。我有一个计算到它相当接近的地方,但没有什么是一成不变的。【参考方案3】:

Swift 版本由@AVT 发布在MKPolygon area calculation:

import MapKit
let kEarthRadius = 6378137.0

// CLLocationCoordinate2D uses degrees but we need radians
func radians(degrees: Double) -> Double 
    return degrees * M_PI / 180


func regionArea(locations: [CLLocationCoordinate2D]) -> Double 

    guard locations.count > 2 else  return 0 
    var area = 0.0

    for i in 0..<locations.count 
        let p1 = locations[i > 0 ? i - 1 : locations.count - 1]
        let p2 = locations[i]

        area += radians(degrees: p2.longitude - p1.longitude) * (2 + sin(radians(degrees: p1.latitude)) + sin(radians(degrees: p2.latitude)) )
    

    area = -(area * kEarthRadius * kEarthRadius / 2)

    return max(area, -area) // In order not to worry about is polygon clockwise or counterclockwise defined.

【讨论】:

以上是关于MKPolygon 面积计算 Swift的主要内容,如果未能解决你的问题,请参考以下文章

来自点 + 半径/距离的 MKPolygon (iPhone SDK)

从 SQLite 读取坐标并创建一个 MKPolygon

验证 latlong 是不是在 iOS 的 MKPolygon 内

Swift4 中 MKPolygon 的指定初始化程序是啥?

MKPolygon 未绘制

使用 MKPolygon 或 polygonWithCoordinates (Swift) 时遇到问题