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 缩放到 MKAnnotationView 的框架