한 번에 여러 주석을 표시하도록 MKMapView 배치


92

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?

미리 감사드립니다.

답변:



137

링크 (I 즐겨 찾기에 어딘가에 있던) 짐에 의해 게시 이제 죽었,하지만 난 코드를 찾을 수 있었다. 도움이 되었기를 바랍니다.

- (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(id<MKAnnotation> 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;      

    // Add a little extra space on the sides
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1;
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; 

    region = [mapView regionThatFits:region]; 
    [mapView setRegion:region animated:YES]; 
}

14
키스 할 수 있습니다. 이것은 저에게 많은 시간을 절약했습니다. 위의 코드를 추가하여 한 위치를 처리했습니다. 좀 더 가까이서 개인적으로 보였습니다. 댓글은 코드를 씹는 경향이 있으므로 답변으로 게시하겠습니다.
Michael Reed

대단히 감사합니다. 나는 이것을의 서브 클래스에 추가 MKMapView하고 메서드를 - (void) zoomToFitAnnotations:(BOOL)animated. 완벽하게 작동합니다!
simonbs

1
아주 잘 작동합니다. 또한 유용합니다. 축소 또는 확대 값을 변경할 수 있습니다. 그래서 region.span.latitudeDelta = fabs (topLeftCoord.latitude-bottomRightCoord.latitude) * 1.1; /// 값을 변경합니다. 값을 늘릴 때 : 축소 ........ 값을 줄이면 확대 : 예 : region.span.latitudeDelta = fabs (topLeftCoord.latitude-bottomRightCoord.latitude) * 4.1;
Erhan Demirci 2013 년

1
@ MR.Mustafa : 작동, 굉장합니다! 그러나 나는 문제를 해결하는 것으로 충분하다고 생각합니다. 그래서 어떤 사람이 어떻게 작동하는지 설명 해주세요. 또는 링크를 통해. 내가 어리 석다면 미안하다. 나는 초보자 다. Pls 지원. 감사합니다
Siddarth Hailstorm

1
@Mustafa ... 감사합니다.
Vvk

133

왜 그렇게 복잡합니까?

MKCoordinateRegion coordinateRegionForCoordinates(CLLocationCoordinate2D *coords, NSUInteger coordCount) {
    MKMapRect r = MKMapRectNull;
    for (NSUInteger i=0; i < coordCount; ++i) {
        MKMapPoint p = MKMapPointForCoordinate(coords[i]);
        r = MKMapRectUnion(r, MKMapRectMake(p.x, p.y, 0, 0));
    }
    return MKCoordinateRegionForMapRect(r);
}

6
이것이 게시 된 대안보다 얼마나 더 간단하고, 깨끗하고, 더 쉬운 지 믿기지 않습니다. 실제로 MKCoordinateRegion으로 변환 할 필요가 없기 때문에이 작업을 더욱 단순화 할 수 있습니다. 여기서 생성 한 MKMapRect를 사용하여 MKMapView에서 setVisibleMapRect :를 호출하기 만하면됩니다.
lensovet 2013 년

2
주석이지도 상단에 붙어 보이지 않는 경우가 있습니다. MKCoordinateRegion을 만든 후 확대 / 축소를 늘리는 가장 좋은 방법에 대한 입력이 있습니까?
Kyle C

3
@KyleC[mapView setVisibleMapRect:mapRect edgePadding:UIEdgeInsetsMake(20.0f, 20.0f, 20.0f, 20.0f) animated:animated];
사용자

CLLocationCoordinate2D *coords어레이를 어떻게 생성 합니까? 사용 malloc()?
Hlung

3
@KyleC. 내가 돌아 오기 전에이 추가 r기본적으로 20 % 축소하는CGFloat zoomOutPercent = 0.2f; r = MKMapRectMake(r.origin.x-r.size.width*zoomOutPercent, r.origin.y-r.size.height*zoomOutPercent, r.size.width*(1+zoomOutPercent*2), r.size.height*(1+zoomOutPercent*2));
Loozie

44

점 주석과 현재 위치가 포함 된 영역을 축소 (또는 축소)하기 위해 이와 유사한 작업을 수행했습니다. 주석을 반복하여 확장 할 수 있습니다.

기본 단계는 다음과 같습니다.

  • 최소 위도 / 경도 계산
  • 최대 위도 / 경도 계산
  • 이 두 지점에 대한 CLLocation 객체 생성
  • 점 사이의 거리 계산
  • 점 사이의 중심점과 각도로 변환 된 거리를 사용하여 영역 만들기
  • 조정을 위해 지역을 MapView로 전달
  • 조정 된 영역을 사용하여 MapView 영역 설정
    -(IBAction)zoomOut:(id)sender {

        CLLocationCoordinate2D southWest = _newLocation.coordinate;
        CLLocationCoordinate2D northEast = southWest;

        southWest.latitude = MIN(southWest.latitude, _annotation.coordinate.latitude);
        southWest.longitude = MIN(southWest.longitude, _annotation.coordinate.longitude);

        northEast.latitude = MAX(northEast.latitude, _annotation.coordinate.latitude);
        northEast.longitude = MAX(northEast.longitude, _annotation.coordinate.longitude);

        CLLocation *locSouthWest = [[CLLocation alloc] initWithLatitude:southWest.latitude longitude:southWest.longitude];
        CLLocation *locNorthEast = [[CLLocation alloc] initWithLatitude:northEast.latitude longitude:northEast.longitude];

        // This is a diag distance (if you wanted tighter you could do NE-NW or NE-SE)
        CLLocationDistance meters = [locSouthWest getDistanceFrom: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 = 0.0;

        _savedRegion = [_mapView regionThatFits:region];
        [_mapView setRegion:_savedRegion animated:YES];

        [locSouthWest release];
        [locNorthEast release];
    }

이것은 갈 길처럼 보입니다. 감사!
jbrennan 2009-08-27

1
이 사용 일하러 가야 관리 MKCoordinateRegionMake: gist.github.com/1599700을 경우 사람에 아직도 이런 식으로 할 싶어요.
chakrit

region.center.latitude = (southWest.latitude + northEast.latitude) / 2.0; 감사합니다
Tony

이것은 자오선의 양쪽에있는 점에서 작동합니까? 적도?
Eliot

1
이 코드는 위치가 유사한 y 값을 가질 때 위치를 화면 밖으로 배치합니다. 예를 들어 (50, -4) 및 (100, -3)에 두 위치를 표시하면지도가 너무 멀리 확대되어 화면의 왼쪽과 오른쪽에 좌표가 배치됩니다.
사용자

21

대답이 다릅니다. 내가 직접 확대 / 축소 알고리즘을 구현하려고했지만 Apple 많은 작업 없이도 원하는 작업을 수행 할 수있는 방법이 있어야 한다고 생각했습니다 . API doco를 사용하면 MKPolygon을 사용하여 필요한 작업을 수행 할 수 있음을 빠르게 보여주었습니다.

/* this simply adds a single pin and zooms in on it nicely */
- (void) zoomToAnnotation:(MapAnnotation*)annotation {
    MKCoordinateSpan span = {0.027, 0.027};
    MKCoordinateRegion region = {[annotation coordinate], span};
    [mapView setRegion:region animated:YES];
}

/* This returns a rectangle bounding all of the pins within the supplied
   array */
- (MKMapRect) getMapRectUsingAnnotations:(NSArray*)theAnnotations {
    MKMapPoint points[[theAnnotations count]];

    for (int i = 0; i < [theAnnotations count]; i++) {
        MapAnnotation *annotation = [theAnnotations objectAtIndex:i];
        points[i] = MKMapPointForCoordinate(annotation.coordinate);
    }

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

    return [poly boundingMapRect];
}

/* this adds the provided annotation to the mapview object, zooming 
   as appropriate */
- (void) addMapAnnotationToMapView:(MapAnnotation*)annotation {
    if ([annotations count] == 1) {
        // If there is only one annotation then zoom into it.
        [self zoomToAnnotation:annotation];
    } else {
        // If there are several, then the default behaviour is to show all of them
        //
        MKCoordinateRegion region = MKCoordinateRegionForMapRect([self getMapRectUsingAnnotations:annotations]);

        if (region.span.latitudeDelta < 0.027) {
            region.span.latitudeDelta = 0.027;
        }

        if (region.span.longitudeDelta < 0.027) {
            region.span.longitudeDelta = 0.027;
        }
        [mapView setRegion:region];
    }

    [mapView addAnnotation:annotation];
    [mapView selectAnnotation:annotation animated:YES];
}

도움이 되었기를 바랍니다.


아무 문제 없습니다. 당신이 기꺼이 그것을 할 시간이 있다면 일반적으로 더 나은 방법이 있습니다.
PKCLsoft

나는 이것이 화면의 가장자리에 너무 가깝게 핀을 놓는 것을 발견했습니다. annotationsRegion.span.latitudeDelta = annotationsRegion.span.latitudeDelta * kEventMapDetailBorderFactor를 추가해보세요. setRegion 바로 전에.
Adam Eberbach

@AdamEberbach의 말이 맞지만 클립에 사용할 수없는 상수가 포함 된 것 같습니다. 핀 주변에 "멋진"테두리를 제공하는 값을 찾았습니까?
PKCLsoft

iOS7에서 새로운 showAnnotations 메서드를 사용하는 방법에 대한 Code Commander의 답변은이 코드가 더 멋지지만 실제로 더 잘 작동하는 좋은 여백을 추가합니다.
James Toomey

14

이 방법으로도 할 수 있습니다 ..

// Position the map so that all overlays and annotations are visible on screen.
MKMapRect regionToDisplay = [self mapRectForAnnotations:annotationsToDisplay];
if (!MKMapRectIsNull(regionToDisplay)) myMapView.visibleMapRect = regionToDisplay;

- (MKMapRect) mapRectForAnnotations:(NSArray*)annotationsArray
{
    MKMapRect mapRect = MKMapRectNull;

    //annotations is an array with all the annotations I want to display on the map
    for (id<MKAnnotation> annotation in annotations) { 

        MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
        MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);

        if (MKMapRectIsNull(mapRect)) 
        {
            mapRect = pointRect;
        } else 
        {
            mapRect = MKMapRectUnion(mapRect, pointRect);
        }
    }

     return mapRect;
}

13

모든 사람들의 정보와 제안을 바탕으로 다음과 같이 생각했습니다. 기여 해주신이 토론의 모든 분들께 감사드립니다.

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

이것은 더 많은 투표를 얻을 것입니다. 매우 정확하고 요점.
Natasha

5

제 경우에는 CLLocation 객체로 시작하여 각각에 대한 주석을 작성합니다.
두 개의 주석 만 배치하면되므로 점 배열을 만드는 간단한 방법이 있지만 CLLocation 집합이 주어지면 임의의 길이로 배열을 만들기 위해 쉽게 확장 할 수 있습니다.

내 구현은 다음과 같습니다 (MKMapPoints를 만들 필요가 없음).

//start with a couple of locations
CLLocation *storeLocation = store.address.location.clLocation;
CLLocation *userLocation = [LBLocationController sharedController].currentLocation;

//build an array of points however you want
CLLocationCoordinate2D points[2] = {storeLocation.coordinate, userLocation.coordinate};

//the magic part
MKPolygon *poly = [MKPolygon polygonWithCoordinates:points count:2];
[self.mapView setRegion:MKCoordinateRegionForMapRect([poly boundingMapRect])];

5

Swift, 다각형 및 추가 패딩을 사용하여 다음을 사용했습니다.

func zoomToFit() {
    var allLocations:[CLLocationCoordinate2D] = [
        CLLocationCoordinate2D(latitude: 32.768805, longitude: -117.167119),
        CLLocationCoordinate2D(latitude: 32.770480, longitude: -117.148385),
        CLLocationCoordinate2D(latitude: 32.869675, longitude: -117.212929)
    ]

    var poly:MKPolygon = MKPolygon(coordinates: &allLocations, count: allLocations.count)

    self.mapView.setVisibleMapRect(poly.boundingMapRect, edgePadding: UIEdgeInsetsMake(40.0, 40.0, 40.0, 40.0), animated: false)
}


setVisibleMapRect (...). 나 스스로 수학을하고 있었어 ..
CodeReaper 2011

3

iOS 7부터 'MKMapView'에 사용할 수있는 새로운 방법이 있습니다.

선언

빠른

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

목표 -C

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

매개 변수

주석지도에 표시 할 주석입니다. 애니메이션 맵 영역 변경에 애니메이션을 적용하려면 YES, 애니메이션없이 새 영역을 즉시 표시하려면 NO를 선택하십시오.

토론

이 메서드를 호출하면 region 속성의 값과 잠재적으로 다른 속성이 새지도 영역을 반영하도록 업데이트됩니다.


3

나는 이것이 오래된 질문이라는 것을 알고 있지만 모든 주석을 이미지도에 표시하려면 다음을 사용하십시오.

 mapView.showAnnotations(mapView.annotations, animated: true)

3

Mustafa의 답변에 대한 SWIFT 동등 항목 (작업 확인 : Xcode6.1, SDK 8.2)은 다음과 같습니다.

func zoomToFitMapAnnotations() {
    if self.annotations.count == 0 {return}

    var topLeftCoordinate = CLLocationCoordinate2D(latitude: -90, longitude: 180)
    var bottomRightCoordinate = CLLocationCoordinate2D(latitude: 90, longitude: -180)

    for object in self.annotations {
        if let annotation = object as? MKAnnotation {
            topLeftCoordinate.longitude = fmin(topLeftCoordinate.longitude, annotation.coordinate.longitude)
            topLeftCoordinate.latitude = fmax(topLeftCoordinate.latitude, annotation.coordinate.latitude)
            bottomRightCoordinate.longitude = fmax(bottomRightCoordinate.longitude, annotation.coordinate.longitude)
            bottomRightCoordinate.latitude = fmin(bottomRightCoordinate.latitude, annotation.coordinate.latitude)
        }
    }

    let center = CLLocationCoordinate2D(latitude: topLeftCoordinate.latitude - (topLeftCoordinate.latitude - bottomRightCoordinate.latitude) * 0.5, longitude: topLeftCoordinate.longitude - (topLeftCoordinate.longitude - bottomRightCoordinate.longitude) * 0.5)

    print("\ncenter:\(center.latitude) \(center.longitude)")
    // Add a little extra space on the sides
    let span = MKCoordinateSpanMake(fabs(topLeftCoordinate.latitude - bottomRightCoordinate.latitude) * 1.01, fabs(bottomRightCoordinate.longitude - topLeftCoordinate.longitude) * 1.01)
    print("\nspan:\(span.latitudeDelta) \(span.longitudeDelta)")

    var region = MKCoordinateRegion(center: center, span: span)


    region = self.regionThatFits(region)

    self.setRegion(region, animated: true)

}

1
안녕하세요 iOS_Developer. Swift 변환에 감사드립니다. 저에게는 topLeftCoordinate.latitude 및 bottomRightCoordinate.longitude에 대해 "fmin"대신 두 개의 "fmax"가 누락되었다고 생각하기 때문에 작동하지 않습니다.
Philipp Otto

2

한 가지 가능한 해결책은 현재 위치와 모든 주석 사이의 거리를 측정하고 MKCoordinateRegionMakeWithDistance 메서드를 사용하여 가장 먼 주석보다 약간 더 먼 거리를 갖는 영역을 만드는 것입니다.

물론 더 많은 주석을 추가할수록 속도가 느려집니다.


나는 자신을 검증하기 위해서만 댓글 섹션을 살펴 보았다. 다른 사람이 내가 한 방식으로 생각하는 것이 기쁩니다. :-) 두 개의 주석 (시작점과 끝점) 만 추가했기 때문에 느림을 느끼지 않았습니다.
thandasoru

