【问题标题】:Determine whether a CLLocationCoordinate2D is within a defined region (bounds)?确定 CLLocationCoordinate2D 是否在定义的区域(边界)内?
【发布时间】:2014-11-08 06:25:31
【问题描述】:

我试图找到一种简单的方法来确定 CLLocationCoordinate2D 是否位于由一系列其他 CLLocationCoordinate2D 定义的任意形状的边界内。形状可能足够大,需要考虑大圆路径。

CL 曾经有一个圆形区域和 containsCoordinate: 调用来测试,但这在 iOS7 中已被弃用,并且 dox 不包含可能替代它的提示。我找不到任何其他示例,尤其是适用于多边形的示例。

这里有很多关于 SO 的类似问题,但它们与 iOS 无关,而且我似乎无法找到一个普遍适用于大圆多边形的问题。

【问题讨论】:

  • 您能否举例说明您所说的“形状可能足够大以至于需要考虑大圆路径”是什么意思?你试过this CGPathContainsPoint approach吗?您可以在路径中使用 CLLocationCoordinate2D 值而不是 MKMapPoint 值(如果您愿意的话),尽管它应该可以使用任何一种方式。
  • 是的,这些形状可能覆盖安大略省或阿尔伯塔省的大部分地区。今天最大的一个覆盖了安大略省皮克林和阿贾克斯的大部分地区,但未来可能会更大。一个合适的例子可能是阿冈昆公园,就大小和我希望在多边形中看到的点数而言。
  • 我认为 CGPathContainsPoint 方法对你有用。
  • 只处理笛卡尔,不处理大圆。
  • 另外,这需要一个我没有的mapView。

标签: ios7 core-location


【解决方案1】:

这是一个可能适合您的方法示例(使用阿冈昆省立公园)。

要为此目的使用CGPathContainsPoint,不需要MKMapView

也没有必要创建MKPolygon 甚至使用CLLocationCoordinate2DMKMapPoint 结构。它们只是让代码更容易理解。

下面的屏幕截图是根据数据创建的,仅用于说明目的。

int numberOfCoordinates = 10;

//This example draws a crude polygon with 10 coordinates
//around Algonquin Provincial Park.  Use as many coordinates
//as you like to achieve the accuracy you require.
CLLocationCoordinate2D algonquinParkCoordinates[numberOfCoordinates];
algonquinParkCoordinates[0] = CLLocationCoordinate2DMake(46.105,    -79.4);
algonquinParkCoordinates[1] = CLLocationCoordinate2DMake(46.15487,  -78.80759);
algonquinParkCoordinates[2] = CLLocationCoordinate2DMake(46.16629,  -78.12095);
algonquinParkCoordinates[3] = CLLocationCoordinate2DMake(46.11964,  -77.70896);
algonquinParkCoordinates[4] = CLLocationCoordinate2DMake(45.74140,  -77.45627);
algonquinParkCoordinates[5] = CLLocationCoordinate2DMake(45.52630,  -78.22532);
algonquinParkCoordinates[6] = CLLocationCoordinate2DMake(45.18662,  -78.06601);
algonquinParkCoordinates[7] = CLLocationCoordinate2DMake(45.11689,  -78.29123);
algonquinParkCoordinates[8] = CLLocationCoordinate2DMake(45.42230,  -78.69773);
algonquinParkCoordinates[9] = CLLocationCoordinate2DMake(45.35672,  -78.90647);

//Create CGPath from the above coordinates...
CGMutablePathRef mpr = CGPathCreateMutable();

for (int p=0; p < numberOfCoordinates; p++)
{
    CLLocationCoordinate2D c = algonquinParkCoordinates[p];

    if (p == 0)
        CGPathMoveToPoint(mpr, NULL, c.longitude, c.latitude);
    else
        CGPathAddLineToPoint(mpr, NULL, c.longitude, c.latitude);
}

//set up some test coordinates and test them...
int numberOfTests = 7;
CLLocationCoordinate2D testCoordinates[numberOfTests];
testCoordinates[0] = CLLocationCoordinate2DMake(45.5, -78.5);
testCoordinates[1] = CLLocationCoordinate2DMake(45.3, -79.1);
testCoordinates[2] = CLLocationCoordinate2DMake(45.1, -77.9);
testCoordinates[3] = CLLocationCoordinate2DMake(47.3, -79.6);
testCoordinates[4] = CLLocationCoordinate2DMake(45.5, -78.7);
testCoordinates[5] = CLLocationCoordinate2DMake(46.8, -78.4);
testCoordinates[6] = CLLocationCoordinate2DMake(46.1, -78.2);

for (int t=0; t < numberOfTests; t++)
{
    CGPoint testCGPoint = CGPointMake(testCoordinates[t].longitude, testCoordinates[t].latitude);

    BOOL tcInPolygon = CGPathContainsPoint(mpr, NULL, testCGPoint, FALSE);

    NSLog(@"tc[%d] (%f,%f) in polygon = %@",
          t,
          testCoordinates[t].latitude,
          testCoordinates[t].longitude,
          (tcInPolygon ? @"Yes" : @"No"));
}

CGPathRelease(mpr);

以下是上述测试的结果:

tc[0] (45.500000,-78.500000) in polygon = Yes
tc[1] (45.300000,-79.100000) in polygon = No
tc[2] (45.100000,-77.900000) in polygon = No
tc[3] (47.300000,-79.600000) in polygon = No
tc[4] (45.500000,-78.700000) in polygon = Yes
tc[5] (46.800000,-78.400000) in polygon = No
tc[6] (46.100000,-78.200000) in polygon = Yes


此截图仅用于说明数据(实际运行上述代码不需要MKMapView):

【讨论】:

  • 因此,即使它们是 -ve 值,似乎只是将所有内容都保留为点是诀窍。像冠军安娜一样工作,谢谢!
  • 嗨安娜....如果我们只想点击这些点而不是图表内部的线条...意味着当我们点击不在图表内部的点线时由他们绘制。
【解决方案2】:

Anna 的解决方案转换为 Swift 3.0:

extension CLLocationCoordinate2D {

    func contained(by vertices: [CLLocationCoordinate2D]) -> Bool {
        let path = CGMutablePath()

        for vertex in vertices {
            if path.isEmpty {
                path.move(to: CGPoint(x: vertex.longitude, y: vertex.latitude))
            } else {
                path.addLine(to: CGPoint(x: vertex.longitude, y: vertex.latitude))
            }
        }

        let point = CGPoint(x: self.longitude, y: self.latitude)
        return path.contains(point)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多