iOS Map学习
学习目的
地图是手机上很重要的一个功能,很多和位置相关的应用都需要用到手机上的地图显示功能,因此我们来了解一下iOS上地图的使用和深入学习地图的特性。
具体内容
这部分先来学习iOS上地图的显示(MKMapView)、在地图上标记点(Annotation)和在地图上添加覆盖层(Overlay)。
MKMapView
iOS上的地图使用的是MKMapView,继承自UIView。 可以显示三种类型的地图:街道图、卫星图和混合图。
MKMapViewDelegate是MKMapView的代理,处理MKMapView的回调。
Map Regions是指地图的显示区域,由一个中心点和区域范围决定。 其中中心点的类型为:
typedef struct {
CLLocationDegrees latitude;
CLLocationDegrees longitude;
} CLLLocationCoordinate2D; 区域范围的类型为:
typedef struct {
CLLocationDegrees latitudeDelta;
CLLocationDegrees longitudeDelta;
} MKCoordinateSpan; 由这两个组成的地图区域类型为:
typedef struct {
CLLocationCoordinate2D center;
MKCoordinateSpan span;
} MKCoordinateRegion;
设置地图的区域有两种方式,如果需要改变缩放级别的话,可以设置map region,如果只是移动位置,不改变缩放级别的话,可以只设置centerCoordinate这个地图中心属性。
地图区域(Map Region)有个容易出错的陷阱:因为iOS上的Google Map使用的是墨卡托投影(Mercator Projection,又名等角正轴原著投影)把三维球形的地球变成二维平面的地图,而墨卡托投影的方式是指假设用一个相切的圆柱包围地球,然后从地球的球心向圆柱的面上投影,把地球表面上的图形投影到圆柱体上,再把圆柱体展开成一个二维的平面,就是一幅“墨卡托投影”绘制出的世界地图,如图-1所示:
图-1 墨卡托投影示意图
但是由图也可以看出墨卡托投影有个缺点,就是投影会产生面积的变形,越靠近两极地区,变形越大,并且到纬度接近两极时,投影会到无穷远。因此实际使用过程中会选择长和宽相等的正方形区域,宽就是地球赤道的周长,为2*PI*6378137 = 2 * 20037508.3427892,即转换成X x Y坐标表示的范围为[-20037508.3427892,20037508.3427892] * [-20037508.3427892,20037508.3427892]。
而把长20037508.3427892转换为投影的角度为纬度85.05112877980659,因此X x Y坐标的角度取值为(-180,180) x (-85.05112877980659,85.05112877980659)。图-2为北纬82度和南纬82度之间墨卡托投影产生的地图:
图-2 北纬82度和南纬82度之间墨卡托投影产生的地图
所以地图区域的容易出错的陷阱就是相同的一个MKCoordinateSpan,越往两极,在地图上覆盖的面积范围就会越大。
所以另一种方式是可以按界面上实际指定的区域来显示地图,叫做Map Rects,由一个左上角的起点和长宽范围决定,其中左上角起点的类型为:
typedef struct {
double x;
double y;
} MKMapPoint;
长宽范围的类型为:
double struct {
double width;
double height;
} MKMapSize;
由这两个类型组成的另一个地图范围类型为:
typedef struct {
MKMapPoint origin;
MKMapSize size;
} MKMapRect;
MKMapSize的显示范围指定了后就是固定的,不随地图移动后经纬度的变化而变化。
同时iOS提供了MKMapPointForCoordinate
,MKCoordinateForMapPoint
和MKCoordinateRegionForMapRect
来对以上两种范围的显示进行转换。
Annotation
在地图上添加的标记叫做Annotation。一个Annotation是标准的MVC模式实现,由两部分组成:一个表示Model的
在地图上添加一个Annotation需要MKMapViewDelegate的配合,具体的过程为:
1.首先产生了个Annotation的Model,添加到地图上
2.然后MKMapView会通知MKMapViewDelegate需要这个Annotation的View,具体的回调方法为:mapView:viewForAnnotation:
3.在这个回调方法中提供MKAnnotationView
4.然后会在MKMapView上放置Annotation
5.放置后回调MKMapViewDelegate的mapView:didAddAnnotationViews:
方法
6.在这个方法里可以有选择的实现一些Annotation添加的动画效果
----------------------
blog comments powered by Disqus