2
- (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

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

mustufa의 cound 코드 스 니펫에 추가하기 위해 1 개의 위치를 ​​처리하는 약간의 if 절을 추가했습니다. 이를 위해 pkclSoft의 zoomToAnnotation 함수를 사용했습니다.

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
}

1

이 코드는 저에게 효과적이며 현재 위치의 모든 핀을 보여줍니다.

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

나는 이것이 적어도 관련이 있기를 바랍니다. 이것은 내가 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
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];

0

me2 응답을 기반으로 MKMapView에 대한 범주를 작성하여 여백을 추가하고 사용자 위치 주석을 건너 뜁니다.

@interface MKMapView (ZoomToFitAnnotations)
- (void)zoomToFitAnnotations:(BOOL)animated;
@end

@implementation MKMapView (ZoomToFitAnnotations)
- (void)zoomToFitAnnotations:(BOOL)animated {
    if (self.annotations.count == 0)
        return;

    MKMapRect rect = MKMapRectNull;
    for (id<MKAnnotation> annotation in self.annotations) {
        if ([annotation isKindOfClass:[MKUserLocation class]] == false) {
            MKMapPoint point = MKMapPointForCoordinate(annotation.coordinate);
            rect = MKMapRectUnion(rect, MKMapRectMake(point.x, point.y, 0, 0));
        }
    }

    MKCoordinateRegion region = MKCoordinateRegionForMapRect(rect);
    region.span.longitudeDelta *= 2; // Margin
    region.span.latitudeDelta *= 2; // Margin
    [self setRegion:region animated:animated];
}
@end

