Позиционирование MKMapView для отображения нескольких аннотаций одновременно - PullRequest
90 голосов
/ 26 августа 2009

У меня есть несколько аннотаций, которые я хочу добавить в свой MKMapView (это может быть 0-n элементов, где n обычно составляет около 5). Я могу добавить аннотации в порядке, но я хочу изменить размер карты, чтобы разместить все аннотации на экране сразу, и я не уверен, как это сделать.

Я смотрел на -regionThatFits:, но я не совсем уверен, что с этим делать. Я выложу код, чтобы показать, что у меня есть. Я думаю, что это должно быть в целом простой задачей, но я чувствую себя немного перегруженным MapKit.

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{

location = newLocation.coordinate;
//One location is obtained.. just zoom to that location

MKCoordinateRegion region;
region.center = location;

//Set Zoom level using Span
MKCoordinateSpan span;
span.latitudeDelta = 0.015;
span.longitudeDelta = 0.015;
region.span = span;
// Set the region here... but I want this to be a dynamic size
// Obviously this should be set after I've added my annotations
[mapView setRegion:region animated:YES];

// Test data, using these as annotations for now
NSArray *arr = [NSArray arrayWithObjects:@"one", @"two", @"three", @"four", nil];
float ex = 0.01;
for (NSString *s in arr) {
    JBAnnotation *placemark = [[JBAnnotation alloc] initWithLat:(location.latitude + ex) lon:location.longitude];
    [mapView addAnnotation:placemark];
    ex = ex + 0.005;
}
    // What do I do here?
    [mapView setRegion:[mapView regionThatFits:region] animated:YES];
}

Обратите внимание, что все это происходит, когда я получаю обновление местоположения ... Я не знаю, подходит ли это место для этого. Если нет, то где было бы лучше? -viewDidLoad

Заранее спасибо.

Ответы [ 22 ]

3 голосов
/ 26 февраля 2015

В iOS 7 появился новый метод MKMapView, который вы можете использовать

Декларация

SWIFT

func showAnnotations(_ annotations: [AnyObject]!,
            animated animated: Bool)

Objective-C

- (void)showAnnotations:(NSArray *)annotations
               animated:(BOOL)animated

Параметры

аннотации Аннотации, которые вы хотите видеть в карта. анимированный ДА, если вы хотите, чтобы изменение региона карты было анимированный, или НЕТ, если вы хотите, чтобы карта отображала новый регион сразу без анимации.

Обсуждение

вызов этого метода обновлений значение в собственности региона и потенциально других свойств отражать новую область карты.

2 голосов
/ 27 августа 2009

Одним из возможных решений может быть измерение расстояния между текущим местоположением и всеми аннотациями и использование метода MKCoordinateRegionMakeWithDistance для создания области, расстояние которой немного больше, чем самая дальняя аннотация.

Это, конечно, будет медленнее, если вы добавите больше комментариев.

2 голосов
/ 03 декабря 2014
- (void)zoomToFitMapAnnotations {

if ([self.mapview.annotations count] == 0) return;

int i = 0;
MKMapPoint points[[self.mapview.annotations count]];

//build array of annotation points
for (id<MKAnnotation> annotation in [self.mapview annotations])
    points[i++] = MKMapPointForCoordinate(annotation.coordinate);

MKPolygon *poly = [MKPolygon polygonWithPoints:points count:i];

[self.mapview setRegion:MKCoordinateRegionForMapRect([poly boundingMapRect]) animated:YES];
}
2 голосов
/ 23 декабря 2016

Я знаю, что это старый вопрос, но, если вы хотите отобразить все аннотации УЖЕ НА карте, используйте это:

 mapView.showAnnotations(mapView.annotations, animated: true)
2 голосов
/ 18 мая 2015

Основано на превосходном ответе me2 (теперь на Swift)

