2010-11-12 5 views
14

Aperçu rapide de ce que je fais. UIMapView charge et affiche une seule annotation (jamais plus d'une). Sur la barre de menu, il y a un bouton Me localiser, en appuyant sur le userLocation est trouvé et affiché comme une deuxième annotation. J'ai alors MapView zoom arrière pour s'adapter à ces deux annotations dans la gamme, mais je suis incapable de trouver un moyen approprié de le faire. En fonction de l'emplacement de la première annotation par rapport à l'emplacement de l'utilisateur, il est possible que le zoom arrière ne soit pas suffisant. Par exemple, si l'annotation est au nord-ouest de l'utilisateur, il effectue un zoom arrière très fin.Quel est le meilleur moyen de réduire et d'ajuster toutes les annotations dans MapKit?

Mais si l'annotation est au sud-est de l'utilisateur, il suffit de zoomer suffisamment pour qu'ils soient juste coupés et vous devez faire un zoom arrière manuellement un peu plus. Voici le code que j'utilise, la variation de certains autres que j'ai trouvés sur SO.

 CLLocation *whereIAm = mapView.userLocation.location; 

     float lat = whereIAm.coordinate.latitude; 
     float lon = whereIAm.coordinate.longitude; 


     CLLocationCoordinate2D southWest = {[currentLatitude floatValue], [currentLongitude floatValue]}; 
     CLLocationCoordinate2D northEast = southWest; 

     southWest.latitude = MIN(southWest.latitude, lat); 
     southWest.longitude = MIN(southWest.longitude, lon); 

     northEast.latitude = MAX(northEast.latitude, lat); 
     northEast.longitude = MAX(northEast.longitude, lon); 

     CLLocation *locSouthWest = [[CLLocation alloc] initWithLatitude:southWest.latitude longitude:southWest.longitude]; 
     CLLocation *locNorthEast = [[CLLocation alloc] initWithLatitude:northEast.latitude longitude:northEast.longitude]; 

     CLLocationDistance meters = [locSouthWest distanceFromLocation:locNorthEast]; 

     MKCoordinateRegion region; 
     region.center.latitude = (southWest.latitude + northEast.latitude)/2.0; 
     region.center.longitude = (southWest.longitude + northEast.longitude)/2.0; 
     region.span.latitudeDelta = meters/111319.5 
     region.span.longitudeDelta = 7.0; 

     MKCoordinateRegion savedRegion = [mapView regionThatFits:region]; 
     [mapView setRegion:savedRegion animated:YES]; 

     [locSouthWest release]; 
     [locNorthEast release]; 

Y at-il une meilleure façon intégrée dans MapKit pour zoomer juste de telle sorte que les deux annotations ont, disons un demi-pouce entre eux au cadre extérieur? Je ne m'inquiète pas vraiment si l'utilisateur doit zoomer après, je veux juste qu'il fasse un zoom arrière correctement.

Répondre

32
-(void)zoomToFitMapAnnotations:(MKMapView*)mapView 
{ 
    if([mapView.annotations count] == 0) 
     return; 

    CLLocationCoordinate2D topLeftCoord; 
    topLeftCoord.latitude = -90; 
    topLeftCoord.longitude = 180; 

    CLLocationCoordinate2D bottomRightCoord; 
    bottomRightCoord.latitude = 90; 
    bottomRightCoord.longitude = -180; 

    for(MapAnnotation* annotation in mapView.annotations) 
    { 
     topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude); 
     topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude); 

     bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude); 
     bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude); 
    } 

    MKCoordinateRegion region; 
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5; 
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5; 
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides 
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides 

    region = [mapView regionThatFits:region]; 
    [mapView setRegion:region animated:YES]; 
} 

Extrait de: http://codisllc.com/blog/zoom-mkmapview-to-fit-annotations/

(. Utilisez tout le temps)

+0

Hmm J'ai essayé celui-ci à un moment donné et cela n'a pas fonctionné comme prévu non plus. J'ai eu les mêmes résultats. Je vais faire un coup rapide et revoir. Je rapporterai. –

