常用功能
- 定位
- 地圖展示/標(biāo)注
- (逆向)地理位置查詢
- 路線查詢
定位
我們可以通過CLLocationManager和MKMapview定位.在定位之前,我們可以先做一些判斷:
是否開啟定位:
[CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied;
以及請求定位(ios8+):
[manager requestWhenInUseAuthorization];
在ios8中,需要在plist里面加入一個key為:NSLocationWhenInUseUsageDescription的property.在xcode里面,直接輸入沒有補(bǔ)全提示,不用擔(dān)心,直接寫寫入即可.當(dāng)然value則是需要提示的用戶的字符.
地圖展示
目前常用的地圖有mkmapview,百度地圖,高德地圖,以及google地圖.這里聊聊我的理解.
- mkmapview:我目前項(xiàng)目使用這個地圖,因?yàn)轫?xiàng)目并沒有重度的地圖需求,原生地圖能完全滿足我的需求.所以我不需要為了第三方地圖,被迫做一些額外的事情包括:下載sdk,配置項(xiàng)目,注冊key,查詢相關(guān)文檔等.
- 第三方地圖:各自有著各自更豐富的功能.以高德地圖為例:可以再這里查看高德地圖的全部功能
我們到底怎么選擇呢?
在原生地圖和第三方地圖的選擇中,如果原生地圖能夠滿足需求,我傾向于原生,畢竟第三方地圖的sdk也并不小.
如果需要使用第三方地圖,那么我強(qiáng)烈建議高德地圖(AMap) - 是蘋果在國內(nèi)的數(shù)據(jù)提供者,坐標(biāo)系相同.否則存在一個坐標(biāo)系轉(zhuǎn)換的問題.
- google map無法使用,百度地圖坐標(biāo)系不相同.
- 高德地圖的官網(wǎng)/文檔/支持比百度都要好,想想可以理解,一個專業(yè)的公司vs一個大公司的某個部門.
- 百度地圖配置需要c++環(huán)境,也就是需要修改編譯器設(shè)置或者在工程中任意加入一個mm文件,在設(shè)置為objectivec++.這么做本身沒什么大問題.但是!如果在oc和swift混編的情況下,則會出現(xiàn)編譯不通過的問題.解決方案是在子工程引入mm文件.
關(guān)于坐標(biāo)系,有兩個非官方轉(zhuǎn)換的方式:
+(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);
}
標(biāo)注
標(biāo)注和tableview其實(shí)幾乎一樣.同樣的對map設(shè)置數(shù)據(jù)源(add annotation),然后通過代理使用數(shù)據(jù)源對相關(guān)的view進(jìn)行設(shè)置,最終return并渲染.
返回的是一個MKAnnotationView的東西,第三方地圖的話會各自進(jìn)行封裝,不過肯定是個view.所以既然是個view,很多東西我們可以自行實(shí)現(xiàn),并不一定要通過map的相關(guān)方法.
比如自定義的calloutview等,完全可以自行控制.
在某一個區(qū)域,如果annotation特別多的話,可能會出現(xiàn)卡頓的情況.這個時候我們可以做一個實(shí)時加載annotation的方案.
大致思路為:我們獲取到當(dāng)前地圖的中心點(diǎn),通過中心點(diǎn)獲取到坐標(biāo),在同樣的道理,獲取地圖(0,0)點(diǎn)坐標(biāo).通過2個點(diǎn)坐標(biāo),這樣就能計算到半徑.然后根據(jù)annotation的數(shù)據(jù)源進(jìn)行計算,和當(dāng)前中心點(diǎn)的距離小于半徑的,才進(jìn)行顯示.
而每當(dāng)中心點(diǎn)變動的時候(regionDidChangeAnimated),我們需要重新計算當(dāng)前annotation數(shù)據(jù)源和map上已經(jīng)添加的數(shù)據(jù)源,進(jìn)行比對,2種數(shù)據(jù)源的并集不做任何處理,而差集進(jìn)行相應(yīng)的刪除或添加.
(逆向)地理位置
地理位置并沒有特別需要注意的地方.只是在原生地圖中,碰上過一個小坑.
CLPlacemark這個東西,里面很多屬性,大體上來說就是國家,省,城市等等之類的東西,很容易明白.
不過如果要獲取城市的話,可能需要判斷一下locality和administrativeArea.這兩個東西,一個是地址,一個是行政區(qū)域.在中國來講一個就是城市,一個就是省.但是...直轄市通過locality是獲取不到的,只能夠通過administrativeArea來獲取,所以注意一下就好了.
路線查詢
在原生地圖中,是使用一個叫做MKMapItem的東西進(jìn)行規(guī)劃查詢.如果有復(fù)雜的顯示/查詢功能,還是使用第三方地圖比較合適.