缩放和区域

我很熟悉使用 Google Maps Javascript API。最近我开始在一个 iphone 项目中使用 MapKit 框架,但是我很难在地图上找到缩放和设置区域的方法。

在 Google Maps API 中,我使用了8、9、10这样的整数缩放级别,以及简单的 setZoom ()函数。在 MapKit 框架中,我看到的唯一等价的方法是 setArea: Animated。据我所知,我需要设置一个区域的 span 的经纬度“ delta”值来指定缩放级别。但是我真的不知道这些值代表什么(我阅读了文档)。

当我使用 MKMapView 委托并跟踪 regionDidChange 委托方法中的 span 值时,结果似乎并不相关。当我缩小并看到 span delta 值正在按照文档中的指定增加时,这样做是可以的。但是突然我拖动地图而不放大,delta 值变成了0.0。

有人能解释一下这些跨度和三角洲的参考点是什么吗?或者有没有什么算法可以将整数缩放级别(比如9)转换成这些增量值?

作为一个额外的问题,是否有任何方法可以指定 MKMapView 上的最小-最大缩放级别:)

谢谢

80727 次浏览

The span is in degrees of latitude and longitude. There is a method for constructing MKCoordinateRegion structs that takes distance, instead. It may be that you are using MKCoordinateRegionMakeWithDistance to specify the span, and then when you check it in regionDidChange, you're seeing at the lat/long span, which is how it is stored in an MKCoordinateRegion struct.

As far as I know, the integer zoom levels are not available or useful at all when working with MKMapKit. I personally prefer using the span figures, its more flexible.

You cannot specify max and min zoom, and I don't know of a way to hack it in. MKMapKit is actually pretty weak right now, I'm pretty disappointed by the lack of features.

First of all, MKMapView does not use/have a predefined set of zoom levels like Google Maps does.

Instead, the visible area of a MKMapView is described using MKCoordinateRegion, which consists of two values:

  1. center (the center point of the region), and
  2. span (the size of the visible area around center).

The center point should be obvious (it's the center point of the region.)

However, span (which is a MKCoordinateSpan) consists of:

  1. latitudeDelta (the vertical distance represented by the region), and
  2. longitudeDelta (the horizontal distance represented by the region).

A brief example. Here's a toy MKCoordinateRegion:

  1. center:
    • latitude: 0
    • longitude: 0
  2. span:
    • latitudeDelta: 8
    • longitudeDelta: 6

The region could be described using its min and max coordinates as follows:

  1. min coordinate (lower left-hand point):
    • latitude: -4
    • longitude: -3
  2. max coordinate (upper right-hand point):
    • latitude: 4
    • longitude: 3

So, you can specify zoom levels around a center point by using an appropriately sized MKCoordinateSpan. As an approximation of Google's numeric zoom levels, you could reverse engineer the span sizes that Google uses for a given zoom level and create a span, accordingly. (Google describes their view regions in the same way that MKMapView does, as a center + span, so you can pull these values out of Google Maps.)

As for restricting the region, you may play w/ this delegate method:

mapView:regionWillChangeAnimated

e.g. by resizing the region back into your allowed zoom levels. (Kind of like how table views will let you scroll past the edge, but will then rubber band back into place.) However, your mileage may vary, since I haven't used it for this purpose.

btw, there are definite fixes/improvements in OS 3.1 to aspects of MapKit that were giving me trouble in 3.0.

A quick comparison of zoom levels for a location using maps.google.com by inspecting the link querystring shows that the dx and dy span values increase by a factor of 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
...

If you prefer using explicit zoom levels instead of defining an MKCoordinateSpan, I wrote a category that adds support for specifying the zoom level of an MKMapView. The code can be found here.

Brant's category on MKMapView works well. However, it appears that it has not been updated to support newer devices with retina screens when calculating mapSizeInPixels.

It can be fixed by replacing this line:

CGSize mapSizeInPixels = mapView.bounds.size;

With this line:

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