2010-11-12 9 views
14

Fondo rápido de lo que estoy pasando. UIMapView carga y muestra una sola anotación (nunca más de una). En la barra de menú, hay un botón Ubicarme, al tocar se encuentra la ubicación del usuario y se muestra como una segunda anotación. Luego, tengo MapView alejamiento para ajustar ambas anotaciones en el rango, pero no puedo encontrar una forma adecuada de hacerlo. Dependiendo de dónde se coloque la primera anotación en relación con la ubicación del usuario, a veces no se aleja lo suficiente.Cuál es la mejor manera de alejar y ajustar todas las anotaciones en MapKit

Por ejemplo, si la anotación está al noroeste del usuario, se aleja bien. Pero si la anotación está al sudeste del usuario, solo se aleja lo suficiente como para que se corte y tiene que alejarse manualmente un poco más. Aquí está el código que estoy usando, variación de algunos otros que he encontrado en 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]; 

¿Hay una mejor manera integrada en MapKit para ampliar acaba de salir de modo que ambos tienen anotaciones, digamos media pulgada entre ellos en el marco exterior? Realmente no me importa si el usuario tiene que acercarse más, solo quiero que se aleje correctamente.

Respuesta

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

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

(. Se usa todo el tiempo)

+0

Hmm Probé este en un punto y tampoco funcionó como se esperaba. Yo tuve los mismos resultados. Sin embargo, voy a darle una oportunidad rápida y volver a ver. Informaré de nuevo. –

+0

¿Qué quiere decir con "como se esperaba"? ¿Qué problemas tienes? –

+0

Acabo de implementarlo y funciona mejor de lo que tenía, así que me quedaré con él. Lo único que se corta ahora es la leyenda, que puedo resolver haciéndola repop después de la animación. Gracias por tu ayuda. –

1

Los que hacen la MonoTouch c codificación

BasicMapAnnotation # es la clase hereda 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

En iOS7 hay un método que hace precisamente eso. Sólo tiene que llamar:

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

Esto es asombroso. Gracias por mostrarlo No es tan flexible como la función hecha a sí mismo pero funciona. Sería genial si pudiera agregar insectos para tener más espacio alrededor de las anotaciones. – palme

+0

Oh mi ... Esto es perfecto ... He estado usando código de alrededor de 30 líneas para esto y he estado molestando - ¡esto funciona perfectamente! –

1

Usted puede utilizar este código para mostrar todas las anotaciones

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 desea incluir la ubicación del usuario basta con sustituir dos líneas más abajo con la primera línea de código anterior

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

además: 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 animated: YES]; –

Cuestiones relacionadas