我试图找到一种简单的方法来确定CLLocationCoordinate2D是否位于由一系列其他CLLocationCoordinate2D定义的任意形状的边界内。形状可能足够大,需要考虑大圆路径。
CL曾经有一个循环区域和containsCoordinate:call to test,但是这在iOS7中已经被弃用了,dox中没有包含可能替换它的提示。我找不到任何其他的例子,特别是那些适用于多边形的例子。
这里有很多类似的问题,但它们并没有特别与iOS有关,而且我似乎找不到一个通常适用于大圆聚合物的问题。
答案 0 :(得分:4)
以下是一个可能适合您的方法(使用阿冈昆省立公园)。
要将CGPathContainsPoint
用于此目的,不需要MKMapView
。
也无需创建MKPolygon
甚至使用CLLocationCoordinate2D
或MKMapPoint
结构。它们只是让代码更容易理解。
以下屏幕截图仅根据数据创建。
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
):
答案 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)
}
}