我怎样才能检查一个CLLocationCoordinate2D是否在四个CLLocationCoordinate2D Square内? 在目标C与谷歌地图

我想testing一个CLLocationCoordinate2D是否在由其他四个CLLocationCoordinate2D创build的Square中

我有这样的结构:

typedef struct { CLLocationCoordinate2D southWest; CLLocationCoordinate2D southEast; CLLocationCoordinate2D northEast; CLLocationCoordinate2D northWest; } Bounds; 

并且以param的forms传递一个CLLocationCoordinate2D坐标。 我想testing坐标是否在边界内。 我如何testing?

 - (BOOL) isCoordinate:(CLLocationCoordinate2D)coordinate insideBounds:(Bounds)bounds { ... } 

如果你有四点你可以做一个CGRect并使用CGRectContainsPoint()

如果4个点不代表矩形或一个圆圈,但在地图上有4个点,则需要自己创build系统。 对于在由4个定向点表示的形状内部的点来说,检查中心和每个连续的边界点对之间的叉积是最容易的。 所有的结果必须是正确的时钟明智的顺序点在边界内。 第二件事是你需要将坐标转换为笛卡尔系统并定位它们…让代码自己说话:

 - (double)crossProductZCoordinateForCenter:(CLLocationCoordinate2D)center left:(CLLocationCoordinate2D)left right:(CLLocationCoordinate2D)right { CLLocationCoordinate2D A = CLLocationCoordinate2DMake(left.latitude-center.latitude, left.longitude-center.longitude); CLLocationCoordinate2D B = CLLocationCoordinate2DMake(right.latitude-center.latitude, right.longitude-center.longitude); return B.latitude*A.longitude - A.latitude*B.longitude; } - (BOOL)isCartesianCoordinate:(CLLocationCoordinate2D)coordinate insideBounds:(Bounds)bounds { // Now we will break the system into 4 triangles and check their orientation by using az component of the cross product. If one of them if negative the coordinate is not inside the region if([self crossProductZCoordinateForCenter:coordinate left:bounds.southWest right:bounds.northWest] < .0) return NO; if([self crossProductZCoordinateForCenter:coordinate left:bounds.northWest right:bounds.northEast] < .0) return NO; if([self crossProductZCoordinateForCenter:coordinate left:bounds.northEast right:bounds.southEast] < .0) return NO; if([self crossProductZCoordinateForCenter:coordinate left:bounds.southEast right:bounds.southWest] < .0) return NO; return YES; } - (BOOL)isCoordinate:(CLLocationCoordinate2D)coordinate insideBounds:(Bounds)bounds { // We may treat the coordinates as cartesian but east should always be larger then west and north should be larger then south // Those smaller must be increased by 360 degrees if(bounds.southEast.latitude < bounds.southWest.latitude) bounds.southEast.latitude += 360.0; if(bounds.northEast.latitude < bounds.northWest.latitude) bounds.northEast.latitude += 360.0; if(bounds.northEast.longitude < bounds.southEast.longitude) bounds.northEast.longitude += 360.0; if(bounds.northWest.longitude < bounds.southWest.longitude) bounds.northWest.longitude += 360.0; // Check if any of the combination coordinates are cartesicly inside the bounds // We need to increase the longitude and the latitude by 360 and check all 4 combinations if([self isCartesianCoordinate:coordinate insideBounds:bounds]) return YES; if([self isCartesianCoordinate:CLLocationCoordinate2DMake(coordinate.latitude+360.0, coordinate.longitude) insideBounds:bounds]) return YES; if([self isCartesianCoordinate:CLLocationCoordinate2DMake(coordinate.latitude, coordinate.longitude+360.0) insideBounds:bounds]) return YES; if([self isCartesianCoordinate:CLLocationCoordinate2DMake(coordinate.latitude+360.0, coordinate.longitude+360.0) insideBounds:bounds]) return YES; return NO; } 

一些简单的testing可能会派上用场:

 - (void)resampleCoordinate:(CLLocationCoordinate2D *)coordinate { if(coordinate->latitude < -180.0) coordinate->latitude += 360.0; if(coordinate->latitude > 180.0) coordinate->latitude -= 360.0; if(coordinate->longitude < -180.0) coordinate->longitude += 360.0; if(coordinate->longitude > 180.0) coordinate->longitude -= 360.0; } - (void)testLocationSystem { NSInteger numberOfTests = 0; NSInteger numberOfTestsCheckedOut = 0; for(double latitude = -180.0; latitude <= 180.0; latitude++) { for(double longitude = -180.0; longitude <= 180.0; longitude++) { Bounds bounds; bounds.southWest = CLLocationCoordinate2DMake(latitude-15.0, longitude-15.0); bounds.northEast = CLLocationCoordinate2DMake(latitude+15.0, longitude+15.0); bounds.northWest = CLLocationCoordinate2DMake(latitude-15.0, longitude+15.0); bounds.southEast = CLLocationCoordinate2DMake(latitude+15.0, longitude-15.0); [self resampleCoordinate:&(bounds.northWest)]; [self resampleCoordinate:&(bounds.northEast)]; [self resampleCoordinate:&(bounds.southEast)]; [self resampleCoordinate:&(bounds.southWest)]; numberOfTests++; BOOL success = [self isCoordinate:CLLocationCoordinate2DMake(latitude, longitude) insideBounds:bounds]; if(success) { numberOfTestsCheckedOut++; } else { NSLog(@"Failed"); } } } NSLog(@"%d/%d succeeded", (int)numberOfTestsCheckedOut, (int)numberOfTests); } - (void)testLocationFailSystem { NSInteger numberOfTests = 0; NSInteger numberOfTestsCheckedOut = 0; for(double latitude = -180.0; latitude <= 180.0; latitude++) { for(double longitude = -180.0; longitude <= 180.0; longitude++) { Bounds bounds; bounds.southWest = CLLocationCoordinate2DMake(latitude-15.0, longitude-15.0); bounds.northEast = CLLocationCoordinate2DMake(latitude+15.0, longitude+15.0); bounds.northWest = CLLocationCoordinate2DMake(latitude-15.0, longitude+15.0); bounds.southEast = CLLocationCoordinate2DMake(latitude+15.0, longitude-15.0); [self resampleCoordinate:&(bounds.northWest)]; [self resampleCoordinate:&(bounds.northEast)]; [self resampleCoordinate:&(bounds.southEast)]; [self resampleCoordinate:&(bounds.southWest)]; for(double angle = .0f; angle < M_PI; angle+=M_PI/10.0) { CLLocationCoordinate2D coordiunate = CLLocationCoordinate2DMake(latitude+cos(angle)*20.0, longitude+sin(angle)*20.0); [self resampleCoordinate:&coordiunate]; numberOfTests++; BOOL success = [self isCoordinate:coordiunate insideBounds:bounds]; // must fail if(success == NO) { numberOfTestsCheckedOut++; } else { NSLog(@"Failed"); } } } } NSLog(@"%d/%d succeeded", (int)numberOfTestsCheckedOut, (int)numberOfTests); } 

这些都传给我。 如果您发现情况不正常,但应该或其他方式请与我联系。

您只需创build一个CLregionCLCircularRegion并检查该坐标是否包含在区域内…

喜欢这个

 CLCircularRegion *myRegion = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(22, -111) radius:500 identifier:@"myRegion"]; if ([myRegion containsCoordinate:CLLocationCoordinate2DMake(22.45, -111.1)]) { //Do what you want here }