MKMapView 缩放和区域

Posted

技术标签:

【中文标题】MKMapView 缩放和区域【英文标题】:MKMapView Zoom and Region 【发布时间】:2010-11-13 01:54:32 【问题描述】:

我熟悉使用 Google Maps javascript API。最近我开始为一个 iphone 项目使用 MapKit 框架,但我很难弄清楚在地图上缩放和设置区域。

在 Google Maps API 中,我曾经使用整数缩放级别(例如 8、9、10)以及简单的函数 setZoom()。我可以在 MapKit 框架中看到的唯一等效方法是 setRegion:animated。据我了解,我需要设置区域跨度的纬度和经度“增量”值来指定缩放级别。但我真的不知道这些值代表什么(我阅读了文档)。

当我使用 MKMapView 委托并跟踪 regionDidChange 委托方法中的跨度值时,结果似乎彼此不相关。当我缩小并看到跨度增量值按照文档中的指定增加时,这没关系。但是突然我拖动地图而不进行缩放,增量值变为 0.0。

有人可以解释一下这些跨度和增量的参考点是什么吗?或者是否有任何算法可以将整数缩放级别(如 9)转换为这些增量值?

作为一个额外的问题,有没有办法在 MKMapView 上指定最小-最大缩放级别:)

谢谢

【问题讨论】:

【参考方案1】:

首先,MKMapView 不像 Google 地图那样使用/拥有一组预定义的缩放级别。

相反,MKMapView 的可见区域是使用 MKCoordinateRegion 描述的,它由两个值组成:

    center(区域的中心点),以及 span(中心周围可见区域的大小)。

中心点应该很明显(它是区域的中心点。)

然而,span(这是一个MKCoordinateSpan)包括:

    latitudeDelta(区域所代表的垂直距离),以及 longitudeDelta(区域表示的水平距离)。

一个简单的例子。这是一个玩具 MKCoordinateRegion:

    中心: 纬度:0 经度:0 跨度: latitudeDelta: 8 longitudeDelta:6

该区域可以使用它的最小和最大坐标来描述如下:

    最小坐标(左下点): 纬度:-4 经度:-3 最大坐标(右上角): 纬度:4 经度:3

因此,您可以使用适当大小的 MKCoordinateSpan 指定围绕中心点的缩放级别。作为 Google 数字缩放级别的近似值,您可以对 Google 用于给定缩放级别的跨度大小进行逆向工程,并相应地创建一个跨度。 (Google 以与 MKMapView 相同的方式描述他们的视图区域,作为中心 + 跨度,因此您可以将这些值从 Google 地图中提取出来。)

至于限制区域,你可以用这个委托方法玩:

mapView:regionWillChangeAnimated

例如通过将区域大小重新调整为允许的缩放级别。 (有点像表格视图如何让您滚动到边缘,但随后将橡皮筋带回原位。)但是,您的里程可能会有所不同,因为我没有将它用于此目的。

顺便说一句,OS 3.1 中对 MapKit 的某些方面进行了明确的修复/改进,这些方面在 3.0 中给我带来了麻烦。

【讨论】:

@Kelvin,您能否更详细地描述如何“对 Google 用于给定缩放级别的跨度大小进行逆向工程并创建跨度”。我真的需要它【参考方案2】:

如果您更喜欢使用显式缩放级别而不是定义 MKCoordinateSpan,我编写了一个类别,增加了对指定 MKMapView 缩放级别的支持。代码可以在here找到。

【讨论】:

Troy 的博客文章让我对 mapkit 和 google 地图的工作原理有了很好的了解。我强烈推荐阅读它。 git://github.com/jdp-global/MKMapViewZoom.git【参考方案3】:

跨度以纬度和经度为单位。有一种构造 MKCoordinateRegion 结构的方法,它取而代之的是距离。可能是您使用 MKCoordinateRegionMakeWithDistance 来指定跨度,然后当您在 regionDidChange 中检查它时,您会看到纬度/经度跨度,这就是它在 MKCoordinateRegion 结构中的存储方式。

据我所知,整数缩放级别在使用 MKMapKit 时根本不可用或根本没有用。我个人更喜欢使用跨度数字,它更灵活。

你不能指定最大和最小缩放,我不知道有什么方法可以破解它。MKMapKit 现在实际上很弱,我对缺乏功能感到非常失望。

【讨论】:

【参考方案4】:

使用 maps.google.com 通过检查链接查询字符串快速比较某个位置的缩放级别显示 dx 和 dy 跨度值增加了 2 倍:

 (0.005334, 0.011834) starting span
 (0.010668, 0.023668) dx: x2, dy: x2 
 (0.021335, 0.047337) dx: x2, dy: x2
 (0.042671, 0.094671) dx: x2, dy: x2
  ...

【讨论】:

【参考方案5】:

Brant 在 MKMapView 上的类别效果很好。但是,在计算 mapSizeInPixels 时,它似乎尚未更新以支持具有视网膜屏幕的较新设备。

可以通过替换这一行来修复:

CGSize mapSizeInPixels = mapView.bounds.size;

用这一行:

CGSize mapSizeInPixels = CGSizeMake(mapView.bounds.size.width * [UIScreen mainScreen].scale, mapView.bounds.size.height * [UIScreen mainScreen].scale);

【讨论】:

以上是关于MKMapView 缩放和区域的主要内容,如果未能解决你的问题,请参考以下文章

如果在添加注释时缩放,MKMapView 会崩溃

将 MKMapView 缩放到 MKAnnotationView 的框架

MKMapView 和注释隐藏与缩放

从另一个类缩放 MkMapView

防止 MKMapView 不断地重新缩放和重新居中到用户位置

防止覆盖在缩放时消失 - MKMapView & MKOverlay