1. 程式人生 > >高德地圖---顯示/定位/POI搜尋/大頭針/氣泡

高德地圖---顯示/定位/POI搜尋/大頭針/氣泡

接觸高德地圖也有一段時間了。但是也有很長一段時間沒用了,手生了。閒來無事就再寫寫地圖。好在高德的文件做的很詳實,使用起來得心應手。今天就寫了一點關於顯示/定位/POI搜尋/大頭針/氣泡的簡單程式碼。

難點就是搜尋後大頭針的問題。首先需要移除上一次搜尋顯示的大頭針,再顯示這一次需要顯示大頭針,不然螢幕顯示的大頭針會越來越多。這一點在官方的視訊裡面是有這些的。

首先上一張效果圖:


這次使用的版本是V2.6.0的。這個官方也有文件和視訊。高德開放平臺  http://lbs.amap.com/api/ios-sdk/guide/nearby/。

之間看程式碼,程式碼裡面的註釋還是比較詳細的。程式碼下載地址:高德地圖Demo

下載  https://github.com/zhuming3834/GaodeDemo。

ViewController.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
DetailViewController.m
#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.
}