web-dev-qa-db-fra.com

Obtenir les limites d'un MKMapView

Afin de configurer une requête sur un serveur externe, je souhaite connaître les limites de la carte actuelle dans une application iPhone en cours de construction. UIView devrait répondre aux limites, mais il semble que MKMapView ne le fasse pas. Après avoir défini une région et zoomé sur la carte, j'essaie d'obtenir les limites. Je suis bloqué sur la première étape qui consiste à essayer d'obtenir les CGPoints qui représentent les coins SE et NO de la carte. Après cela, j'allais utiliser:

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

Transformer les points en coordonnées cartographiques. Mais je ne peux même pas aller aussi loin ...

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

Le code est compilé sans avertissements mais se et nw sont tous deux nuls. En regardant self.mapView.bounds.Origin.x, la variable est 0. Essayer de NSLog directement self.mapView.bounds.size.width me donne un "signal de programme reçu:" EXC_BAD_ACCESS "." qui semble provenir de NSLog.

Quelqu'un sait-il comment obtenir le coin sud-est et le nord-ouest (en coordonnées de carte) de la zone visible d'un MKMapView?

EDIT: Il semble que chaque fois que vous demandez quelque chose ici, la réponse vous parvient juste après. J'utilisais% @ au lieu de @f pour imprimer chaque variable dans NSLog qui y renvoyait des erreurs. J'ai également découvert la propriété annotationVisibleRect de MKMapview. Il semble cependant que l'annotationVisibleRect soit basé sur les coordonnées de la vue parent.

31
deadroxy

D'accord, j'ai officiellement répondu à ma propre question, mais comme je ne l'ai trouvée nulle part auparavant, je posterai la réponse ici:

//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];
74
deadroxy

Une autre option consiste à utiliser la propriété visibleMapRect sur votre instance MKMapView et à utiliser MKCoordinateForMapPoint () pour convertir le fichier en 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);
41
afarnham

Swift away ... (Basé sur la réponse 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)
    }
}
9
Aviel Gross

This http://wiki.openstreetmap.org/wiki/Bounding_Box est un document pour le cadre de sélection

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

 enter image description here

Vous pouvez avoir une structure BoundingBox qui représente ceci

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,
    ]
  }
}

La visibleMapRect est la même chose 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)
6
onmyway133

J'ai pu faire en sorte que cela fonctionne avec la requête 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];
1
Cindy

ce site Web résout le problème. 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]];
}
1
Zgpeace

J'avais quelques problèmes avec certaines des autres réponses pour les cartes qui avaient été pivotées à 2 doigts. Ce code a fonctionné pour moi:

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

Ma réponse est dérivée de La réponse de 保 状 et du site Web associé entrez la description du lien ici . Son simplifié bas aussi 3 lignes pour les coins sud ouest et nord est.

0
Marc

Ce code fonctionne avec une carte tournant à 90/180 degrés. Set mapView.pitchEnabled = NO; pour moins de bugs.

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];
0
Can Aksoy