iOS百度地图的使用
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
????項目最近對地圖整體模塊進行了重構(gòu), 為了和我們的安卓同學保持統(tǒng)一,放棄了原本就很6的高德地圖,全部改用百度地圖(雖然我覺得百度地圖不好用,文檔也一般,但是沒辦法啊,沒辦法啊 啊啊啊啊啊..).
項目中用到的百度地圖的主要功能點有以下幾個:
?在實際的使用過程中這些功能可能會有交叉,所以代碼會整個貼過來,下面就根據(jù)實際功能需求一一介紹.
一.基礎(chǔ)地圖和定位功能
地圖的初始化:
- (void)initMapView {self.mapView = [[BMKMapView alloc] initWithFrame:CGRectMake(0, 44, SCREEN_WIDTH, SCREEN_WIDTH/372*253)];self.mapView.showsUserLocation = YES;self.mapView.userTrackingMode = BMKUserTrackingModeNone;self.mapView.gesturesEnabled = YES;self.mapView.zoomEnabled = YES;self.mapView.maxZoomLevel = 23;self.mapView.zoomLevel = 16;// 顯示比例尺 200m (和微信一樣....)self.mapView.showMapScaleBar = YES;// 回到當前位置按鈕UIButton *showUserLocation = [[UIButton alloc] initWithFrame:CGRectMake(self.mapView.mj_width - 21 - 50, self.mapView.mj_height - 21 - 50, 50, 50)];[self.mapView addSubview:showUserLocation];[showUserLocation addTarget:self action:@selector(backToCurrentLocation) forControlEvents:UIControlEventTouchUpInside];[showUserLocation setBackgroundImage:[UIImage imageNamed:@"showuserlocation"] forState:UIControlStateNormal];UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.mapView.mj_width * 0.5 - 8, self.mapView.mj_height * 0.5 - 40, 16, 40)];imageView.image = [UIImage imageNamed:@"datouzhen"];imageView.contentMode = UIViewContentModeScaleAspectFit;[self.mapView addSubview:imageView];[self.view addSubview:self.mapView]; }這里提醒一點百度地圖各項服務(wù)的delegate需要在 viewWillApper設(shè)置為self,viewWillDisapper時設(shè)置為nil,否則的話會出現(xiàn)內(nèi)存泄露.
以下是定位成功后的回調(diào)方法
/***用戶位置更新后,會調(diào)用此函數(shù)*@param userLocation 新的用戶位置*/ - (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation {[self.mapView updateLocationData:userLocation];CLLocation *location = userLocation.location;// 如果不是區(qū)域檢索if (!(self.city.length > 0)) {// 設(shè)置當前位置為地圖的中心點NSLog(@"%f-----%f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude) animated:YES];}self.currentCoor = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude);// 定位成功會后if (location) {[self.locationService stopUserLocationService];// 反向編碼[self beginReverseGeoCodeSearch];} }這里進行了判斷,如果不是區(qū)域檢索(如果我人在北京,但是要讓地圖顯示是石家莊市 此時需要用到區(qū)域檢索),則將當前定位到的位置設(shè)置為地圖的中心點 . 然后開始進行反地理編碼.
二.反地理編碼
因為在發(fā)布分享的時候有一個選項顯示的是當前所在的城市,如下圖一,二 ?. 第二個cell顯示的 "北京市"?所以需要進行反地理編碼.
反地理編碼成功后的回調(diào):
// 反地理編碼回調(diào) - (void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error {// result ->poiList ///地址周邊POI信息,成員類型為BMKPoiInfo // @property (nonatomic, strong) NSArray* poiList;if (result.poiList.count > 0) {self.currentPoiInfo = [result.poiList firstObject];}// 反向地理編碼成功后 ,進行poi搜索[self beginPoiSearch:self.currentCoor keyword:@""]; }三.poi 檢索
百度地圖poi只能設(shè)置一個關(guān)鍵字(也有可能是我沒找到方法,如果可以設(shè)置多個請及時聯(lián)系,謝謝)?
發(fā)起poi檢索?
#pragma mark ----發(fā)起檢索 // 發(fā)起poi檢索 - (void)beginPoiSearch:(CLLocationCoordinate2D)coor keyword:(NSString *)keyowrd{BMKNearbySearchOption *option = [[BMKNearbySearchOption alloc]init];option.pageCapacity = 50;// 按距離排序option.sortType = BMK_POI_SORT_BY_DISTANCE;// 以地圖中心點為坐標發(fā)起檢索 默認keyword 寫字樓option.location = CLLocationCoordinate2DMake(coor.latitude, coor.longitude);option.keyword = keyowrd.length > 0 ? keyowrd : @"寫字樓";BOOL flag = [self.poiSearch poiSearchNearBy:option];NSLog(@"%@",flag ? @"周邊檢索發(fā)送成功" : @"周邊檢索發(fā)送失敗"); }poi檢索發(fā)起成功后的頁面展示如下圖:
?? ? ? ?
? 圖 一????????????????????????????????????????????????????????????????? ? ?圖 二
這里除了poi檢索之外,還加了一個地圖中心點功能,及拖動地圖的時候以大頭針的位置為當前地圖的中心點,然后再進行poi檢索.這里需要監(jiān)聽另外一個回調(diào)方法.
// 拖拽地圖的回調(diào) - (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {[self beginPoiSearch:self.mapView.centerCoordinate keyword:self.keyword.length > 0 ? self.keyword : @""]; }在這個回調(diào)方法中,以當前地圖的中心為poi檢索的中心點 發(fā)起poi檢索.
四.搜索建議功能和poi詳情檢索
搜搜建議功能截圖如下圖:
在serchDisplayController的代理方法中發(fā)送搜索建議的請求:
#pragma mark ---displayControllerDelegate - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {self.searchText = searchString;self.suggestSearch = [[BMKSuggestionSearch alloc]init];self.suggestSearch.delegate = self;BMKSuggestionSearchOption* option = [[BMKSuggestionSearchOption alloc] init];option.cityname = self.city;option.keyword = searchString;BOOL flag = [self.suggestSearch suggestionSearch:option];NSLog(@"%@",flag ? @"建議檢索發(fā)送成功" : @"建議檢索發(fā)送失敗");return YES; }然后在其回調(diào)方法中處理搜索建議結(jié)果:
// 搜索建議返回的關(guān)鍵詞list和區(qū)list ,coor list,poi id list @property (nonatomic,strong)NSMutableArray *keyList; // 萬達廣場 @property (nonatomic,strong)NSMutableArray *districtList; // 海淀區(qū) @property (nonatomic,strong)NSMutableArray *coorList; // coor 包裝成的 NSValue對象 @property (nonatomic,strong)NSMutableArray *poiuIdList; // poi id- (void)onGetSuggestionResult:(BMKSuggestionSearch *)searcherresult:(BMKSuggestionResult *)resulterrorCode:(BMKSearchErrorCode)error {self.keyList = [NSMutableArray arrayWithCapacity:0];self.districtList = [NSMutableArray arrayWithCapacity:0];self.coorList = [NSMutableArray arrayWithCapacity:0];self.poiuIdList = [NSMutableArray arrayWithCapacity:0];NSMutableArray *emptyLocationArray = [NSMutableArray arrayWithCapacity:0];for (int i = 0; i<result.ptList.count; i++) {CLLocationCoordinate2D coor;NSValue *coorValue = result.ptList[i];[coorValue getValue:&coor];// 非空的地址加到數(shù)組中if (!((int)coor.latitude == 0 && (int)coor.longitude == 0)) {[emptyLocationArray addObject:[NSString stringWithFormat:@"%d",i]];[self.keyList addObject:result.keyList[i]];[self.districtList addObject:result.districtList[i]];[self.coorList addObject:result.ptList[i]];[self.poiuIdList addObject:result.poiIdList[i]];}}[self.displayController.searchResultsTableView reloadData]; }點擊搜索建議tableView的cell時,需要mapView跳轉(zhuǎn)到對應(yīng)的位置,并搜索其附近對應(yīng)的poi信息(比如我點的結(jié)果是個餐廳,那么就地圖就滾動到這個餐廳的位置,并以"餐飲"為關(guān)鍵詞搜索附近的poi信息),所以這里需要用到另外一個接口:poi詳情搜索(注意是poi詳情搜索,兩個有點像)
點擊cell時,根據(jù)poi 的id發(fā)起poi詳情搜索?:
// 發(fā)起poi 詳情檢索 - (void)beginPoiDetailSearch:(NSString *)uid {BMKPoiDetailSearchOption* option = [[BMKPoiDetailSearchOption alloc] init];option.poiUid = uid;//POI搜索結(jié)果中獲取的uidBOOL flag = [self.poiSearch poiDetailSearch:option];NSLog(@"%@",flag ? @"POI詳情檢索發(fā)送成功" : @"POI詳情檢索發(fā)送失敗"); }poi詳情檢索成功后的回調(diào):
- (void)onGetPoiDetailResult:(BMKPoiSearch *)searcher result:(BMKPoiDetailResult *)poiDetailResult errorCode:(BMKSearchErrorCode)errorCode {CLLocationCoordinate2D coor;NSValue *coorValue = self.coorList[self.searchResultSelectedIndexPath.row];[coorValue getValue:&coor];self.keyword = poiDetailResult.tag;// 改變中心坐標[self.mapView setCenterCoordinate:coor animated:YES];[self beginPoiSearch:coor keyword:poiDetailResult.tag]; }返回的結(jié)果是?BMKPoiDetailResult 對象,里面包含了 poi的詳細信息,包括 name address tag(poi標簽)等.
然后以?poiDetailResult.tag 為關(guān)鍵字進行poi搜索.
五.區(qū)域檢索功能
我人在北京,但是想查看石家莊的景點,小吃等信息 . ?此時就需要用到區(qū)域檢索功能了. 先判斷
if (self.city.length > 0) {
? ? ? ? [self beginDistrictSearch];
? ? }?如果傳過來的城市的名字長度大于 0 則說明要先進行區(qū)域檢索.
// 發(fā)起區(qū)域檢索 - (void)beginDistrictSearch {//初始化檢索對象self.districtSearch = [[BMKDistrictSearch alloc] init];//設(shè)置delegate,用于接收檢索結(jié)果self.districtSearch.delegate = self;//構(gòu)造行政區(qū)域檢索信息類BMKDistrictSearchOption *option = [[BMKDistrictSearchOption alloc] init];option.city = self.city;option.district = self.district;//發(fā)起檢索BOOL flag = [self.districtSearch districtSearch:option];NSLog(@"%@",flag ? @"區(qū)域檢索發(fā)送成功" : @"區(qū)域檢索發(fā)送失敗"); }區(qū)域檢索成功后的回調(diào):
- (void)onGetDistrictResult:(BMKDistrictSearch *)searcher result:(BMKDistrictResult *)result errorCode:(BMKSearchErrorCode)error {NSLog(@"---->%f----%f",result.center.latitude,result.center.longitude);// 設(shè)置地圖中心點[self.mapView setCenterCoordinate:result.center animated:YES];// 以城市中心點為中心發(fā)起poi檢索[self beginPoiSearch:result.center keyword:@""]; }這樣就可以實現(xiàn)檢索不同省份城市的 poi信息了.
六.通過url調(diào)起第三方地圖進行
效果如下圖:
?? ? ?
點擊上面導航按鈕會進行判斷,判斷當前app是否安裝了高德,百度以及蘋果自帶的地圖 如果有則將其展示出來否則則不顯示. 點擊之后則會調(diào)起對應(yīng)的地圖進行導航,具體實現(xiàn)可以看我這篇博客 iOS通過URL調(diào)起第三方地圖進行導航
七.自定義彈出pop
效果如下圖:
點擊大頭針彈出pop ,這里的pop是自己繪制的代碼:
@interface BubbleView : UIView@end@implementation BubbleView- (void)drawRect:(CGRect)rect {[super drawRect:rect];CGFloat width = rect.size.width;CGFloat height = rect.size.height;CGFloat radius = 5;CGFloat jianjiaoH = 12;// 獲取CGContext,注意UIKit里用的是一個專門的函數(shù)CGContextRef context = UIGraphicsGetCurrentContext();// 移動到初始點CGContextMoveToPoint(context, radius, 0);// 繪制第1條線和第1個1/4圓弧CGContextAddLineToPoint(context, width - radius, 0);CGContextAddArc(context, width - radius, radius, radius, -0.5 * M_PI, 0.0, 0);// CGContextAddArc(<#CGContextRef _Nullable c#>, <#CGFloat x#>, <#CGFloat y#>, <#CGFloat radius#>, <#CGFloat startAngle#>, <#CGFloat endAngle#>, <#int clockwise#>)// 繪制第2條線和第2個1/4圓弧 17CGContextAddLineToPoint(context, width, height - radius - jianjiaoH);CGContextAddArc(context, width - radius, height - radius - jianjiaoH, radius, 0.0, 0.5 * M_PI, 0);// 繪制第3條線和第3個1/4圓弧和尖角CGContextAddLineToPoint(context, width/2 + 9, height - jianjiaoH);CGContextAddLineToPoint(context, width/2, height);CGContextAddLineToPoint(context, width/2 - 9, height - jianjiaoH);CGContextAddLineToPoint(context, width - radius, height - jianjiaoH);CGContextAddArc(context, radius, height - radius - jianjiaoH, radius, 0.5 * M_PI, M_PI, 0);// 繪制第4條線和第4個1/4圓弧CGContextAddLineToPoint(context, 0, radius);CGContextAddArc(context, radius, radius, radius, M_PI, 1.5 * M_PI, 0);// 閉合路徑CGContextClosePath(context);// 填充半透明黑色CGContextSetRGBFillColor(context, 0, 0, 0.0, 0.5);CGContextDrawPath(context, kCGPathFill); }@end至此,此次我們用的百度地圖的功能已經(jīng)全部分享給大家了,如果紕漏請指正 .全部的代碼我貼在動彈里了 -_-
轉(zhuǎn)載于:https://my.oschina.net/zhxx/blog/748468
總結(jié)
以上是生活随笔為你收集整理的iOS百度地图的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转Java 理论与实践: 正确使用 Vo
- 下一篇: 使用MyBatis的Generator自