Obteniendo los límites de un MKMapView

Para configurar una consulta a un servidor externo, quiero obtener los límites de la vista de mapa actual en una aplicación de iPhone que estoy construyendo. UIView debe responder a los límites, pero parece que MKMapView no lo hace. Después de establecer una región y hacer zoom en el mapa, bash obtener los límites. Estoy atascado en el primer paso, que es tratar de obtener los CGPoints que representan las esquinas SE y NW del mapa. Después de eso, iba a usar:

- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view 

Para transformar los puntos en coordenadas del mapa. Pero ni siquiera puedo llegar tan lejos …

 //Recenter and zoom map in on search location MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}}; region.center = mySearchLocation.searchLocation.coordinate; region.span.longitudeDelta = 0.01f; region.span.latitudeDelta = 0.01f; [self.mapView setRegion:region animated:YES]; //After the new search location has been added to the map, and the map zoomed, we need to update the search bounds //First we need to calculate the corners of the map CGPoint se = CGPointMake(self.mapView.bounds.origin.x, mapView.bounds.origin.y); CGPoint nw = CGPointMake((self.mapView.bounds.origin.x + mapView.bounds.size.width), (mapView.bounds.origin.y + mapView.bounds.size.height)); NSLog(@"points are: se %@, nw %@", se, nw); 

El código se comstack sin advertencias, sin embargo, se y nw son ambos nulos. Al mirar a self.mapView.bounds.origin.x, la variable es 0. Intentar con NSLog directamente self.mapView.bounds.size.width me da una “Señal de progtwig recibida:” EXC_BAD_ACCESS “.” que parece provenir de NSLog.

¿Alguien sabe la forma correcta de obtener la esquina sureste y la esquina noroeste (en las coordenadas del mapa) desde el área visible de un MKMapView?

EDITAR: Parece que siempre que preguntas algo aquí la respuesta viene a ti justo después. Estaba usando% @ en lugar de @f para imprimir cada variable en NSLog que estaba arrojando errores allí. También descubrí la propiedad annotationVisibleRect de MKMapview. Sin embargo, parece que el annotationVisibleRect se basa en las coordenadas de vista principal.

De acuerdo, oficialmente respondí mi propia pregunta, pero como no la encontré antes publicaré la respuesta aquí:

 //To calculate the search bounds... //First we need to calculate the corners of the map so we get the points CGPoint nePoint = CGPointMake(self.mapView.bounds.origin.x + mapView.bounds.size.width, mapView.bounds.origin.y); CGPoint swPoint = CGPointMake((self.mapView.bounds.origin.x), (mapView.bounds.origin.y + mapView.bounds.size.height)); //Then transform those point into lat,lng values CLLocationCoordinate2D neCoord; neCoord = [mapView convertPoint:nePoint toCoordinateFromView:mapView]; CLLocationCoordinate2D swCoord; swCoord = [mapView convertPoint:swPoint toCoordinateFromView:mapView]; 

Otra opción es usar la propiedad visibleMapRect en su instancia de MKMapView y usar MKCoordinateForMapPoint () para convertir a lat / lon.

 MKMapRect mRect = self.mapView.visibleMapRect; MKMapPoint neMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), mRect.origin.y); MKMapPoint swMapPoint = MKMapPointMake(mRect.origin.x, MKMapRectGetMaxY(mRect)); CLLocationCoordinate2D neCoord = MKCoordinateForMapPoint(neMapPoint); CLLocationCoordinate2D swCoord = MKCoordinateForMapPoint(swMapPoint); 

Swift away … (Basado en la respuesta de @ deadroxy …)

 typealias Edges = (ne: CLLocationCoordinate2D, sw: CLLocationCoordinate2D) extension MKMapView { func edgePoints() -> Edges { let nePoint = CGPoint(x: self.bounds.maxX, y: self.bounds.origin.y) let swPoint = CGPoint(x: self.bounds.minX, y: self.bounds.maxY) let neCoord = self.convertPoint(nePoint, toCoordinateFromView: self) let swCoord = self.convertPoint(swPoint, toCoordinateFromView: self) return (ne: neCoord, sw: swCoord) } } 

Este http://wiki.openstreetmap.org/wiki/Bounding_Box es un documento para el cuadro delimitador

 bbox = left,bottom,right,top bbox = min Longitude , min Latitude , max Longitude , max Latitude 

enter image description here

Puede tener una estructura BoundingBox que represente esto

 struct BoundingBox { let min: CLLocationCoordinate2D let max: CLLocationCoordinate2D init(rect: MKMapRect) { let bottomLeft = MKMapPointMake(rect.origin.x, MKMapRectGetMaxY(rect)) let topRight = MKMapPointMake(MKMapRectGetMaxX(rect), rect.origin.y) min = MKCoordinateForMapPoint(bottomLeft) max = MKCoordinateForMapPoint(topRight) } var points: [CLLocationDegrees] { return [ min.latitude, min.longitude, max.latitude max.longitude, ] } } 

El visibleMapRect es el mismo que region.span

 let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 320, height: 640)) XCTAssertEqual(mapView.userLocation.coordinate.latitude, 0) XCTAssertEqual(mapView.userLocation.coordinate.longitude, 0) let boundingBox = BoundingBox(rect: mapView.visibleMapRect) XCTAssertEqual(boundingBox.max.longitude-boundingBox.min.longitude, mapView.region.span.longitudeDelta) XCTAssertEqual(boundingBox.max.latitude-boundingBox.min.latitude, mapView.region.span.latitudeDelta) 

