一组CLLocationsCoordinate2D的中心坐标

8

有没有办法在iOS中获取一组CLLocationsCoordinate2D的中心坐标?

enter image description here


定义一组点的中心是很困难的。对于给定的点 (1,1) (2,1) (2,2) (1,2),你可以轻松地找到中心,但对于像 (1,1) (6,8) (8,1) (3,6) 这样的点集,就要困难得多了。你能否澄清一下你所说的中心是什么意思。 - Fogmeister
我有一组某个区域的位置坐标,需要找出该区域的中心坐标。但是该区域不一定具有固定的形状,可能是 PolyLine 或 PolyGon。 - dispatchMain
我希望上面的图片能够给你一些用户可以绘制的区域的想法,而且它可能会更加复杂,线条可能会交叉一次或多次。 - dispatchMain
是的,但您没有在该图像上指定中心在哪里!您需要定义“中心”是什么意思。 - Fogmeister
正如Fogmeister所指出的那样,这取决于您对“中心”的理解。如果有人画了字母“C”,您希望中心位于字母的中间位置而不是在线上,还是希望它位于线的一半或其他某种方法。 - Craig
显示剩余2条评论
7个回答

14

嗯...这取决于你如何定义点的中心。它是否取决于分布等等...

一种简单的方法是按以下方式进行...

//find rect that encloses all coords

float maxLat = -200;
float maxLong = -200;
float minLat = MAXFLOAT;
float minLong = MAXFLOAT;

for (int i=0 ; i<[locations count] ; i++) {
    CLLocationCoordinate2D location = [locations objectAtIndex:i];

    if (location.latitude < minLat) {
        minLat = location.latitude;
    }

    if (location.longitude < minLong) {
        minLong = location.longitude;
    }

    if (location.latitude > maxLat) {
        maxLat = location.latitude;
    }

    if (location.longitude > maxLong) {
        maxLong = location.longitude;
    }
}

//Center point

CLLocationCoordinate2D center = CLLocationCoordinate2DMake((maxLat + minLat) * 0.5, (maxLong + minLong) * 0.5);

这将给出覆盖所有点的矩形的中心。然而,它没有考虑散布。

. = point
X = centre

.....               X                   .

编辑

修正了部分数学内容。


这种方法在区域的形状是一些标量形状,比如矩形、正方形或圆形,或者几乎相同的情况下非常有用。但在我的情况下,区域没有特定的形状,因为它是由用户在地图视图上绘制的。 - dispatchMain
1
这个程序可以适用于任何形状。它会找到最小值和最大值,然后计算中心点。如果你想要其他的东西,就像我在评论中说的那样,你需要定义一下你所谓的“中心”。如果没有清楚地定义中心,那么你并没有提供帮助。也许举一个或两个例子会有所帮助等等... - Fogmeister
如果坐标跨越了日期变更线,这将会出现问题,但是如果用户正在绘图,那么这不会成为问题,因为他们无法以这种方式绘制。 - Craig

7

同时兼容Swift 5的扩展

extension Array where Element == CLLocationCoordinate2D {
func center() -> CLLocationCoordinate2D {
    var maxLatitude: Double = -200;
    var maxLongitude: Double = -200;
    var minLatitude: Double = Double(MAXFLOAT);
    var minLongitude: Double = Double(MAXFLOAT);

    for location in self {
        if location.latitude < minLatitude {
            minLatitude = location.latitude;
        }

        if location.longitude < minLongitude {
            minLongitude = location.longitude;
        }

        if location.latitude > maxLatitude {
            maxLatitude = location.latitude;
        }

        if location.longitude > maxLongitude {
            maxLongitude = location.longitude;
        }
    }

    return CLLocationCoordinate2DMake(CLLocationDegrees((maxLatitude + minLatitude) * 0.5), CLLocationDegrees((maxLongitude + minLongitude) * 0.5));
}

}


6
您还可以获取CLLocationCoordinate2D数组的中心和span
extension MKCoordinateRegion {

  init(coordinates: [CLLocationCoordinate2D]) {
    var minLatitude: CLLocationDegrees = 90.0
    var maxLatitude: CLLocationDegrees = -90.0
    var minLongitude: CLLocationDegrees = 180.0
    var maxLongitude: CLLocationDegrees = -180.0

    for coordinate in coordinates {
      let lat = Double(coordinate.latitude)
      let long = Double(coordinate.longitude)
      if lat < minLatitude {
        minLatitude = lat
      }
      if long < minLongitude {
        minLongitude = long
      }
      if lat > maxLatitude {
        maxLatitude = lat
      }
      if long > maxLongitude {
        maxLongitude = long
      }
    }

    let span = MKCoordinateSpanMake(maxLatitude - minLatitude, maxLongitude - minLongitude)
    let center = CLLocationCoordinate2DMake((maxLatitude - span.latitudeDelta / 2), (maxLongitude - span.longitudeDelta / 2))
    self.init(center: center, span: span)
  }
}

