前言
項目中要集成百度地圖令蛉,百度的api文檔寫的很亂,說一下我們項目需求,我們有兩個界面需要用到百度地圖。
1.一個需要點擊地理位置在地圖上搜索定位屈呕。
2.另一個類似于微信發(fā)朋友圈輸入關(guān)鍵詞模糊搜索地理位置信息
<br />
開發(fā)過程中遇到的問題先跟大家分享一下,我在導(dǎo)入百度地圖之后,跳轉(zhuǎn)到地圖界面不能滑動不能縮放棺亭,心里很納悶虎眨,而且我也沒有在這里用到手勢縮放、和一些帶滑動的控制器呀镶摘,后來我看上個控制器我發(fā)現(xiàn)我把 這個控制器imageVIew和他上邊的一些按鈕整到 window最上層嗽桩,控制器結(jié)束了跳轉(zhuǎn)到這個界面之后imageView還在Window最上層上,所以你創(chuàng)建的地圖就相當(dāng)于一個在image上當(dāng)然不可能拖動凄敢。所以對于這種問題要向相似的地方想碌冶,很快就能找到問題的所在。
<br />
搜索定位調(diào)起本機地圖.gif
<br />
類似微信模糊搜索.gif
<br />
定位功能的實現(xiàn)步驟
1.配置環(huán)境
建議使用cocoaPods涝缝,這樣減少好多無用功
2.在delegate設(shè)置AppKey扑庞、創(chuàng)建百度manager
如果你導(dǎo)入的第三方太多導(dǎo)致APPdelegate代碼太多,你也可以把各個第三方在delegate里邊的內(nèi)容用類的類別分成一個一個的這樣比較好管理.
.h 文件
#import "AppDelegate.h"
#import <BaiduMapAPI_Base/BMKMapManager.h>
@interface AppDelegate (BaiDu)
- (void)initBaiduMapApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
@end
.m文件
#import "AppDelegate+BaiDu.h"
@implementation AppDelegate (BaiDu)
- (void)initBaiduMapApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//創(chuàng)建并初始化一個引擎對象
BMKMapManager *manager = [[BMKMapManager alloc] init];
//啟動地圖引擎
BOOL success = [manager start:@"LV7PXGmnzecWjEZZ9leZADGUoYXeaVzd" generalDelegate:nil];
if (!success) {
NSLog(@"失敗");
}
// Override point for customization after application launch.
}
然后在APPdelegate里邊調(diào)用這個方法就行了
<br />
3.在相應(yīng)的 controller 里邊導(dǎo)入需要的頭文件、設(shè)置百度地圖的代理
#import "TJLocationMapViewController.h"
/***
<自己定義的大頭針>
****/
#import "mapMark.h"
/***
<最下邊的點擊調(diào)起本機地圖視圖>
****/
#import "TJGuideView.h"
/***
<系統(tǒng)地圖頭文件>
****/
#import <MapKit/MapKit.h>
#import <BaiduMapAPI_Map/BMKMapView.h>
#import <BaiduMapAPI_Map/BMKMapComponent.h>
#import <BaiduMapAPI_Location/BMKLocationComponent.h>
#import <BaiduMapAPI_Search/BMKSearchComponent.h>
@interface TJLocationMapViewController ()<BMKMapViewDelegate,BMKLocationServiceDelegate,BMKPoiSearchDelegate,UIActionSheetDelegate>
@property (nonatomic,strong) BMKMapView *mapView;//地圖視圖
@property (nonatomic,strong) BMKLocationService *locationService;//定位服務(wù)
@property (nonatomic,strong)BMKPoiSearch *poiSearch;
@property (nonatomic , strong)NSMutableArray *dataArr;
/***
<存儲地圖定位自己和目標(biāo)位置坐標(biāo)>
***/
@property (nonatomic)CLLocationCoordinate2D beginingCoordinate;
@property (nonatomic)CLLocationCoordinate2D destinationCoordinate;
/***
<存儲定位地圖的位置名稱>
***/
@property (nonatomic , strong)NSString *myNameStr;
@property (nonatomic , strong)NSString *toNameStr;
/***
<返回到上個控制器的button和點擊回到自己位置的button>
***/
@property (nonatomic , strong)UIButton *backBtn;
@property (nonatomic , strong)UIButton *backToMyselfLocatinBtn;
@property (nonatomic , strong)TJGuideView *guideView;
@end
<br />
注:前三步看百度文檔應(yīng)該沒問題拒逮,好了預(yù)備工作做完了下面開始寫基本功能了
4.創(chuàng)建_mapView罐氨、_locationService、_poiSearch并且在-(void)viewWillAppear:(BOOL)animated滩援、-(void)viewWillDisappear:(BOOL)animated里邊設(shè)置和取消他們的代理栅隐,設(shè)置地圖的一些基本信息
<br />
創(chuàng)建 mapView
self.mapView = [[BMKMapView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, SCREEN_HEIGHT - 105*ADAPTERWIDTH)];
/****
地圖樣式
***/
self.mapView.mapType = BMKMapTypeStandard;
self.mapView.userTrackingMode = BMKUserTrackingModeNone;
self.mapView.scrollEnabled = YES;
self.mapView.showsUserLocation = YES;
//在手機上當(dāng)前可使用的級別為3-21級
self.mapView.zoomLevel = 18;
/***
<定位服務(wù)>
****/
_locationService = [[BMKLocationService alloc] init];
_locationService.distanceFilter = 10.f;
_locationService.desiredAccuracy = kCLLocationAccuracyBest;
[_locationService startUserLocationService];//開始定位
[self.view addSubview:self.mapView];
設(shè)置取消代理
-(void)viewWillAppear:(BOOL)animated
{
[_mapView viewWillAppear];
self.navigationController.navigationBar.hidden = YES;
_mapView.delegate = self; // 此處記得不用的時候需要置nil,否則影響內(nèi)存的釋放
_poiSearch.delegate = self;
_locationService.delegate = self;
}
-(void)viewWillDisappear:(BOOL)animated
{
[_mapView viewWillDisappear];
[self.navigationController setNavigationBarHidden:NO animated:YES];
_mapView.delegate = nil; // 不用時玩徊,置nil
_poiSearch.delegate = nil;
_locationService.delegate = nil;
}
<br />
5.一些代理方法的實現(xiàn)
#pragma mark - BMK Location delegate
/***
<定位>
***/
-(void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation{
CLLocation *location = userLocation.location;
mapMark *nowAnno = [[mapMark alloc] init];
nowAnno.coordinate = location.coordinate;
nowAnno.title = @"我的位置";
nowAnno.type = 0;
[self.mapView addAnnotation:nowAnno];
BMKCoordinateSpan span;
span.latitudeDelta = 0.5;
span.longitudeDelta = 0.5;
BMKCoordinateRegion region;
region.center = location.coordinate;
region.span = span;
[self.mapView setRegion:region animated:YES];
//停止定位
[_locationService stopUserLocationService];
//檢索
[self addBMKCloudSearchWith:userLocation];
}
- (void)addBMKCloudSearchWith:(BMKUserLocation *)userLocation{
// 初始化云檢索服務(wù)
_poiSearch = [[BMKPoiSearch alloc] init];
_poiSearch.delegate = self;
// 設(shè)置地圖級別
[self.mapView setZoomLevel:17];
self.mapView.isSelectedAnnotationViewFront = YES; //設(shè)定是否總讓選中的annotaion置于最前面
BMKNearbySearchOption * option = [[BMKNearbySearchOption alloc]init];
/***
<這個值本來是傳過來的不是固定的租悄,我這里寫的固定是方便大家看>
***/
option.keyword = @"成都市金牛區(qū)萬達(dá)廣場";
option.location = userLocation.location.coordinate;
self.beginingCoordinate = option.location;
NSLog(@"option.loction == %f %f", self.beginingCoordinate.latitude, self.beginingCoordinate.longitude);
option.radius = 10000;
/***
<因為我需要一個定位所以我就拿一個位置的信息>
***/
option.pageCapacity = 1;
BOOL flag = [_poiSearch poiSearchNearBy:option];
if (flag) {
NSLog(@"檢索發(fā)送成功");
}else{
NSLog(@"檢索發(fā)送失敗");
}
}
#pragma mark implement BMKSearchDelegate
/***
<檢索數(shù)據(jù)回調(diào),數(shù)據(jù)都在BMKPoiResult里邊恩袱,拿出來想怎么用都行>
***/
- (void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPoiResult*)result errorCode:(BMKSearchErrorCode)error{
if (error == BMK_SEARCH_NO_ERROR) {
NSMutableArray *annotations = [NSMutableArray array];
result.currPoiNum = 1;
for (int i = 0; i < result.poiInfoList.count; i++) {
BMKPoiInfo* poi = [result.poiInfoList objectAtIndex:i];
mapMark* item = [[mapMark alloc]init];
item.coordinate = poi.pt;
self.destinationCoordinate = item.coordinate;
NSLog(@"%f %f", self.destinationCoordinate.longitude , self.destinationCoordinate.latitude);
item.title = poi.name;
NSLog(@"self.title%@",item.title);
item.type = 1;
[self.dataArr addObject:poi];
[annotations addObject:item];
}
[self.mapView addAnnotations:annotations];//添加大頭針
[self.mapView showAnnotations:annotations animated:YES];//顯示
} else if (error == BMK_SEARCH_PERMISSION_UNFINISHED){
NSLog(@"用戶沒有授權(quán)");
}else{
NSLog(@"檢索失斊濉:%d",error);
}
}
<br />
6.添加大頭針
/***
<大頭針>
***/
- (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id <BMKAnnotation>)annotation{
if ([annotation isKindOfClass:[mapMark class]]) {
mapMark *anno = (mapMark *)annotation;
// 生成重用標(biāo)示identifier
NSString *AnnotationViewID = @"xidanMark";
// 檢查是否有重用的緩存
BMKAnnotationView* annotationView = [view dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
// 緩存沒有命中,自己構(gòu)造一個畔塔,一般首次添加annotation代碼會運行到此處
if (annotationView == nil) {
annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
if (anno.type == 0) {
((BMKPinAnnotationView*)annotationView).pinColor = BMKPinAnnotationColorPurple;
}else if (anno.type == 1){
((BMKPinAnnotationView*)annotationView).pinColor = BMKPinAnnotationColorRed;
}
// 設(shè)置重天上掉下的效果(annotation)
((BMKPinAnnotationView*)annotationView).animatesDrop = YES;
}
// 設(shè)置位置
annotationView.centerOffset = CGPointMake(0, -(annotationView.frame.size.height * 0.5));
annotationView.annotation = annotation;
annotationView.canShowCallout = YES;
[self.mapView selectAnnotation:anno animated:YES];
// 設(shè)置是否可以拖拽
annotationView.draggable = NO;
return annotationView;
}
return nil;
}
好了基本的定位功能就實現(xiàn)了
<br />
下邊就是實現(xiàn)點擊回到自己位置功能和調(diào)起本機地圖功能
1.點擊回到自己位置
其實這個功能很簡單外傅,只要拿到自己的位置數(shù)據(jù),只需要把自己的位置再次設(shè)置到地圖中心點就行了.
/***
<點擊回到自己的位置>
***/
-(void)backToMyselfLocatin:(UIButton *)sender{
BMKCoordinateRegion region ;//表示范圍的結(jié)構(gòu)體
//設(shè)置自己為中心點
region.center = self.beginingCoordinate;//中心點
region.span.latitudeDelta = 0.01;//經(jīng)度范圍(設(shè)置為0.1表示顯示范圍為0.2的緯度范圍)
region.span.longitudeDelta = 0.01;//緯度范圍
[_mapView setRegion:region animated:YES];
}
2.調(diào)起本機地圖
我只寫主要代碼就好了,蘋果地圖使用option就行了不用 URL 調(diào)起俩檬,而百度地圖需要配置URL才能調(diào)起不過性質(zhì)大概都一樣
<br />
調(diào)起百度地圖
//主要是配置自己和目的地的一些左邊參數(shù)萎胰,另外百度地圖如果那個mode參數(shù)里邊你不加經(jīng)緯度格式參數(shù)的話它默認(rèn)就是百度地圖用的參數(shù),加的話記得要和百度地圖的一致
NSString *url = [[NSString stringWithFormat:@"baidumap://map/direction?origin=latlng:%f,%f|name:我的位置&destination=latlng:%f,%f|name:%@&mode=driving®ion=成都",self.beginingCoordinate.longitude, self.beginingCoordinate.latitude,self.destinationCoordinate.longitude,self.destinationCoordinate.latitude,@"成都市萬達(dá)廣場"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] ;
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://map/"]])
{
if ([[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]] == NO)
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms://itunes.apple.com/cn/app/百度地圖-智能的手機導(dǎo)航-公交地鐵出行必備/id452186370?mt=8"]];
}
}else{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms://itunes.apple.com/cn/app/百度地圖-智能的手機導(dǎo)航-公交地鐵出行必備/id452186370?mt=8"]];
}
<br />
調(diào)起蘋果地圖
MKMapItem *currentLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake((self.beginingCoordinate.latitude),(self.beginingCoordinate.longitude)) addressDictionary:nil]];
currentLocation.name =@"我的位置";
//目的地的位置
MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:self.destinationCoordinate addressDictionary:nil]];
toLocation.name = @"成都萬達(dá)廣場";
NSArray *items = [NSArray arrayWithObjects:currentLocation, toLocation, nil];
NSDictionary *options = @{ MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsMapTypeKey: [NSNumber numberWithInteger:MKMapTypeStandard], MKLaunchOptionsShowsTrafficKey:@YES };
//打開蘋果自身地圖應(yīng)用棚辽,并呈現(xiàn)特定的item
[MKMapItem openMapsWithItems:items launchOptions:options];
<br />