代码之家  ›  专栏  ›  技术社区  ›  runmad

将mkmapview区域设置为在两个注释上居中

  •  1
  • runmad  · 技术社区  · 16 年前

    我正在寻找一些帮助来完成一些关于基于当前位置注释和我设置的注释在mkmapview上设置区域的代码。

    我要计算两者之间的距离,并设置两者之间的中心,然后缩小,使两者都在视图中。对于我来说,它在模拟器中似乎可以正常工作,但不幸的是,userlocation.coordinate被固定在了苹果总部。当我在一个设备上测试时,我看到了奇怪的行为。如果两个注释在同一纬度上有点水平,它通常会缩小并设置一个适当的区域,但是如果垂直距离较大,则不会正确缩小。

    我用找到的代码 here 并根据我的需要进行了一些编辑:

    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 回复  |  直到 7 年前
        1
  •  -1
  •   Aaron Saunders    10 年前

    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];
    }
    
        2
  •  2
  •   Robertibiris    12 年前

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

    #import <MapKit/MapKit.h>
    
    @interface MKMapView (Extensions)
    
    -(void)ij_setVisibleRectToFitAllLoadedAnnotationsAnimated:(BOOL)animated;
    -(void)ij_setVisibleRectToFitAnnotations:(NSArray *)annotations animated:(BOOL)animated;
    
    
    @end
    

    #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
    

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

        3
  •  0
  •   jv42    16 年前

    region.span.longitudeDelta = 0.0;
    
        4
  •  0
  •   rockdaswift    7 年前

    Robertibiris

    mapView.showAnnotations(mapView.annotations, animated: true)
    
    推荐文章