0

답변에 대해 언급 할 수 없기 때문에 @ me2의 답변에 약간의 편의를 추가하고 싶습니다 (여기에서 찾은 가장 우아한 접근 방식이라고 생각했기 때문에).

내 개인 프로젝트에서는 MKMapView 클래스에 범주를 추가하여 일반적인 작업을위한 "표시 영역"기능을 캡슐화했습니다. MKMapView 인스턴스에 현재로드 된 모든 주석을 볼 수 있도록 설정하는 것입니다. 결과는 다음과 같습니다.

.h 파일

#import <MapKit/MapKit.h>

@interface MKMapView (Extensions)

-(void)ij_setVisibleRectToFitAllLoadedAnnotationsAnimated:(BOOL)animated;
-(void)ij_setVisibleRectToFitAnnotations:(NSArray *)annotations animated:(BOOL)animated;


@end

.m 파일

#import "MKMapView+Extensions.h"

@implementation MKMapView (Extensions)

/**
 *  Changes the currently visible portion of the map to a region that best fits all the currently loadded annotations on the map, and it optionally animates the change.
 *
 *  @param animated is the change should be perfomed with an animation.
 */
-(void)ij_setVisibleRectToFitAllLoadedAnnotationsAnimated:(BOOL)animated
{
    MKMapView * mapView = self;

    NSArray * annotations = mapView.annotations;

    [self ij_setVisibleRectToFitAnnotations:annotations animated:animated];

}


