最近趕項(xiàng)目,好久沒(méi)更新沈条。抽出時(shí)間把高德地圖的搜索和路徑規(guī)劃整理一下
項(xiàng)目中想加入地圖功能需忿,使用高德地圖第三方,想要實(shí)現(xiàn)確定一個(gè)位置,搜索路線并且顯示的方法贴谎。耗了一番功夫汞扎,總算實(shí)現(xiàn)了。
效果
WeChat_1462507820.jpeg
一擅这、配置工作
1.申請(qǐng)key
訪問(wèn) http://lbs.amap.com/dev/key/ 在高度地圖第三方開(kāi)發(fā)平臺(tái)申請(qǐng)一個(gè)key,注冊(cè)賬戶景鼠,新建應(yīng)用仲翎,這個(gè)沒(méi)什么門檻。
得到這個(gè)key
屏幕快照 2016-05-06 上午10.34.15.png
提示一下铛漓,這個(gè)key對(duì)應(yīng)的bundle ID 要和工程里面的bundle ID 相同溯香,不然每次打開(kāi)地圖都會(huì)報(bào)一個(gè)Invalid_user_scode的提示。
2.導(dǎo)入第三方
方便起見(jiàn) pod導(dǎo)入
pod 'AMap3DMap' #3D地圖SDK
#pod 'AMap2DMap' #2D地圖SDK(2D地圖和3D地圖不能同時(shí)使用浓恶,2選1)
pod 'AMapSearch' #搜索服務(wù)SDK
3.打開(kāi)工程的后臺(tái)定位功能 更改info.plist
增加兩條玫坛,一條請(qǐng)求位置時(shí)提示,一條https
屏幕快照 2016-05-06 上午11.02.06.png
屏幕快照 2016-05-06 上午10.48.19.png
二包晰、地圖基本顯示
把地圖添加到view即可顯示
- (void)viewDidLoad {
[super viewDidLoad];
//配置用戶Key
[MAMapServices sharedServices].apiKey = @"76bb9bc3718375ad03acba7c333694c4";
//把地圖放在底層
[self.view insertSubview:self.mapView atIndex:0];
}
//地圖懶加載
- (MAMapView *)mapView
{
if (!_mapView) {
_mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds))];
_mapView.delegate = self;
_mapView.showsUserLocation = YES; //YES 為打開(kāi)定位湿镀,NO為關(guān)閉定位
[_mapView setUserTrackingMode: MAUserTrackingModeFollow animated:NO]; //地圖跟著位置移動(dòng)
//自定義定位經(jīng)度圈樣式
_mapView.customizeUserLocationAccuracyCircleRepresentation = NO;
//地圖跟蹤模式
_mapView.userTrackingMode = MAUserTrackingModeFollow;
//后臺(tái)定位
_mapView.pausesLocationUpdatesAutomatically = NO;
_mapView.allowsBackgroundLocationUpdates = YES;//iOS9以上系統(tǒng)必須配置
}
return _mapView;
}
三、地圖搜索功能
遵守協(xié)議 AMapSearchDelegate
高德提供了多種搜索方式伐憾,POI搜索(關(guān)鍵字查詢勉痴、周邊搜索、多邊形查詢)树肃,檢索現(xiàn)實(shí)中真實(shí)存在的地物蒸矛。
提示搜索,就是在還沒(méi)有輸入完全時(shí)胸嘴,根據(jù)已有字符進(jìn)行的搜索
//搜索框激活時(shí)雏掠,使用提示搜索
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
//發(fā)起輸入提示搜索
AMapInputTipsSearchRequest *tipsRequest = [[AMapInputTipsSearchRequest alloc] init];
//關(guān)鍵字
tipsRequest.keywords = _searchController.searchBar.text;
//城市
tipsRequest.city = _currentCity;
//執(zhí)行搜索
[_search AMapInputTipsSearch: tipsRequest];
}
//實(shí)現(xiàn)輸入提示的回調(diào)函數(shù)
-(void)onInputTipsSearchDone:(AMapInputTipsSearchRequest*)request response:(AMapInputTipsSearchResponse *)response
{
if(response.tips.count == 0)
{
return;
}
//通過(guò)AMapInputTipsSearchResponse對(duì)象處理搜索結(jié)果
//先清空數(shù)組
[self.searchList removeAllObjects];
for (AMapTip *p in response.tips) {
//把搜索結(jié)果存在數(shù)組
[self.searchList addObject:p];
}
_isSelected = NO;
//刷新表視圖
[self.tableView reloadData];
}
點(diǎn)擊進(jìn)行poi搜索
//周邊搜索
- (IBAction)searchAction:(id)sender {
//初始化檢索對(duì)象
_search = [[AMapSearchAPI alloc] init];
_search.delegate = self;
//構(gòu)造AMapPOIAroundSearchRequest對(duì)象,設(shè)置周邊請(qǐng)求參數(shù)
AMapPOIAroundSearchRequest *request = [[AMapPOIAroundSearchRequest alloc] init];
//當(dāng)前位置
request.location = [AMapGeoPoint locationWithLatitude:_currentLocation.coordinate.latitude longitude:_currentLocation.coordinate.longitude];
//關(guān)鍵字
request.keywords = _searchController.searchBar.text;
NSLog(@"%@",_searchController.searchBar.text);
// types屬性表示限定搜索POI的類別劣像,默認(rèn)為:餐飲服務(wù)|商務(wù)住宅|生活服務(wù)
// POI的類型共分為20種大類別乡话,分別為:
// 汽車服務(wù)|汽車銷售|汽車維修|摩托車服務(wù)|餐飲服務(wù)|購(gòu)物服務(wù)|生活服務(wù)|體育休閑服務(wù)|
// 醫(yī)療保健服務(wù)|住宿服務(wù)|風(fēng)景名勝|(zhì)商務(wù)住宅|政府機(jī)構(gòu)及社會(huì)團(tuán)體|科教文化服務(wù)|
// 交通設(shè)施服務(wù)|金融保險(xiǎn)服務(wù)|公司企業(yè)|道路附屬設(shè)施|地名地址信息|公共設(shè)施
// request.types = @"餐飲服務(wù)|生活服務(wù)";
request.radius = 5000;//<! 查詢半徑,范圍:0-50000驾讲,單位:米 [default = 3000]
request.sortrule = 0;
request.requireExtension = YES;
//發(fā)起周邊搜索
[_search AMapPOIAroundSearch:request];
}
//實(shí)現(xiàn)POI搜索對(duì)應(yīng)的回調(diào)函數(shù)
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
{
if(response.pois.count == 0)
{
return;
}
//通過(guò) AMapPOISearchResponse 對(duì)象處理搜索結(jié)果
[self.dataList removeAllObjects];
for (AMapPOI *p in response.pois) {
NSLog(@"%@",[NSString stringWithFormat:@"%@\nPOI: %@,%@", p.description,p.name,p.address]);
//搜索結(jié)果存在數(shù)組
[self.dataList addObject:p];
}
_isSelected = YES;
[self.tableView reloadData];
}
四蚊伞、路徑規(guī)劃
規(guī)劃路徑查詢(駕車路線搜索、公交換成方案查詢吮铭、步行路徑檢索)时迫,提前知道出行路線
//規(guī)劃線路查詢
- (IBAction)findWayAction:(id)sender {
//構(gòu)造AMapDrivingRouteSearchRequest對(duì)象,設(shè)置駕車路徑規(guī)劃請(qǐng)求參數(shù)
AMapWalkingRouteSearchRequest *request = [[AMapWalkingRouteSearchRequest alloc] init];
//設(shè)置起點(diǎn)谓晌,我選擇了當(dāng)前位置掠拳,mapView有這個(gè)屬性
request.origin = [AMapGeoPoint locationWithLatitude:_currentLocation.coordinate.latitude longitude:_currentLocation.coordinate.longitude];
//設(shè)置終點(diǎn),可以選擇手點(diǎn)
request.destination = [AMapGeoPoint locationWithLatitude:_destinationPoint.coordinate.latitude longitude:_destinationPoint.coordinate.longitude];
// request.strategy = 2;//距離優(yōu)先
// request.requireExtension = YES;
//發(fā)起路徑搜索纸肉,發(fā)起后會(huì)執(zhí)行代理方法
//這里使用的是步行路徑
[_search AMapWalkingRouteSearch: request];
}
//長(zhǎng)按手勢(shì)響應(yīng)方法溺欧,選擇路徑規(guī)劃的終點(diǎn)喊熟,手勢(shì)自己加
- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan)
{
//在地圖上長(zhǎng)按的位置
CGPoint p = [gesture locationInView:_mapView];
NSLog(@"press on (%f, %f)", p.x, p.y);
}
//轉(zhuǎn)換成經(jīng)緯度
CLLocationCoordinate2D coordinate = [_mapView convertPoint:[gesture locationInView:_mapView] toCoordinateFromView:_mapView];
//賦值給目標(biāo)點(diǎn)
_destinationPoint = [[MAPointAnnotation alloc] init];
_destinationPoint.coordinate = coordinate;
}
執(zhí)行路徑搜索后會(huì)執(zhí)行代理方法
//實(shí)現(xiàn)路徑搜索的回調(diào)函數(shù)
- (void)onRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapRouteSearchResponse *)response
{
if(response.route == nil)
{
return;
}
//通過(guò)AMapNavigationSearchResponse對(duì)象處理搜索結(jié)果
NSString *route = [NSString stringWithFormat:@"Navi: %@", response.route];
AMapPath *path = response.route.paths[0]; //選擇一條路徑
AMapStep *step = path.steps[0]; //這個(gè)路徑上的導(dǎo)航路段數(shù)組
NSLog(@"%@",step.polyline); //此路段坐標(biāo)點(diǎn)字符串
if (response.count > 0)
{
//移除地圖原本的遮蓋
[_mapView removeOverlays:_pathPolylines];
_pathPolylines = nil;
// 只顯?示第?條 規(guī)劃的路徑
_pathPolylines = [self polylinesForPath:response.route.paths[0]];
NSLog(@"%@",response.route.paths[0]);
//添加新的遮蓋,然后會(huì)觸發(fā)代理方法進(jìn)行繪制
[_mapView addOverlays:_pathPolylines];
}
}
每次添加路線姐刁,區(qū)域芥牌,或者大頭針等都會(huì)觸發(fā)下面的代理方法
//繪制遮蓋時(shí)執(zhí)行的代理方法
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <MAOverlay>)overlay
{
/* 自定義定位精度對(duì)應(yīng)的MACircleView. */
//畫路線
if ([overlay isKindOfClass:[MAPolyline class]])
{
//初始化一個(gè)路線類型的view
MAPolylineRenderer *polygonView = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
//設(shè)置線寬顏色等
polygonView.lineWidth = 8.f;
polygonView.strokeColor = [UIColor colorWithRed:0.015 green:0.658 blue:0.986 alpha:1.000];
polygonView.fillColor = [UIColor colorWithRed:0.940 green:0.771 blue:0.143 alpha:0.800];
polygonView.lineJoinType = kMALineJoinRound;//連接類型
//返回view,就進(jìn)行了添加
return polygonView;
}
return nil;
}
最后聂使,這是demo壁拉,最好真機(jī)測(cè)試,模擬器的定位不好用
https://github.com/DaLiWangCC/MyOpen