2010-11-12 9 views
14

Szybkie tło tego, co robię. UIMapView ładuje i pokazuje pojedynczą adnotację (Nigdy więcej niż jeden). Na pasku menu znajduje się przycisk Zlokalizuj mnie, po dotknięciu lokalizacji użytkownika znajduje się i wyświetla jako druga adnotacja. Następnie pomijam MapView, aby pasowały do ​​obu adnotacji w zasięgu, ale nie jestem w stanie znaleźć odpowiedniego sposobu. W zależności od tego, gdzie umieszczana jest pierwsza adnotacja w stosunku do lokalizacji użytkownika, czasami nie jest ona wystarczająco pomniejszana.Jaki jest najlepszy sposób, aby pomniejszyć i dopasować wszystkie adnotacje w MapKit

Na przykład, jeśli adnotacja jest północno-zachodnia od użytkownika, powoduje pomniejszenie. Ale jeśli adnotacja znajduje się na południowym wschodzie użytkownika, powiększa się tylko tyle, że są one po prostu odcinane i trzeba ręcznie zmniejszyć nieco więcej. Oto kod, którego używam, odmiany niektórych innych, które znalazłem na 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]; 

Czy istnieje lepszy sposób wbudowane MapKit tylko pomniejszyć tak, że oba mają adnotacje, powiedzmy, pół cala pomiędzy nimi na zewnętrznej ramie? Nie dbam o to, czy użytkownik musi później powiększyć, chcę tylko, żeby pomniejszył obraz.

Odpowiedz

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

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

(. Użyj go cały czas)

+0

Hmm Próbowałem tego w jednym punkcie i nie działało tak, jak tego oczekiwałem. Miałem takie same wyniki. Zamierzam szybko zrobić zdjęcie i zobaczyć ponownie. Odpowiem z powrotem. –

+0

Co masz na myśli mówiąc "zgodnie z oczekiwaniami?" Jakie masz problemy? –

+0

Właśnie to zaimplementowałem i działa lepiej niż to, co miałem, więc się z tym uporam. Jedyną rzeczą, która zostanie odcięta, jest objaśnienie, które można rozwiązać, wykonując repop po animacji. Dzięki za pomoc. –

1

Ci, którzy wykonują MonoTouch C# kodowanie

BasicMapAnnotation jest dziedziczyć klasy z 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

W iOS7 jest metoda, która właśnie to robi. Wystarczy zadzwonić:

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

To jest niesamowite. Dzięki za pokazanie. Nie jest tak elastyczny, jak funkcja stworzona przez siebie, ale wykonuje swoją pracę. Byłoby fajnie, gdybyś mógł dodać owady, by mieć więcej miejsca wokół adnotacji. – palme

+0

O mój ... To jest idealne ... Używałem kodu o długości około 30 linii, a ja podsłuchałem - działa to doskonale! –

1

Można użyć tego kodu, aby pokazać wszystkie adnotacje

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

jeśli chcesz dołączyć lokalizację użytkownika wystarczy wymienić dwie linie poniżej pierwszej linii powyższego kodu

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

dodatkowo: 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 ożywiony: YES]; –

Powiązane problemy