常用功能
- 定位
- 地图展示/标注
- (逆向)地理位置查询
- 路线查询
定位
我们可以通过CLLocationManager和MKMapview定位.在定位之前,我们可以先做一些判断:
是否开启定位:
[CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied;
以及请求定位(ios8+):
[manager requestWhenInUseAuthorization];
在ios8中,需要在plist里面加入一个key为:NSLocationWhenInUseUsageDescription的property.在xcode里面,直接输入没有补全提示,不用担心,直接写写入即可.当然value则是需要提示的用户的字符.
地图展示
目前常用的地图有mkmapview,百度地图,高德地图,以及google地图.这里聊聊我的理解.
- mkmapview:我目前项目使用这个地图,因为项目并没有重度的地图需求,原生地图能完全满足我的需求.所以我不需要为了第三方地图,被迫做一些额外的事情包括:下载sdk,配置项目,注册key,查询相关文档等.
- 第三方地图:各自有着各自更丰富的功能.以高德地图为例:可以再这里查看高德地图的全部功能
我们到底怎么选择呢?
在原生地图和第三方地图的选择中,如果原生地图能够满足需求,我倾向于原生,毕竟第三方地图的sdk也并不小.
如果需要使用第三方地图,那么我强烈建议高德地图(AMap) - 是苹果在国内的数据提供者,坐标系相同.否则存在一个坐标系转换的问题.
- google map无法使用,百度地图坐标系不相同.
- 高德地图的官网/文档/支持比百度都要好,想想可以理解,一个专业的公司vs一个大公司的某个部门.
- 百度地图配置需要c++环境,也就是需要修改编译器设置或者在工程中任意加入一个mm文件,在设置为objectivec++.这么做本身没什么大问题.但是!如果在oc和swift混编的情况下,则会出现编译不通过的问题.解决方案是在子工程引入mm文件.
关于坐标系,有两个非官方转换的方式:
+(CLLocationCoordinate2D )convertBMapToAMap:(double)bMapLat lon:(double) bMapLon{
double x = bMapLon - 0.0065, y = bMapLat - 0.006;
double z = sqrt(x * x + y * y) - 0.00002 * sin(y * x_pi);
double theta = atan2(y, x) - 0.000003 * cos(x * x_pi);
return CLLocationCoordinate2DMake(z * sin(theta), z * cos(theta));
}
+(CLLocationCoordinate2D )convertAMapToBMap:(double)aMapLat lon:(double) aMapLon{
double x = aMapLon, y = aMapLat;
double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);
double theta = atan2(y, x) + 0.000003 * cos(x * x_pi);
return CLLocationCoordinate2DMake(z * sin(theta) + 0.006, z * cos(theta) + 0.0065);
}
标注
标注和tableview其实几乎一样.同样的对map设置数据源(add annotation),然后通过代理使用数据源对相关的view进行设置,最终return并渲染.
返回的是一个MKAnnotationView的东西,第三方地图的话会各自进行封装,不过肯定是个view.所以既然是个view,很多东西我们可以自行实现,并不一定要通过map的相关方法.
比如自定义的calloutview等,完全可以自行控制.
在某一个区域,如果annotation特别多的话,可能会出现卡顿的情况.这个时候我们可以做一个实时加载annotation的方案.
大致思路为:我们获取到当前地图的中心点,通过中心点获取到坐标,在同样的道理,获取地图(0,0)点坐标.通过2个点坐标,这样就能计算到半径.然后根据annotation的数据源进行计算,和当前中心点的距离小于半径的,才进行显示.
而每当中心点变动的时候(regionDidChangeAnimated),我们需要重新计算当前annotation数据源和map上已经添加的数据源,进行比对,2种数据源的并集不做任何处理,而差集进行相应的删除或添加.
(逆向)地理位置
地理位置并没有特别需要注意的地方.只是在原生地图中,碰上过一个小坑.
CLPlacemark这个东西,里面很多属性,大体上来说就是国家,省,城市等等之类的东西,很容易明白.
不过如果要获取城市的话,可能需要判断一下locality和administrativeArea.这两个东西,一个是地址,一个是行政区域.在中国来讲一个就是城市,一个就是省.但是...直辖市通过locality是获取不到的,只能够通过administrativeArea来获取,所以注意一下就好了.
路线查询
在原生地图中,是使用一个叫做MKMapItem的东西进行规划查询.如果有复杂的显示/查询功能,还是使用第三方地图比较合适.