/**
 *  Changes the currently visible portion of the map to a region that best fits the provided annotations array, and it optionally animates the change.
    All elements from the array must conform to the <MKAnnotation> protocol in order to fetch the coordinates to compute the visible region of the map.
 *
 *  @param annotations an array of elements conforming to the <MKAnnotation> protocol, holding the locations for which the visible portion of the map will be set.
 *  @param animated    wether or not the change should be perfomed with an animation.
 */
-(void)ij_setVisibleRectToFitAnnotations:(NSArray *)annotations animated:(BOOL)animated
{
    MKMapView * mapView = self;

    MKMapRect r = MKMapRectNull;
    for (id<MKAnnotation> a in annotations) {
        ZAssert([a conformsToProtocol:@protocol(MKAnnotation)], @"ERROR: All elements of the array MUST conform to the MKAnnotation protocol. Element (%@) did not fulfill this requirement", a);
        MKMapPoint p = MKMapPointForCoordinate(a.coordinate);
        //MKMapRectUnion performs the union between 2 rects, returning a bigger rect containing both (or just one if the other is null). here we do it for rects without a size (points)
        r = MKMapRectUnion(r, MKMapRectMake(p.x, p.y, 0, 0));
    }

    [mapView setVisibleMapRect:r animated:animated];

}

@end

보시다시피 지금까지 두 가지 방법을 추가했습니다. 하나는 맵의 가시 영역을 MKMapView 인스턴스에 현재로드 된 모든 주석에 맞는 것으로 설정하는 방법이고 다른 하나는 객체 배열에 설정하는 방법입니다. 따라서 mapView의 가시 영역을 설정하는 코드는 다음과 같이 간단합니다.

   //the mapView instance  
    [self.mapView ij_setVisibleRectToFitAllLoadedAnnotationsAnimated:animated]; 

나는 그것이 도움이되기를 바랍니다 =)


0

이 확장을 고려하십시오.

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

신속한 5 버전 :

   func regionFor(coordinates coords: [CLLocationCoordinate2D]) -> MKCoordinateRegion {
        var r = MKMapRect.null

        for i in 0 ..< coords.count {
            let p = MKMapPoint(coords[i])

            r = r.union(MKMapRect(x: p.x, y: p.y, width: 0, height: 0))
        }

        return MKCoordinateRegion(r)
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.