Obtención de los límites de un MKMapView

votos
29

Con el fin de configurar una consulta a un servidor externo Quiero obtener los límites del actual mapa en una aplicación para el iPhone que estoy construyendo. UIView debe responder a los límites pero parece MKMapView no lo hace. Después de establecer una región y el zoom en el mapa Trato de los límites. Estoy atascado en el primer paso, que es tratar de conseguir los PuntosCg que representan las esquinas SE y NW del mapa. Después de que iba a utilizar:

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

Para transformar los puntos en las coordenadas del mapa. Pero no puedo ni siquiera 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 compila sin advertencias sin embargo se y nw son ambas nulas. Mirando a self.mapView.bounds.origin.x la variable es 0. Tratando de NSLog directamente self.mapView.bounds.size.width me da señal de programa recibida:‘un EXC_BAD_ACCESS’. que parece provenir de NSLog.

Alguien sabe la manera apropiada para conseguir la esquina y el noroeste esquina sureste (en coordenadas del mapa) de la zona visible de un MKMapView?

EDIT: Parece cada vez que se le pide algo aquí la respuesta viene a ti justo después. Yo estaba usando% @ en lugar de @f para imprimir cada variable en NSLog que fue lanzando errores allí. También descubrí la propiedad annotationVisibleRect de MKMapView. Parece sin embargo que el annotationVisibleRect se basa en la vista padre coordenadas.

Publicado el 17/01/2010 a las 17:53
fuente por usuario
En otros idiomas...                            


10 respuestas

votos
73

De acuerdo respondí oficialmente mi propia pregunta, pero no desde que lo encontré en ningún otro sitio Voy a 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];
Respondida el 17/01/2010 a las 20:14
fuente por usuario

votos
38

Otra opción es utilizar la propiedad visibleMapRect en su instancia MKMapView y utilizar MKCoordinateForMapPoint () para convertir a la latitud / longitud.

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);
Respondida el 06/12/2010 a las 06:04
fuente por usuario

votos
9

Swift de distancia ... (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)
    }
}
Respondida el 23/02/2015 a las 21:30
fuente por usuario

votos
3

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

introducir descripción de la imagen aquí

Usted puede tener una BoundingBoxestructura que representa esta

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 visibleMapRectes el mismo queregion.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)
Respondida el 04/04/2017 a las 04:34
fuente por usuario

votos
1

este sitio web a resolver 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.x y:MKMapRectGetMaxY(mRect)];
}

-(CLLocationCoordinate2D)getCoordinateFromMapRectanglePoint:(double)x y:(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]];
}
Respondida el 18/12/2017 a las 10:14
fuente por usuario

votos
1

Yo era capaz de conseguir esto para trabajar con la consulta Analizar 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];
Respondida el 19/12/2014 a las 14:39
fuente por usuario

votos
0

Actualizado en respuesta excelente de onmyway133 para mis propósitos, que necesitaba las coordenadas de las cuatro esquinas:

struct BoundingBox {
    let topRight: CLLocationCoordinate2D
    let topLeft: CLLocationCoordinate2D
    let bottomRight: CLLocationCoordinate2D
    let bottomLeft: CLLocationCoordinate2D

    init(rect: MKMapRect) {
        topRight = MKMapPoint(x: rect.maxX, y: rect.origin.y).coordinate
        topLeft = MKMapPoint(x: rect.origin.x, y: rect.origin.y).coordinate
        bottomRight = MKMapPoint(x: rect.maxX, y: rect.maxY).coordinate
        bottomLeft = MKMapPoint(x: rect.origin.x, y: rect.maxY).coordinate
    }

    var items: [String: CLLocationCoordinate2D] {
        return [
            "topRight": topRight,
            "topLeft": topLeft,
            "bottomRight": bottomRight,
            "bottomLeft": bottomLeft,
        ]
    }

    var points: [CLLocationDegrees] {
        return [
            topRight.latitude,
            topRight.longitude,
            topLeft.latitude,
            topLeft.longitude,
            bottomRight.latitude,
            bottomRight.longitude,
            bottomLeft.latitude,
            bottomLeft.longitude,
        ]
    }
}

Y un ejemplo de cómo he utilizado estos datos:

        let boundingBox = BoundingBox(rect: mapView.visibleMapRect)
        var annotations = Array<MKPointAnnotation>()

        for point in boundingBox.items {
            let newPoint = MKPointAnnotation()
            newPoint.coordinate = point.value
            annotations.append(newPoint)
        }

        mapView.addAnnotations(annotations)
Respondida el 27/05/2019 a las 23:57
fuente por usuario

votos
0

Esta extensión resuelve este problema y mantener la centerCoordinatesintaxis en Swift 5

extension MKMapView {
    var northWestCoordinate: CLLocationCoordinate2D {
        return MKMapPoint(x: visibleMapRect.minX, y: visibleMapRect.minY).coordinate
    }

    var northEastCoordinate: CLLocationCoordinate2D {
        return MKMapPoint(x: visibleMapRect.maxX, y: visibleMapRect.minY).coordinate
    }

    var southEastCoordinate: CLLocationCoordinate2D {
        return MKMapPoint(x: visibleMapRect.maxX, y: visibleMapRect.maxY).coordinate
    }

    var southWestCoordinate: CLLocationCoordinate2D {
        return MKMapPoint(x: visibleMapRect.minX, y: visibleMapRect.maxY).coordinate
    }
}
Respondida el 17/04/2019 a las 18:02
fuente por usuario

votos
0

Tenía un poco de apuro con algunas de las otras respuestas para los mapas que habían estado 2 dedo girar. 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 respuesta陈保状's y el sitio web asociado ingrese Descripción enlace aquí . Sus simplificados abajo también 3 líneas para esquinas este oeste y norte sur.

Respondida el 24/08/2018 a las 20:04
fuente por usuario

votos
0

Este código funciona con el mapa de rotación como 90/180 grados. establecer mapView.pitchEnabled = NO; para 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];
Respondida el 14/10/2015 a las 22:17
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more