MKMapView setRegion不精确

时间:2013-05-06 12:46:09

标签: ios6 zoom mapkit

起始情况

iOS6,Apple Maps。我在MKMapView上有两个注释。两个注释的坐标具有纬度组件的相同值,但不同的经度

我想要什么

我现在想要缩放地图,以便一个注释完全位于mapView框架的左边缘,另一个注释位于框架的右边缘。为此我尝试了MKMapView的setRegion和setVisibleMapRect方法。

问题

问题是这些方法似乎捕捉到某些缩放级别,因此没有按照我的需要设置区域。我在Stack Overflow上看到很多问题,指出这种行为在iOS5及以下版本中是正常的。但由于Apple Maps正在使用矢量图形,因此视图不受某些缩放级别的约束,无法以适当的分辨率显示图像。

经过测试......

我在iPhone 4,4S,5,iPad 3和iPad Mini(均使用iOS6.1)以及iOS6.1上的模拟器中进行了测试。

我的问题

那么为什么setRegion和setVisibleMapRect捕捉到某些缩放级别并且不会将精确区域调整为我传递的值?

示例代码

在视图中确实出现了我将4个不同的位置定义为iVars,并设置了地图视图:

// define coords
_coord1 = CLLocationCoordinate2DMake(46.0, 13.0);
_coord2 = CLLocationCoordinate2DMake(46.0, 13.1);
_coord3 = CLLocationCoordinate2DMake(46.0, 13.2);
_coord4 = CLLocationCoordinate2DMake(46.0, 13.3);

// define frame for map in landscape mode
CGRect mainScreen = [[UIScreen mainScreen] bounds];
CGRect newSRect =  mainScreen;
newSRect.size.width = mainScreen.size.height;
newSRect.size.height = mainScreen.size.width;

// setup map view
customMapView = [[MKMapView alloc] initWithFrame:newSRect];
[customMapView setDelegate:self];
[customMapView setShowsUserLocation:NO];
[self.view addSubview:customMapView];

然后我添加3个按钮。那些触发所有相同的方法addAnnotationsWithCoord1:coord2。第一个按钮传递_coord1和_coord2,第二个按钮传递_coord1和_coord3,第三个按钮传递_coord1和_coord4。方法看起来像这样(TapAnnotation是我的MKAnnotation的子类):

-(void)addAnnotationsWithCoord1:(CLLocationCoordinate2D)coord1 coord2:(CLLocationCoordinate2D)coord2{
    // Make 2 new annotations with the passed coordinates
    TapAnnotation *annot1 = [[TapAnnotation alloc] initWithNumber:0 coordinate:coord1];
    TapAnnotation *annot2 = [[TapAnnotation alloc] initWithNumber:0 coordinate:coord2];

    // Remove all existing annotations 
    for(id<MKAnnotation> annotation in customMapView.annotations){
        [customMapView removeAnnotation:annotation];
    }

    // Add annotations to map
    [customMapView addAnnotation:annot1];
    [customMapView addAnnotation:annot2];
}

之后我确定了SouthWest和NorthEast点,它们将确定包含我的2个注释的rect。

// get northEast and southWest
CLLocationCoordinate2D northEast;
CLLocationCoordinate2D southWest;
northEast.latitude = MAX(coord1.latitude, coord2.latitude);
northEast.longitude = MAX(coord1.longitude, coord2.longitude);
southWest.latitude = MIN(coord1.latitude, coord2.latitude);
southWest.longitude = MIN(coord1.longitude, coord2.longitude);

然后我计算两个坐标之间的中心点,并将地图的中心坐标设置为它(记住,因为所有坐标具有相同的纬度,所以下面的计算应该是正确的):

// determine center coordinate and set to map
double centerLon = ((coord1.longitude + coord2.longitude) / 2.0f);
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(southWest.latitude, centerLon);
[customMapView setCenterCoordinate:center animated:NO];

现在我尝试设置地图的区域,使其符合我的要求:

CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:southWest.latitude longitude:southWest.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:northEast.latitude longitude:northEast.longitude];
CLLocationDistance meterSpanLong = [loc1 distanceFromLocation:loc2];
CLLocationDistance meterSpanLat = 0.1;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(center, meterSpanLat, meterSpanLong);
[customMapView setRegion:region animated:NO];

这不符合预期,所以我试试这个:

MKCoordinateSpan span = MKCoordinateSpanMake(0.01, northEast.longitude-southWest.longitude);
MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
[customMapView setRegion:region animated:NO];

这仍然没有按预期运行,所以我尝试使用setVisibleMapRect:

MKMapPoint westPoint = MKMapPointForCoordinate(southWest);
MKMapPoint eastPoint = MKMapPointForCoordinate(northEast);
MKMapRect mapRect = MKMapRectMake(westPoint.x, westPoint.y,eastPoint.x-westPoint.x,1);
[customMapView setVisibleMapRect:mapRect animated:NO];

然而,它并不像我想要的那样。作为验证,我计算从左注释到mapView框架左边缘的点距离:

// log the distance from the soutwest point to the left edge of the mapFrame
CGPoint tappedWestPoint = [customMapView convertCoordinate:southWest toPointToView:customMapView];
NSLog(@"distance: %f", tappedWestPoint.x);
  • 对于_coord1和_coord2,它显示:138
  • 对于_coord1和_coord3,它显示:138
  • 对于_coord1和_coord4,它显示:65

那么为什么我会得到这些价值呢? 如果有任何工作正常,那么这些都应为0。

感谢您的帮助,现在为这个问题苦苦挣扎了一周。

1 个答案:

答案 0 :(得分:-1)

阅读setRegion上的文档:

  

设置此属性时,地图可能会调整新的区域值,以使其精确地适合地图的可见区域。这是正常的,可以确保此属性中的值始终反映地图的可见部分。但是,它确实意味着如果在设置后立即获得此属性的值,则返回的值可能与您设置的值不匹配。 (您可以使用regionThatFits:方法来确定地图实际设置的区域。)

如果你想要精确的变焦,你必须自己弄清楚数学。