如何检查MKCoordinateRegion是否包含CLLocationCoordinate2D而不使用MKMapView?

我需要检查用户位置是否属于MKCoordinateRegion。 我很惊讶没有find简单的函数, 像这样:CGRectContainsCGPoint(矩形,点)

我发现下面的一段代码:

CLLocationCoordinate2D topLeftCoordinate = CLLocationCoordinate2DMake(region.center.latitude + (region.span.latitudeDelta/2.0), region.center.longitude - (region.span.longitudeDelta/2.0)); CLLocationCoordinate2D bottomRightCoordinate = CLLocationCoordinate2DMake(region.center.latitude - (region.span.latitudeDelta/2.0), region.center.longitude + (region.span.longitudeDelta/2.0)); if (location.latitude < topLeftCoordinate.latitude || location.latitude > bottomRightCoordinate.latitude || location.longitude < bottomRightCoordinate.longitude || location.longitude > bottomRightCoordinate.longitude) { // Coordinate fits into the region } 

但是,我不确定是否准确,因为文档没有明确指定区域矩形的计算方式。

必须有更简单的方法来做到这一点。 我忽略了MapKit框架文档中的一些function吗?

如果有人与纬度和长度混淆,这里testing,工作的解决scheme:

 MKCoordinateRegion region = self.mapView.region; CLLocationCoordinate2D location = user.gpsposition.coordinate; CLLocationCoordinate2D center = region.center; CLLocationCoordinate2D northWestCorner, southEastCorner; northWestCorner.latitude = center.latitude - (region.span.latitudeDelta / 2.0); northWestCorner.longitude = center.longitude - (region.span.longitudeDelta / 2.0); southEastCorner.latitude = center.latitude + (region.span.latitudeDelta / 2.0); southEastCorner.longitude = center.longitude + (region.span.longitudeDelta / 2.0); if ( location.latitude >= northWestCorner.latitude && location.latitude <= southEastCorner.latitude && location.longitude >= northWestCorner.longitude && location.longitude <= southEastCorner.longitude ) { // User location (location) in the region - OK :-) NSLog(@"Center (%f, %f) span (%f, %f) user: (%f, %f)| IN!", region.center.latitude, region.center.longitude, region.span.latitudeDelta, region.span.longitudeDelta, location.latitude, location.longitude); }else { // User location (location) out of the region - NOT ok :-( NSLog(@"Center (%f, %f) span (%f, %f) user: (%f, %f)| OUT!", region.center.latitude, region.center.longitude, region.span.latitudeDelta, region.span.longitudeDelta, location.latitude, location.longitude); } 

您可以将您的位置转换为MKMapPointForCoordinate的点,然后在mapview的visibleMapRect上使用visibleMapRect 。 这完全是我的头顶。 让我知道如果它的作品。

我发布这个答案,因为接受的解决scheme在我看来是无效的。 这个答案也不是完美的,但它处理的情况下,坐标绕360度的边界,这足以适合我的情况。

 + (BOOL)coordinate:(CLLocationCoordinate2D)coord inRegion:(MKCoordinateRegion)region { CLLocationCoordinate2D center = region.center; MKCoordinateSpan span = region.span; BOOL result = YES; result &= cos((center.latitude - coord.latitude)*M_PI/180.0) > cos(span.latitudeDelta/2.0*M_PI/180.0); result &= cos((center.longitude - coord.longitude)*M_PI/180.0) > cos(span.longitudeDelta/2.0*M_PI/180.0); return result; } 

其他答案都有错误。 接受的答案有点冗长,在国际date线附近失败。 余弦的答案是可行的,但是对于很小的区域是失败的(因为三angular形的余弦是正弦,趋近于零接近零,这意味着更小的angular度差异,我们期望零变化)这个答案应该适用于所有情况,并且更简单。

迅速:

 /* Standardises and angle to [-180 to 180] degrees */ class func standardAngle(var angle: CLLocationDegrees) -> CLLocationDegrees { angle %= 360 return angle < -180 ? -360 - angle : angle > 180 ? 360 - 180 : angle } /* confirms that a region contains a location */ class func regionContains(region: MKCoordinateRegion, location: CLLocation) -> Bool { let deltaLat = abs(standardAngle(region.center.latitude - location.coordinate.latitude)) let deltalong = abs(standardAngle(region.center.longitude - location.coordinate.longitude)) return region.span.latitudeDelta >= deltaLat && region.span.longitudeDelta >= deltalong } 

目标C:

 /* Standardises and angle to [-180 to 180] degrees */ + (CLLocationDegrees)standardAngle:(CLLocationDegrees)angle { angle %= 360 return angle < -180 ? -360 - angle : angle > 180 ? 360 - 180 : angle } /* confirms that a region contains a location */ + (BOOL)region:(MKCoordinateRegion*)region containsLocation:(CLLocation*)location { CLLocationDegrees deltaLat = fabs(standardAngle(region.center.latitude - location.coordinate.latitude)) CLLocationDegrees deltalong = fabs(standardAngle(region.center.longitude - location.coordinate.longitude)) return region.span.latitudeDelta >= deltaLat && region.span.longitudeDelta >= deltalong } 

这个方法对于包含任何一个极点的区域都是失败的,但是坐标系本身在极点失败。 对于大多数应用来说,这个解决scheme就足够了 (注意,未在Objective C上testing)

我已经使用这个代码来确定一个坐标是否在一个圆形的区域内(一个以它为圆心的坐标)。

 - (BOOL)location:(CLLocation *)location isNearCoordinate:(CLLocationCoordinate2D)coordinate withRadius:(CLLocationDistance)radius { CLCircularRegion *circularRegion = [[CLCircularRegion alloc] initWithCenter:location.coordinate radius:radius identifier:@"radiusCheck"]; return [circularRegion containsCoordinate:coordinate]; } 

欧文戈弗雷,目标C代码不起作用,这是好的代码:在Objective-C上失败,这是好的代码:

 /* Standardises and angle to [-180 to 180] degrees */ - (CLLocationDegrees)standardAngle:(CLLocationDegrees)angle { angle=fmod(angle,360); return angle < -180 ? -360 - angle : angle > 180 ? 360 - 180 : angle; } -(BOOL)thisRegion:(MKCoordinateRegion)region containsLocation:(CLLocation *)location{ CLLocationDegrees deltaLat =fabs([self standardAngle:(region.center.latitude-location.coordinate.latitude)]); CLLocationDegrees deltaLong =fabs([self standardAngle:(region.center.longitude-location.coordinate.longitude)]); return region.span.latitudeDelta >= deltaLat && region.span.longitudeDelta >=deltaLong; } CLLocationDegrees deltalong = fabs(standardAngle(region.center.longitude - location.coordinate.longitude)); return region.span.latitudeDelta >= deltaLat && region.span.longitudeDelta >= deltalong; } 

谢谢!

基于Lukasz的解决scheme,但在Swift中,如果有人可以使用Swift:

 func isInRegion (region : MKCoordinateRegion, coordinate : CLLocationCoordinate2D) -> Bool { let center = region.center; let northWestCorner = CLLocationCoordinate2D(latitude: center.latitude - (region.span.latitudeDelta / 2.0), longitude: center.longitude - (region.span.longitudeDelta / 2.0)) let southEastCorner = CLLocationCoordinate2D(latitude: center.latitude + (region.span.latitudeDelta / 2.0), longitude: center.longitude + (region.span.longitudeDelta / 2.0)) return ( coordinate.latitude >= northWestCorner.latitude && coordinate.latitude <= southEastCorner.latitude && coordinate.longitude >= northWestCorner.longitude && coordinate.longitude <= southEastCorner.longitude ) }