Подтвердить что ты не робот

IOS MKMapView увеличить, чтобы показать все маркеры

Я работаю с MKMapView и нарисовал несколько точек на карте. Я использовал MKCoordinateRegion и MKCoordinateSpan, чтобы включить масштабирование и т.д. Вокруг одной из точек - но это не то, что я хочу...

Я пытаюсь использовать нечто похожее на функцию Javascript для масштабирования. поэтому все мои точки должны быть видны пользователю. (В Великобритании будет около 10 баллов) Я бы хотел показать их всем, или, если большинство из них находились в районе Лондона, увеличьте масштаб.

Есть ли способ работать с этим программно?

4b9b3361

Ответ 1

Конечно. Вы хотите найти самые большие и наименьшие значения широты и долготы среди ваших аннотаций (которые вы можете сделать, итерации по map.annotations), затем установите карту, чтобы показать все из них.

// pad our map by 10% around the farthest annotations
#define MAP_PADDING 1.1

// we'll make sure that our minimum vertical span is about a kilometer
// there are ~111km to a degree of latitude. regionThatFits will take care of
// longitude, which is more complicated, anyway. 
#define MINIMUM_VISIBLE_LATITUDE 0.01

MKCoordinateRegion region;
region.center.latitude = (minLatitude + maxLatitude) / 2;
region.center.longitude = (minLongitude + maxLongitude) / 2;

region.span.latitudeDelta = (maxLatitude - minLatitude) * MAP_PADDING;

region.span.latitudeDelta = (region.span.latitudeDelta < MINIMUM_VISIBLE_LATITUDE)
    ? MINIMUM_VISIBLE_LATITUDE 
    : region.span.latitudeDelta;

region.span.longitudeDelta = (maxLongitude - minLongitude) * MAP_PADDING;

MKCoordinateRegion scaledRegion = [map regionThatFits:region];
[map setRegion:scaledRegion animated:YES];

Ответ 2

Если вы ориентируетесь только на iOS 7 или выше, вы можете теперь использовать:

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

Ответ 3

Вот улучшение, которое учитывает высоту представлений аннотаций, которые вы накладываете на карту (например, верхняя часть аннотации не обрезается, когда ее смещение координат находится внизу внизу). Или для дальнейшего обобщения, вы можете указать заполнение в пикселях в противоположность проценту. Для этого требуется двухступенчатый проход, в котором вы узнаете границы аннотаций, затем вы дополнительно увеличиваете границы, чтобы учесть наложение вашей карты.

- (void) zoomToAnnotationsBounds:(NSArray *)annotations {

CLLocationDegrees minLatitude = DBL_MAX;
CLLocationDegrees maxLatitude = -DBL_MAX;
CLLocationDegrees minLongitude = DBL_MAX;
CLLocationDegrees maxLongitude = -DBL_MAX;

for (MyAnnotation *annotation in annotations) {
            double annotationLat = annotation.coordinate.latitude;
            double annotationLong = annotation.coordinate.longitude;
    minLatitude = fmin(annotationLat, minLatitude);
    maxLatitude = fmax(annotationLat, maxLatitude);
    minLongitude = fmin(annotationLong, minLongitude);
    maxLongitude = fmax(annotationLong, maxLongitude);
}

    // See function below
[self setMapRegionForMinLat:minLatitude minLong:minLongitude maxLat:maxLatitude maxLong:maxLongitude];

// If your markers were 40 in height and 20 in width, this would zoom the map to fit them perfectly. Note that there is a bug in mkmapview set region which means it will snap the map to the nearest whole zoom level, so you will rarely get a perfect fit. But this will ensure a minimum padding.
UIEdgeInsets mapPadding = UIEdgeInsetsMake(40.0, 10.0, 0.0, 10.0);
CLLocationCoordinate2D relativeFromCoord = [self.mapView convertPoint:CGPointMake(0, 0) toCoordinateFromView:self.mapView];

// Calculate the additional lat/long required at the current zoom level to add the padding
CLLocationCoordinate2D topCoord = [self.mapView convertPoint:CGPointMake(0, mapPadding.top) toCoordinateFromView:self.mapView];
CLLocationCoordinate2D rightCoord = [self.mapView convertPoint:CGPointMake(0, mapPadding.right) toCoordinateFromView:self.mapView];
CLLocationCoordinate2D bottomCoord = [self.mapView convertPoint:CGPointMake(0, mapPadding.bottom) toCoordinateFromView:self.mapView];
CLLocationCoordinate2D leftCoord = [self.mapView convertPoint:CGPointMake(0, mapPadding.left) toCoordinateFromView:self.mapView];

double latitudeSpanToBeAddedToTop = relativeFromCoord.latitude - topCoord.latitude;
double longitudeSpanToBeAddedToRight = relativeFromCoord.latitude - rightCoord.latitude;
double latitudeSpanToBeAddedToBottom = relativeFromCoord.latitude - bottomCoord.latitude;
double longitudeSpanToBeAddedToLeft = relativeFromCoord.latitude - leftCoord.latitude;

maxLatitude = maxLatitude + latitudeSpanToBeAddedToTop;
minLatitude = minLatitude - latitudeSpanToBeAddedToBottom;

maxLongitude = maxLongitude + longitudeSpanToBeAddedToRight;
minLongitude = minLongitude - longitudeSpanToBeAddedToLeft;

[self setMapRegionForMinLat:minLatitude minLong:minLongitude maxLat:maxLatitude maxLong:maxLongitude];
}