+0

Que voulez-vous dire par "comme prévu?" Quels problèmes avez-vous? –

+0

Je l'ai juste mis en œuvre et ça marche mieux que ce que j'avais, donc je m'en tiendrai là. La seule chose qui est coupée maintenant est la légende que je peux résoudre en le faisant repop après l'animation. Merci de votre aide. –

1

Ceux qui font le MonoTouch C# codage

BasicMapAnnotation est classe Hériter de MKAnnotation

private void GetRegion(MKMapView mapView) 
{ 
    var userWasVisible = mapView.ShowsUserLocation; 
    mapView.ShowsUserLocation = false; // ignoring the blue blip 
    // start with the widest possible viewport 
    var tl = new CLLocationCoordinate2D(-90, 180); // top left 
    var br = new CLLocationCoordinate2D(90, -180); // bottom right 
    foreach (var an in mapView.Annotations) 
    { 
     // narrow the viewport bit-by-bit 
     CLLocationCoordinate2D coordinate = ((BasicMapAnnotation) an).Coordinate; 
     tl.Longitude = Math.Min(tl.Longitude, coordinate.Longitude); 
     tl.Latitude = Math.Max(tl.Latitude, coordinate.Latitude); 
     br.Longitude = Math.Max(br.Longitude, coordinate.Longitude); 
     br.Latitude = Math.Min(br.Latitude, coordinate.Latitude); 
    } 
    var center = new CLLocationCoordinate2D 
    { 
     // divide the range by two to get the center 
     Latitude = tl.Latitude - (tl.Latitude - br.Latitude)*0.5,Longitude = tl.Longitude + (br.Longitude - tl.Longitude)*0.5 

    }; 
    var span = new MKCoordinateSpan 
    { 
     // calculate the span, with 20% margin so pins aren’t on the edge 
     LatitudeDelta = Math.Abs(tl.Latitude - br.Latitude)*1.2,LongitudeDelta = Math.Abs(br.Longitude - tl.Longitude)*1.2 

    }; 
    var region = new MKCoordinateRegion {Center = center, Span = span}; 
    region = mapView.RegionThatFits(region); // adjusts zoom level too 
       mapView.SetRegion(region, true); // animated transition 
       mapView.ShowsUserLocation = 

    userWasVisible; 

} 
8

Dans iOS7, il y a une méthode qui fait exactement cela. Il suffit d'appeler:

[yourMapView showAnnotations:yourAnnotationsArray animated:YES]; 
+0

C'est génial. Merci de l'avoir montré. Pas aussi flexible que la fonction self-made mais ça marche. Serait cool si vous pouviez ajouter des insectes pour avoir plus d'espace autour des annotations. – palme

+0

Oh mon ... C'est parfait ... J'utilise du code autour de 30 lignes pour cela et j'ai été en train d'écoutes - cela fonctionne parfaitement! –

1

Vous pouvez utiliser ce code pour afficher toutes les annotations

MKMapRect zoomRect = MKMapRectNull; 
for (id <MKAnnotation> annotation in mapView.annotations) 
{ 
    MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate); 
    MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1); 
    zoomRect = MKMapRectUnion(zoomRect, pointRect); 
} 
[mapView setVisibleMapRect:zoomRect animated:YES]; 

si vous voulez inclure l'emplacement de l'utilisateur il suffit de remplacer deux lignes ci-dessous avec la première ligne de code ci-dessus

MKMapPoint annotationPoint = MKMapPointForCoordinate(mapView.userLocation.coordinate); 
MKMapRect zoomRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1); 
+0

en outre: double dx = zoomRect.size.width * CGRectGetWidth (self.map.bounds)/CGRectGetWidth (self.view.bounds); double dy = zoomRect.size.height * CGRectGetHeight (self.map.bounds)/CGRectGetHeight (self.view.bounds); zoomRect = MKMapRectInset (zoomRect, -dx/2, -dy/2); [self.map setVisibleMapRect: zoomRect animé: OUI]; –

Questions connexes