Pude hacer que esto funcionara con la consulta de Parse GeoBox:

 //Calculate the corners of the map to get the points CGPoint nePoint = CGPointMake(self.mapView.bounds.origin.x + self.mapView.bounds.size.width, self.mapView.bounds.origin.y); CGPoint swPoint = CGPointMake((self.mapView.bounds.origin.x),(self.mapView.bounds.origin.y+ self.mapView.bounds.size.height)); //Transform points into lat/long values CLLocationCoordinate2D NECoordinate = [self.mapView convertPoint:nePoint toCoordinateFromView:self.mapView]; CLLocationCoordinate2D SWCoordinate = [self.mapView convertPoint:swPoint toCoordinateFromView:self.mapView]; //Convert to Parse GeoPoints PFGeoPoint *Southwest = [PFGeoPoint geoPointWithLatitude:SWCoordinate.latitude longitude:SWCoordinate.longitude]; PFGeoPoint *Northeast = [PFGeoPoint geoPointWithLatitude:NECoordinate.latitude longitude:NECoordinate.longitude]; 

este sitio web resuelve el problema. http://www.softwarepassion.com/how-to-get-geographic-coordinates-of-the-visible-mkmapview-area-in-ios/

 MKMapRect mRect = self.mapView.visibleMapRect; -(CLLocationCoordinate2D)getNECoordinate:(MKMapRect)mRect{ return [self getCoordinateFromMapRectanglePoint:MKMapRectGetMaxX(mRect) y:mRect.origin.y]; } -(CLLocationCoordinate2D)getNWCoordinate:(MKMapRect)mRect{ return [self getCoordinateFromMapRectanglePoint:MKMapRectGetMinX(mRect) y:mRect.origin.y]; } -(CLLocationCoordinate2D)getSECoordinate:(MKMapRect)mRect{ return [self getCoordinateFromMapRectanglePoint:MKMapRectGetMaxX(mRect) y:MKMapRectGetMaxY(mRect)]; } -(CLLocationCoordinate2D)getSWCoordinate:(MKMapRect)mRect{ return [self getCoordinateFromMapRectanglePoint:mRect.origin.xy:MKMapRectGetMaxY(mRect)]; } -(CLLocationCoordinate2D)getCoordinateFromMapRectanglePoint:(double)xy:(double)y{ MKMapPoint swMapPoint = MKMapPointMake(x, y); return MKCoordinateForMapPoint(swMapPoint); } -(NSArray *)getBoundingBox:(MKMapRect)mRect{ CLLocationCoordinate2D bottomLeft = [self getSWCoordinate:mRect]; CLLocationCoordinate2D topRight = [self getNECoordinate:mRect]; return @[[NSNumber numberWithDouble:bottomLeft.latitude ], [NSNumber numberWithDouble:bottomLeft.longitude], [NSNumber numberWithDouble:topRight.latitude], [NSNumber numberWithDouble:topRight.longitude]]; } 

Este código funciona con un mapa que gira como 90/180 grados. establecer mapView.pitchEnabled = NO; por menos errores.

 CLLocationDirection heading = mapView.camera.heading; float mapWidth = mapView.frame.size.width; float mapHeight = mapView.frame.size.height; float neX = mapWidth; float neY = 0.0; float swX = 0.0; float swY = mapHeight; if (heading >= 0 && heading <= 90) { //println("Q1") float ratio = heading / 90; neX = (1-ratio) * mapWidth; swX = (mapWidth*ratio); } else if (heading >= 90 && heading <= 180) { //println("Q2") float ratio = (heading - 90) / 90; neX = 0; neY = (mapHeight*ratio); swY = (1-ratio) * mapHeight; swX = mapWidth; } else if (heading >= 180 && heading <= 270) { //println("Q3") float ratio = (heading - 180) / 90; neX = mapWidth*ratio; neY = mapHeight; swX = (1-ratio) * mapWidth; swY = 0; } else if (heading >= 270 && heading <= 360) { //println("Q4"); float ratio = (heading - 270) / 90; neX = mapWidth; neY = (1-ratio) * mapHeight; swY = ratio * mapHeight; } CGPoint swPoint = CGPointMake(swX, swY); CGPoint nePoint = CGPointMake(neX, neY); CLLocationCoordinate2D swCoord = [mapView convertPoint:swPoint toCoordinateFromView:mapView]; CLLocationCoordinate2D neCoord = [mapView convertPoint:nePoint toCoordinateFromView:mapView]; 

Estaba teniendo algunos problemas con algunas de las otras respuestas para mapas que habían sido rotados con 2 dedos. Este código funcionó para mí:

 MKMapRect rect = self.mapView.visibleMapRect; CLLocationCoordinate2D northeast = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMaxX(rect),rect.origin.y)); CLLocationCoordinate2D southwest = MKCoordinateForMapPoint(MKMapPointMake(rect.origin.x ,MKMapRectGetMaxY(rect))); 

Mi respuesta se deriva de la respuesta de 陈 保 and y el sitio web asociado introduce la descripción del enlace aquí . Se simplificó también 3 líneas para las esquinas suroeste y noreste.