¿Cómo verificar si MKCoordinateRegion contiene CLLocationCoordinate2D sin usar MKMapView?

Necesito verificar si la location del usuario pertenece a MKCoordinateRegion. Me sorprendió no encontrar una function simple para esto, algo así: CGRectContainsCGPoint (rect, punto) .

Encontré la siguiente pieza de código:

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 } 

Pero, no estoy seguro si es preciso ya que la documentation no especifica exactamente cómo se calcula el rectángulo de la región.

Debe haber una forma más simple de hacerlo. ¿He pasado por alto alguna function en la documentation del marco MapKit?

Puede convertir su location a un punto con MKMapPointForCoordinate , luego use MKMapRectContainsPoint en MKMapRectContainsPoint de la vista de visibleMapRect . Esto está completamente fuera de mi cabeza. Déjame saber si funciona.

En caso de que haya alguien más confundido con latitudes y longitudes, aquí se testing, solución de trabajo:

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

Estoy publicando esta respuesta ya que la solución aceptada no es válida en mi opinión. Esta respuesta tampoco es perfecta, pero maneja el caso cuando las coorderadas se envuelven alnetworkingedor de límites de 360 ​​grados, lo cual es suficiente para ser adecuado en mi situación.

 + (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; } 

Las otras respuestas tienen fallas. La respuesta aceptada es un poco detallada y falla cerca de la línea de date internacional. La respuesta del coseno es viable, pero falla para regiones muy pequeñas (porque el coseno delta es un seno que tiende a cero cerca de cero, lo que significa que para diferencias angulares más pequeñas esperamos un cambio cero). Esta respuesta debería funcionar correctamente para todas las situaciones y es más simple.

Rápido:

 /* 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 objective:

 /* 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 } 

Este método falla para las regiones que incluyen polos, pero el sistema de coorderadas falla en los polos. Para la mayoría de las aplicaciones, esta solución debería ser suficiente. (Nota, no probado en el Objetivo C)

He usado este código para determinar si una coorderada está dentro de una región circular (una coorderada con un radio alnetworkingedor).

 - (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]; } 

Owen Godfrey, el código objective-C no funciona, este es el buen código: falla en Objective-C, este es el buen código:

 /* 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; } 

¡Gracias!

Basado en la solución de Lukasz, pero en Swift, en caso de que alguien pueda usar 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 ) }