使用方法:

let region = MKCoordinateRegion(coordinates: coordinates)
region.center
region.span

6

我知道现在已经很晚了,但是如果有人看到这条信息并需要帮助的话,可以参考Fogmeister的回答,创建一个MKCoordinateRegion。

CLLocationDegrees minLat,minLng,maxLat,maxLng;
for(CLLocationCoordinate2D coordinate in coordinates) {
    minLat = MIN(minLat, coordinate.latitude);
    minLng = MIN(minLng, coordinate.longitude);

    maxLat = MAX(maxLat, coordinate.latitude);
    maxLng = MAX(maxLng, coordinate.longitude);
}

CLLocationCoordinate2D coordinateOrigin = CLLocationCoordinate2DMake(minLat, minLng);
CLLocationCoordinate2D coordinateMax = CLLocationCoordinate2DMake(maxLat, maxLng);

MKMapPoint upperLeft = MKMapPointForCoordinate(coordinateOrigin);
MKMapPoint lowerRight = MKMapPointForCoordinate(coordinateMax);

//Create the map rect
MKMapRect mapRect = MKMapRectMake(upperLeft.x,
                                  upperLeft.y,
                                  lowerRight.x - upperLeft.x,
                                  lowerRight.y - upperLeft.y);

//Create the region
MKCoordinateRegion region = MKCoordinateRegionForMapRect(mapRect);

//THIS HAS THE CENTER, it should include spread
CLLocationCoordinate2D centerCoordinate = region.center;

问候!!!

您好!


1

一个小型的数组扩展,没有像-200.0这样的神奇数字。

extension Array where Element == CLLocationCoordinate2D {
    func center() -> CLLocationCoordinate2D {
        var maxLatitude: Double = -.greatestFiniteMagnitude
        var maxLongitude: Double = -.greatestFiniteMagnitude
        var minLatitude: Double = .greatestFiniteMagnitude
        var minLongitude: Double = .greatestFiniteMagnitude

        for location in self {
            maxLatitude = Swift.max(maxLatitude, location.latitude)
            maxLongitude = Swift.max(maxLongitude, location.longitude)
            minLatitude = Swift.min(minLatitude, location.latitude)
            minLongitude = Swift.min(minLongitude, location.longitude)
        }

        let centerLatitude = CLLocationDegrees((maxLatitude + minLatitude) * 0.5)
        let centerLongitude = CLLocationDegrees((maxLongitude + minLongitude) * 0.5)
        return .init(latitude: centerLatitude, longitude: centerLongitude)
    }
}

1
Fogmeisters的答案能够起作用,但有3个错误,我已经进行了以下更正:
//find rect that encloses all coords

float maxLat = -200;
float maxLong = -200;
float minLat = MAXFLOAT;
float minLong = MAXFLOAT;

for (int i=0 ; i<[locations count] ; i++) {
CLLocationCoordinate2D location = [locations objectAtIndex:i];

    if (location.latitude < minLat) {
        minLat = location.latitude;
    }

    if (location.longitude < minLong) {
        minLong = location.longitude;
    }

    if (location.latitude > maxLat) {
        maxLat = location.latitude;
    }

    if (location.longitude > maxLong) { //Change to be greater than
        maxLong = location.longitude;
    }
}

//Center point
//The min's and max's should be ADDED not subtracted
CLLocationCoordinate2D center = CLLocationCoordinate2DMake((maxLat + minLat) * 0.5, (maxLong + minLong) * 0.5);

三个错误?我数了两个。而且,如果你要像这样复制粘贴,只是评论一个答案而不是偷走它的话,请不要这样做。 - Fogmeister
4
Fogmeister,我还没有足够的声望来评论。此外,由于被拒绝了,所以无法提交更正,而建议是提交一个新的、纠正过的答案。我只是按照建议去做了。实际上有3个错误。 - Aaron A.

1

如果您想以平均值作为中心,则将所有纬度和经度分别加总,然后除以您拥有的坐标数量,这是相当标准的数学方法。

(请注意,如果您的坐标跨越日期线,则此方法不适用)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接