确定CLLocationCoordinate2D是否在定义的区域(边界)内?

时间:2014-09-14 17:27:33

标签: ios7 core-location

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

CL曾经有一个循环区域和containsCoordinate:call to test,但是这在iOS7中已经被弃用了,dox中没有包含可能替换它的提示。我找不到任何其他的例子,特别是那些适用于多边形的例子。

这里有很多类似的问题,但它们并没有特别与iOS有关,而且我似乎找不到一个通常适用于大圆聚合物的问题。

2 个答案:

答案 0 :(得分:4)

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

要将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):

enter image description here

答案 1 :(得分:0)

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)
    }
}