1

起始情况

iOS6,苹果地图。我在 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 个不同的位置定义为 iVar,并设置了地图视图:

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

之后,我确定将确定包含我的 2 个注释的矩形的西南和东北点。

// 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。

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

4

1 回答 1

-1

阅读以下文档setRegion

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

如果你想要一个精确的缩放,你必须自己弄清楚数学。

于 2013-05-06T18:00:11.020 回答