2010-10-29 77 views
0

我正在寻找一些帮助完成基于当前位置注释和我设置的注释在MKMapView上设置区域的一些代码。将MKMapView区域设置为以两个注释为中心

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

我用代码中发现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 ......

在此先感谢谁谁得到了一些帮助,输入:)

回答

-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]; 
} 
+0

完美!德尔塔是我能看到的问题。非常感谢! – runmad 2010-10-29 14:47:34

+1

不幸的是,这个页面似乎没有回应。有没有人有页面的缓存版本?谢谢! – jowie 2011-08-21 22:17:34

+0

@jowie我能够使用回机器找到页面的缓存版本。我希望这有帮助。 http://web.archive.org/web/20100612181520/http://codisllc。com/blog/zoom-mkmapview-to-fit-annotations – avelis 2013-04-04 21:00:52

0

不要被两个第一线感到害怕,你可以忽略什么是权=迹象,因为这将在下面覆盖...

我认为这个问题是在这里:

region.span.longitudeDelta = 0.0; 
+0

是的,上面的Aaron的链接有正确计算的增量,它似乎解决了它。只需要调整额外的余量,但代码是完美的! – runmad 2010-10-29 14:47:19

1

对于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]; 

对于我的个人项目(之前IO S7)我只是在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种方法至今:一个用于设置的可见区域映射到适合MKMapView实例上所有当前加载的批注的映射,以及将其设置为任何对象数组的另一种方法。 所以设置的MapView的可视区域,则代码将简单:

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

我希望它有助于=)