1

現在の場所の注釈と設定した注釈に基づいて、MKMapViewで領域を設定するためのコードを完成させるためのヘルプを探しています。

2つの間の距離を計算し、2つの間の中心を設定してから、両方が表示されるようにズームアウトします。私にとってはSimulatorで正常に動作しているように見えますが、残念ながらuserLocation.coordinateはAppleHQに固定されています。デバイスでテストすると、奇妙な動作が見られます。多くの場合、2つの注釈が同じ緯度で水平方向にいくらかある場合はズームアウトして適切な領域を設定しますが、垂直方向の距離が大きい場合は適切にズームアウトしません。

ここにあるコードを使用し、ニーズに合わせて少し編集しました。

CLLocationCoordinate2D southWest = mapView.userLocation.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 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 = 0.0;

MKCoordinateRegion savedRegion = [mapView regionThatFits:region];
[mapView setRegion:savedRegion animated:YES];

[locSouthWest release];
[locNorthEast release];

私を混乱させた一つのことは彼が言うことnorthEast = southWestです...

助けと入力を持っている人に事前に感謝します:)

4

4 に答える 4

2

iOS7フォワードの場合、これを行うための最良の方法は次のとおりです。

//from API docs: 
//- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated NS_AVAILABLE(10_9, 7_0);
[self.mapView showAnnotations:self.mapView.annotations animated:YES];

私の個人的なプロジェクト(iOS7より前)では、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

ご覧のとおり、これまでに2つのメソッドを追加しました。1つはマップの表示領域をMKMapViewインスタンスに現在読み込まれているすべてのアノテーションに適合するものに設定する方法、もう1つはオブジェクトの任意の配列に設定する方法です。したがって、mapViewの表示領域を設定するには、コードは次のように単純になります。

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

お役に立てば幸いです=)

于 2014-06-10T13:32:18.867 に答える
0

最初の2行に怖がらないでください。以下で上書きされるため、=記号の正しい内容は無視してかまいません...

問題はここにあると思います:

region.span.longitudeDelta = 0.0;
于 2010-10-29T14:38:27.297 に答える
0

RobertibirisのSwift4バージョンの回答:

mapView.showAnnotations(mapView.annotations, animated: true)
于 2019-04-04T15:28:05.730 に答える
-1

このブログ投稿は、必要な洞察を提供する可能性があります

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

-(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];
}
于 2010-10-29T14:37:12.450 に答える