-(void) setMapRegionForMinLat:(double)minLatitude minLong:(double)minLongitude maxLat:(double)maxLatitude maxLong:(double)maxLongitude {

    MKCoordinateRegion region;
    region.center.latitude = (minLatitude + maxLatitude) / 2;
    region.center.longitude = (minLongitude + maxLongitude) / 2;
    region.span.latitudeDelta = (maxLatitude - minLatitude);
    region.span.longitudeDelta = (maxLongitude - minLongitude);

    // MKMapView BUG: this snaps to the nearest whole zoom level, which is wrong- it doesn't respect the exact region you asked for. See http://stackoverflow.com/questions/1383296/why-mkmapview-region-is-different-than-requested
    [self.mapView setRegion:region animated:YES];
}

Ответ 4

Это старый вопрос, и я знаю, что вам может не понадобиться помощь. Но я просто помещаю его туда для всех, кто ищет способ сделать это сейчас, так как есть новый метод в MKMapView от iOS 7, который можно использовать. Он чист и прост.

Заявление

СВИФТ

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

OBJECTIVE-C

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

Параметры

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

Обсуждение

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

Ответ 5

Измененный ответ со всем совершенным рабочим кодом.

//Zooming the ploted Area
- (void)zoomToAnnotationsBounds:(NSArray *)latLongArray {
        __block CLLocationDegrees minLatitude = DBL_MAX;
        __block CLLocationDegrees maxLatitude = -DBL_MAX;
        __block CLLocationDegrees minLongitude = DBL_MAX;
        __block CLLocationDegrees maxLongitude = -DBL_MAX;

        [latLongArray enumerateObjectsUsingBlock:^(NSString *latLongObj, NSUInteger latLongIdx, BOOL *stop) {
            latLongObj = [latLongArray objectAtIndex:latLongIdx];
            NSArray *latLongPoint = [latLongObj componentsSeparatedByString:@","];

            double annotationLat = [[latLongPoint objectAtIndex:0] doubleValue];
            double annotationLong = [[latLongPoint objectAtIndex:1] doubleValue];
            minLatitude = fmin(annotationLat, minLatitude);
            maxLatitude = fmax(annotationLat, maxLatitude);
            minLongitude = fmin(annotationLong, minLongitude);
            maxLongitude = fmax(annotationLong, maxLongitude);
        }];

        [self setMapRegionForMinLat:minLatitude minLong:minLongitude maxLat:maxLatitude maxLong:maxLongitude];
}


-(void) setMapRegionForMinLat:(double)minLatitude minLong:(double)minLongitude maxLat:(double)maxLatitude maxLong:(double)maxLongitude {

    // pad our map by 10% around the farthest annotations

    // we'll make sure that our minimum vertical span is about a kilometer
    // there are ~111km to a degree of latitude. regionThatFits will take care of
    // longitude, which is more complicated, anyway.

    MKCoordinateRegion region;
    region.center.latitude = (minLatitude + maxLatitude) / 2;
    region.center.longitude = (minLongitude + maxLongitude) / 2;

    region.span.latitudeDelta = (maxLatitude - minLatitude) * MAP_PADDING;

    region.span.latitudeDelta = (region.span.latitudeDelta < MINIMUM_VISIBLE_LATITUDE)
    ? MINIMUM_VISIBLE_LATITUDE
    : region.span.latitudeDelta;

    region.span.longitudeDelta = (maxLongitude - minLongitude) * MAP_PADDING;

    MKCoordinateRegion scaledRegion = [regionsMapView regionThatFits:region];
    [regionsMapView setRegion:scaledRegion animated:YES];

}