高德地圖---顯示/定位/POI搜尋/大頭針/氣泡
阿新 • • 發佈:2019-01-26
接觸高德地圖也有一段時間了。但是也有很長一段時間沒用了,手生了。閒來無事就再寫寫地圖。好在高德的文件做的很詳實,使用起來得心應手。今天就寫了一點關於顯示/定位/POI搜尋/大頭針/氣泡的簡單程式碼。
難點就是搜尋後大頭針的問題。首先需要移除上一次搜尋顯示的大頭針,再顯示這一次需要顯示大頭針,不然螢幕顯示的大頭針會越來越多。這一點在官方的視訊裡面是有這些的。
首先上一張效果圖:
這次使用的版本是V2.6.0的。這個官方也有文件和視訊。高德開放平臺 http://lbs.amap.com/api/ios-sdk/guide/nearby/。
之間看程式碼,程式碼裡面的註釋還是比較詳細的。程式碼下載地址:高德地圖Demo
ViewController.m
DetailViewController.m#import "ViewController.h" //地圖顯示需要的標頭檔案 #import <MAMapKit/MAMapKit.h> //poi搜素需要的標頭檔案 #import <AMapSearchKit/AMapSearchAPI.h> #import "DetailViewController.h" @interface ViewController ()<MAMapViewDelegate, AMapSearchDelegate,UISearchBarDelegate,UITableViewDelegate,UITableViewDataSource> @property (nonatomic,strong)MAMapView *mapView; @property (nonatomic,strong)AMapSearchAPI *search; @property (nonatomic,strong)MAUserLocation *location; @property (nonatomic,strong)AMapPlaceSearchRequest *request; @property (nonatomic,strong)UISearchBar *searchBar; @property (nonatomic,strong)UITableView *tableView; @property (nonatomic,strong)NSMutableArray *annotationArr; @property (nonatomic,strong)NSMutableArray *poisArray; @property (nonatomic,assign)NSInteger index; @end @implementation ViewController #pragma mark - 頁面跳轉時需要使用 /* 需要頁面跳轉時使用 - (void)viewWillAppear:(BOOL)animated{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setPoiPoint:) name:@"test" object:nil]; } - (void)setPoiPoint:(NSNotification *)notice{ //先移除掉上次搜尋的大頭針 [self.mapView removeAnnotations:self.annotationArr]; //清空陣列 [self.annotationArr removeAllObjects]; NSString *index = notice.object; AMapPOI *poi = self.poisArray[index.integerValue]; MAPointAnnotation *annotation = [[MAPointAnnotation alloc] init]; CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(poi.location.latitude, poi.location.longitude); annotation.coordinate = coordinate; annotation.title = poi.name; annotation.subtitle = poi.address; [self.annotationArr addObject:annotation]; [self.mapView addAnnotation:annotation]; } */ - (void)viewDidLoad { [super viewDidLoad]; //增加一個KVO index [self addObserver:self forKeyPath:@"index" options: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; self.annotationArr = [[NSMutableArray alloc] init]; [self configApiKey]; [self setMySearchConterl]; [self setMainView]; [self setTableView]; //獲取bundleIdentifier // NSLog(@"bundleIdentifier = %@",[[NSBundle mainBundle] bundleIdentifier]); // Do any additional setup after loading the view, typically from a nib. } #pragma mark - 地圖顯示和搜尋部分 /** * 配置APIKey */ - (void)configApiKey{ [MAMapServices sharedServices].apiKey = @"a12bc9db3e3f5ba30482aa704ee0fc29"; } /** * 設定地圖顯示 有這個方法就可以顯示使用者的位置 */ - (void)setMainView{ self.mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, 200)]; self.mapView.delegate = self; //設定地圖語言 預設是中文 // self.mapView.language = MAMapLanguageEn; //地圖型別 預設是2D柵格地圖 // self.mapView.mapType = MAMapTypeSatellite; //關閉指南針顯示 self.mapView.showsCompass = NO; //關閉比例尺顯示 self.mapView.showsScale = NO; //顯示使用者位置 self.mapView.showsUserLocation = YES; //設定跟蹤模式 self.mapView.userTrackingMode = MAUserTrackingModeFollow; [self.view addSubview:self.mapView]; } /** * 設定POI搜素請求 * * @param keyword 搜尋需要的關鍵字 */ - (void)setPoiSearchMapWithKeyword:(NSString *)keyword{ //初始化檢索物件 self.search = [[AMapSearchAPI alloc] initWithSearchKey:[MAMapServices sharedServices].apiKey Delegate:self]; //構建AMapPlaceSearchRequest物件 self.request = [[AMapPlaceSearchRequest alloc] init]; //搜尋型別 關鍵字搜尋 self.request.searchType = AMapSearchType_PlaceKeyword; //設定搜尋關鍵字 self.request.keywords = keyword; //搜尋地點 廣州 self.request.city = @[@"guangzhou"]; //開擴充套件 self.request.requireExtension = YES; //發起POI搜尋 [self.search AMapPlaceSearch:self.request]; } /** * POI搜尋請求後呼叫的方法 * * @param request 搜尋請求 * @param response 請求結果 */ - (void)onPlaceSearchDone:(AMapPlaceSearchRequest *)request response:(AMapPlaceSearchResponse *)response{ if (response.count == 0) { return; } /* 僅僅顯示搜尋結果的大頭針 //先移除掉上次搜尋的大頭針 不然上一次的大頭針會一直存在 [self.mapView removeAnnotations:self.annotationArr]; //清空陣列 [self.annotationArr removeAllObjects]; */ // NSString *responseCount = [NSString stringWithFormat:@"%d",response.count];; // NSLog(@"responseCount = %@",responseCount); self.poisArray = [[NSMutableArray alloc] init]; for (AMapPOI *poi in response.pois) { [self.poisArray addObject:poi]; /* 僅僅顯示搜尋結果的大頭針 MAPointAnnotation *annotation = [[MAPointAnnotation alloc] init]; CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(poi.location.latitude, poi.location.longitude); annotation.coordinate = coordinate; annotation.title = poi.name; annotation.subtitle = poi.address; [self.annotationArr addObject:annotation]; [self.mapView addAnnotation:annotation]; */ } [self.tableView reloadData]; /*需要頁面跳轉時使用 DetailViewController *dvc = [[DetailViewController alloc] init]; dvc.poisArray = self.poisArray; [self presentViewController:dvc animated:YES completion:nil]; */ } /** * 設定大頭針點選後的氣泡 * * @param mapView mapView * @param annotation annotation * * @return 氣泡 */ - (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation{ // if ([annotation isKindOfClass:[MAAnnotationView class]]) { static NSString *identify = @"annotation"; //在原有的大頭針中新增自定義的修飾 MAPinAnnotationView *pointAnnotation = (MAPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identify]; if (pointAnnotation == nil) { //在原有的大頭針中建立一個新的自定義的大頭針 pointAnnotation = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identify]; } //設定是否能選中的標題 pointAnnotation.canShowCallout = YES; //是否允許拖拽 pointAnnotation.draggable = YES; //是否允許退拽動畫 pointAnnotation.animatesDrop = YES; return pointAnnotation; } /** * 地圖定位後就會呼叫這個方法 酒店 * * @param mapView 當前的mapView * @param userLocation userLocation * @param updatingLocation 位置更新標誌 */ - (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{ // NSLog(@"地圖"); if (updatingLocation) { // NSLog(@"latitude = %f longitude = %f",userLocation.coordinate.latitude,userLocation.coordinate.longitude); //確定地圖經緯度 CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude); //設定的當前位置 為地圖中心 self.mapView.centerCoordinate = coordinate; self.location = userLocation; } } #pragma mark - searchBar部分 /** * 設定searchBar */ - (void)setMySearchConterl{ self.searchBar = [[UISearchBar alloc] init]; self.searchBar.frame = CGRectMake(0, 20, self.view.frame.size.width, 44); self.searchBar.delegate = self; self.searchBar.placeholder = @"請輸入關鍵字"; [self.view addSubview:self.searchBar]; } - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{ return YES; } /** * 設定左邊的“取消”按鈕 * * @param searchBar searchBar */ - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{ self.searchBar.showsCancelButton = YES; for (id cc in [searchBar.subviews[0] subviews]) { if ([cc isKindOfClass:[UIButton class]]) { UIButton * cancelButton = (UIButton *)cc; [cancelButton setTitle:@"取消" forState:UIControlStateNormal]; } } }// called when text starts editing - (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar{ return YES; }// return NO to not resign first responder - (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text NS_AVAILABLE_IOS(3_0){ return YES; }// called before text changes /** * 鍵盤搜尋按鈕按下就會呼叫這個方法 * * @param searchBar searchBar本身 */ - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ // NSLog(@"text = %@",searchBar.text); //發起POI搜尋請求 [self setPoiSearchMapWithKeyword:searchBar.text]; //收起鍵盤 [searchBar resignFirstResponder]; searchBar.text = @""; }// called when keyboard search button pressed /** * “取消”按鈕按下會呼叫這個方法 * 收起鍵盤 * @param searchBar searchBar本身 */ - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{ [searchBar resignFirstResponder]; self.searchBar.showsCancelButton = NO; }// called when cancel button pressed #pragma mark - tableView部分 /** * 設定tableView */ - (void)setTableView{ self.tableView = [[UITableView alloc] init]; self.tableView.frame = CGRectMake(0, 264, self.view.frame.size.width, self.view.frame.size.height - 264); self.tableView.delegate = self; self.tableView.dataSource = self; [self.view addSubview:self.tableView]; } /** * 設定tableView的row個數 * * @param tableView tableView本身 * @param section 當前的section * * @return 當前section裡面的row數 */ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.poisArray.count; } /** * 設定cell的顯示 * * @param tableView tableView本身 * @param indexPath cell的位置 * * @return cell */ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *identify = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identify]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identify]; } AMapPOI *poi = (AMapPOI *)self.poisArray[indexPath.row]; cell.textLabel.text = poi.name; cell.detailTextLabel.text = poi.address; return cell; } /** * tableView點選時間 * * @param tableView tableView本身 * @param indexPath 被點選的cell的位置 */ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ self.index = indexPath.row; } /** * 實現KVO鍵值監聽的方法 * 值改變後 增加大頭針 * @param keyPath keyPath * @param object self * @param change 值字典 * @param context */ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ //先移除掉上次搜尋的大頭針 [self.mapView removeAnnotations:self.annotationArr]; //清空陣列 [self.annotationArr removeAllObjects]; NSString *index = change[@"new"]; AMapPOI *poi = self.poisArray[index.integerValue]; MAPointAnnotation *annotation = [[MAPointAnnotation alloc] init]; CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(poi.location.latitude, poi.location.longitude); //地圖中心點 設定為選中的點 self.mapView.centerCoordinate = coordinate; annotation.coordinate = coordinate; //一下兩句 就是氣泡的顯示內容 annotation.title = poi.name; annotation.subtitle = poi.address; [self.annotationArr addObject:annotation]; [self.mapView addAnnotation:annotation]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
#import "DetailViewController.h" #import <AMapSearchKit/AMapSearchAPI.h> @interface DetailViewController ()<UITableViewDataSource,UITableViewDelegate> @property (weak, nonatomic) IBOutlet UITableView *tableView; @end @implementation DetailViewController - (void)viewDidLoad { [super viewDidLoad]; [self setMainView]; // Do any additional setup after loading the view from its nib. } - (void)setMainView{ self.tableView.delegate = self; self.tableView.dataSource = self; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.poisArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *identify = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identify]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identify]; } AMapPOI *poi = (AMapPOI *)self.poisArray[indexPath.row]; cell.textLabel.text = poi.name; cell.detailTextLabel.text = poi.address; return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:[NSString stringWithFormat:@"%d",indexPath.row]]; [self dismissViewControllerAnimated:YES completion:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }