Какой лучший способ уменьшить масштаб и поместить все аннотации в MapKit

Краткая информация о том, что у меня происходит. UIMapView загружает и показывает одну аннотацию (не более одного). В строке меню есть кнопка "Найти меня", нажмите "userLocation" и вы увидите ее как вторую аннотацию. Затем я убираю MapView, чтобы соответствовать обоим аннотациям в диапазоне, но я не могу найти подходящий способ сделать это. В зависимости от того, где первая аннотация размещена в зависимости от местоположения пользователя, иногда она не уменьшает масштаб.

Например, если аннотация находится на северо-западе пользователя, она отлично масштабируется. Но если аннотация находится на юго-востоке пользователя, она просто масштабируется настолько, что их просто обрезают, и вам придется вручную уменьшить масштаб. Вот код, который я использую, вариация некоторых других, которые я нашел на 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];

Есть ли лучший способ, встроенный в MapKit, просто уменьшить масштаб, чтобы обе аннотации имели, скажем, половину дюйма между ними во внешнем кадре? Меня не волнует, если пользователь должен увеличивать масштаб после, я просто хочу, чтобы он правильно уменьшал изображение.

Ответы

Ответ 1

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

Взято из: http://codisllc.com/blog/zoom-mkmapview-to-fit-annotations/

(Используйте его все время.)

Ответ 2

В iOS7 есть метод, который делает именно это. Просто позвоните:

[yourMapView showAnnotations:yourAnnotationsArray animated:YES];

Ответ 3

Те, кто делает кодирование С# monotouch

BasicMapAnnotation наследует класс от 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;

}

Ответ 4

Вы можете использовать этот код, чтобы показать все аннотации

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

если вы хотите включить местоположение пользователя, просто замените две строки ниже первой строкой выше кода

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