func coordinateRegionForCoordinates(coords: [CLLocationCoordinate2D]) -> MKCoordinateRegion {
    var rect: MKMapRect = MKMapRectNull
    for coord in coords {
        let point: MKMapPoint = MKMapPointForCoordinate(coord)
        rect = MKMapRectUnion(rect, MKMapRectMake(point.x, point.y, 0, 0))
    }
    return MKCoordinateRegionForMapRect(rect)
}
1 голос
/ 31 января 2012

Добавлено небольшое условие if для обработки 1 местоположения - для добавления к фрагменту кода мундуфы Для этого использовала функцию zoomToAnnotation pkclSoft:

if ([mapView.annotations count] == 1){
    MKCoordinateSpan span = {0.027, 0.027};
    region.span = span;
    CLLocationCoordinate2D singleCoordinate = [[mapView.annotations objectAtIndex:0] coordinate];
    region.center.latitude = singleCoordinate.latitude;
    region.center.longitude = singleCoordinate.longitude;
}
else
{
    // mustufa's code
}
0 голосов
/ 30 сентября 2017

Рассмотрим это расширение:

extension MKCoordinateRegion {
    init(locations: [CLLocationCoordinate2D], marginMultiplier: Double = 1.1) {
        let mapRect = locations.reduce(MKMapRect(), {
            let point = MKMapPointForCoordinate($1)
            let rect = MKMapRect(origin: point, size: MKMapSize(width: 0.0, height: 0.0))
            return MKMapRectUnion($0, rect)
        })

        var coordinateRegion = MKCoordinateRegionForMapRect(mapRect)
        coordinateRegion.span.latitudeDelta *= marginMultiplier
        coordinateRegion.span.longitudeDelta *= marginMultiplier
        self = coordinateRegion
    }
}
0 голосов
/ 08 апреля 2016

этот код работает для меня, он показывает все контакты с текущим местоположением, надеюсь, это поможет вам,

func setCenterForMap() {
    var mapRect: MKMapRect = MKMapRectNull
    for loc in mapView.annotations {
        let point: MKMapPoint = MKMapPointForCoordinate(loc.coordinate)
        print( "location is : \(loc.coordinate)");
        mapRect = MKMapRectUnion(mapRect, MKMapRectMake(point.x,point.y,0,0))
    }
    if (locationManager.location != nil) {
        let point: MKMapPoint = MKMapPointForCoordinate(locationManager.location!.coordinate)
        print( "Cur location is : \(locationManager.location!.coordinate)");
        mapRect = MKMapRectUnion(mapRect, MKMapRectMake(point.x,point.y,0,0))
    }

    mapView.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsetsMake(40.0, 40.0, 40.0, 40.0), animated: true)

}
0 голосов
/ 06 марта 2012

Надеюсь, это как минимум актуально, вот что я собрал для Mono (основываясь на ответе pkclSoft):

void ZoomMap (MKMapView map)
{
    var annotations = map.Annotations;

    if (annotations == null || annotations.Length == 0) 
        return;

    var points = annotations.OfType<MapAnnotation> ()
                            .Select (s => MKMapPoint.FromCoordinate (s.Coordinate))
                            .ToArray ();            

    map.SetVisibleMapRect(MKPolygon.FromPoints (points).BoundingMapRect, true); 
}
0 голосов
/ 27 июля 2012
CLLocationCoordinate2D min = CLLocationCoordinate2DMake(99999.0, 99999.0);
CLLocationCoordinate2D max = CLLocationCoordinate2DMake(-99999.0, -99999.0);

// find max/min....

// zoom to cover area
// TODO: Maybe better using a MKPolygon which can calculate its own fitting region.
CLLocationCoordinate2D center = CLLocationCoordinate2DMake((max.latitude + min.latitude) / 2.0, (max.longitude + min.longitude) / 2.0);
MKCoordinateSpan span = MKCoordinateSpanMake(max.latitude - min.latitude, max.longitude - min.longitude);
MKCoordinateRegion region = MKCoordinateRegionMake(center, span);

[_mapView setRegion:[_mapView regionThatFits:region] animated:YES];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...