iOS程式設計師之高德地圖SDK
阿新 • • 發佈:2019-01-31
高德SDK
最近專案中需要定位客戶位置,要滿足地址搜尋,長按地圖新增,同時大頭針還要能移動的需求,這裡整理下,希望幫助有需要的人
1.新增地圖
// 地圖 _mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, lineView.bottom, SCREEN_WIDTH, SCREEN_HEIGHT-lineView.bottom-kViewMargin)]; _mapView.showsCompass = NO; // 隱藏指南針 _mapView.showsScale = NO; // 隱藏比例尺 _mapView.delegate = self; [_mapView setUserTrackingMode:MAUserTrackingModeFollow animated:YES]; // 追蹤使用者位置 [self.view addSubview:_mapView];
2.搜尋按鈕點選事件
// 搜尋按鈕事件 - (void)actionSearchAddress:(UIButton *)button { [self.view endEditing:YES]; // 結束編輯回收鍵盤 [[CustomActivityIndicator sharedActivityIndicator] startSynchAnimating]; [_mapView removeAnnotation:_annotation]; // 移除大頭針 //構造AMapGeocodeSearchRequest物件,address為必選項,city為可選項 AMapGeocodeSearchRequest *geo = [[AMapGeocodeSearchRequest alloc] init]; geo.address = _searchContentTF.text; //發起正向地理編碼 [_mapSearch AMapGeocodeSearch: geo]; }
3.高德地圖代理方法(3.0以上的高德SDK包含點選,長按等地圖手勢的代理方法)
#pragma mark - MAMapViewDelegate // 大頭針樣式 - (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id <MAAnnotation>)annotation { if ([annotation isKindOfClass:[ReGeocodeAnnotation class]]) { static NSString *pointReuseIndentifier = @"SearchAdressAnnotationView"; MAPinAnnotationView *annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndentifier]; if (annotationView == nil) { annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndentifier]; } annotationView.canShowCallout= YES; //設定氣泡可以彈出,預設為NO annotationView.animatesDrop = YES; //設定標註動畫顯示,預設為NO annotationView.draggable = YES; //設定標註可以拖動,預設為NO annotationView.pinColor = MAPinAnnotationColorPurple; // 新增點到數值中,便於改變時移除 // if (!_annotationsArray) { // _annotationsArray = [NSMutableArray array]; // } // [_annotationsArray addObject:annotation]; // _annotation = annotation; return annotationView; } return nil; } // 單擊地圖 - (void)mapView:(MAMapView *)mapView didSingleTappedAtCoordinate:(CLLocationCoordinate2D)coordinate { [self.view endEditing:YES]; } // 拖拽大頭針觸發方法 - (void)mapView:(MAMapView *)mapView annotationView:(MAAnnotationView *)view didChangeDragState:(MAAnnotationViewDragState)newState fromOldState:(MAAnnotationViewDragState)oldState { if (newState == MAAnnotationViewDragStateEnding) { _isSearchFromDragging = YES; CLLocationCoordinate2D coordinate = view.annotation.coordinate; self.annotation = view.annotation; [self searchReGeocodeWithCoordinate:coordinate]; } } // 長按觸發方法 - (void)mapView:(MAMapView *)mapView didLongPressedAtCoordinate:(CLLocationCoordinate2D)coordinate { [self.mapView removeAnnotation:_annotation]; _isSearchFromDragging = NO; [self searchReGeocodeWithCoordinate:coordinate]; }
4.長按和移動大頭針時呼叫逆地理編碼方法
// 逆地址編碼搜尋
- (void)searchReGeocodeWithCoordinate:(CLLocationCoordinate2D)coordinate
{
AMapReGeocodeSearchRequest *regeo = [[AMapReGeocodeSearchRequest alloc] init];
regeo.location = [AMapGeoPoint locationWithLatitude:coordinate.latitude longitude:coordinate.longitude];
regeo.requireExtension = YES;
[_mapSearch AMapReGoecodeSearch:regeo];
}
5.高德search的代理方法
#pragma mark - AMapSearchDelegate
//實現正向地理編碼的回撥函式
- (void)onGeocodeSearchDone:(AMapGeocodeSearchRequest *)request response:(AMapGeocodeSearchResponse *)response
{
if(response.geocodes.count == 0)
{
return;
} else {
// 通過AMapGeocodeSearchResponse物件處理搜尋結果, 只要一個位置
AMapGeocode *p = response.geocodes[0];
// NSLog(@"%f,,%f",p.location.latitude, p.location.longitude);
ReGeocodeAnnotation *pointAnnotation = [[ReGeocodeAnnotation alloc] init];
pointAnnotation.coordinate = CLLocationCoordinate2DMake(p.location.latitude, p.location.longitude);
pointAnnotation.title = _searchContentTF.text;
[_mapView addAnnotation:pointAnnotation];
_searchContentTF.text = pointAnnotation.title;
// 儲存點
_annotation = pointAnnotation;
[self.mapView selectAnnotation:self.annotation animated:YES];
// 改變地圖的中心點為大頭針的中心點
MACoordinateRegion theRegion = {{0.0, 0.0 }, { 0.0, 0.0 }};
theRegion.center = CLLocationCoordinate2DMake(p.location.latitude, p.location.longitude);
theRegion.span.longitudeDelta = 0.05f;
theRegion.span.latitudeDelta = 0.05f;
[_mapView setRegion:theRegion animated:YES];
}
[[CustomActivityIndicator sharedActivityIndicator] stopSynchAnimating];
}
// 逆地理編碼回撥.
- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response
{
if (response.regeocode != nil && _isSearchFromDragging == NO)
{
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(request.location.latitude, request.location.longitude);
ReGeocodeAnnotation *reGeocodeAnnotation = [[ReGeocodeAnnotation alloc] initWithCoordinate:coordinate reGeocode:response.regeocode];
[self.mapView addAnnotation:reGeocodeAnnotation];
_annotation = reGeocodeAnnotation;
_searchContentTF.text = reGeocodeAnnotation.title;
[self.mapView selectAnnotation:reGeocodeAnnotation animated:YES];
}
else /* from drag search, update address */
{
[self.annotation setAMapReGeocode:response.regeocode];
_searchContentTF.text = [NSString stringWithFormat:@"%@%@%@%@", response.regeocode.addressComponent.province?: @"", response.regeocode.addressComponent.city ?: @"", response.regeocode.addressComponent.district?: @"", response.regeocode.addressComponent.township?: @""];
[self.mapView selectAnnotation:self.annotation animated:YES];
}
}
6.ReGeocodeAnnotation是自定義的類,程式碼如下:
ReGeocodeAnnotation.h
#import <MAMapKit/MAMapKit.h>
#import <AMapSearchKit/AMapCommonObj.h>
@interface ReGeocodeAnnotation : NSObject <MAAnnotation>
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate reGeocode:(AMapReGeocode *)reGeocode;
@property (nonatomic, readonly, strong) AMapReGeocode *reGeocode;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
- (void)setAMapReGeocode:(AMapReGeocode *)reGerocode;
@end
ReGeocodeAnnotation.m
#import "ReGeocodeAnnotation.h"
@interface ReGeocodeAnnotation ()
@property (nonatomic, readwrite, strong) AMapReGeocode *reGeocode;
@property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;
@end
@implementation ReGeocodeAnnotation
@synthesize reGeocode = _reGeocode;
@synthesize coordinate = _coordinate;
- (void)setAMapReGeocode:(AMapReGeocode *)reGerocode
{
self.reGeocode = reGerocode;
[self updateContent];
}
- (void)updateContent
{
/* 包含 省, 市, 區以及鄉鎮. */
self.title = [NSString stringWithFormat:@"%@%@%@%@",
self.reGeocode.addressComponent.province?: @"",
self.reGeocode.addressComponent.city ?: @"",
self.reGeocode.addressComponent.district?: @"",
self.reGeocode.addressComponent.township?: @""];
/* 包含 社群,建築. */
// self.subtitle = [NSString stringWithFormat:@"%@%@",
// self.reGeocode.addressComponent.neighborhood?: @"",
// self.reGeocode.addressComponent.building?: @""];
}
#pragma mark - Life Cycle
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate reGeocode:(AMapReGeocode *)reGeocode
{
if (self = [super init])
{
self.coordinate = coordinate;
self.reGeocode = reGeocode;
[self updateContent];
}
return self;
}
@end
有時可能會需要修改地圖顯示範圍,方法如下:
- (void)figureMapRegion
{
if (_allPointArray.count == 1) { // 一個點
MACoordinateRegion theRegion = {{0.0, 0.0 }, { 0.0, 0.0 }};
theRegion.center = CLLocationCoordinate2DMake([_allPointArray[0][@"latitude"] doubleValue], [_allPointArray[0][@"longitude"] doubleValue]);
theRegion.span.longitudeDelta = 0.05f;
theRegion.span.latitudeDelta = 0.05f;
[_mapView setRegion:theRegion animated:YES];
}
if (_allPointArray.count > 1) { // 多個點
//構造多邊形資料物件
CLLocationCoordinate2D polylineCoords;
double maxLat = 0;
double maxLon = 0;
double minLat = 0;
double minLon = 0;
for (int i=0; i<_allPointArray.count; i++) {
NSDictionary *dic = _allPointArray[i];
polylineCoords.latitude = [dic[@"latitude"] doubleValue];
polylineCoords.longitude = [dic[@"longitude"] doubleValue];
if (i==0) {
maxLat=[dic[@"latitude"] doubleValue];
minLat=[dic[@"latitude"] doubleValue];
maxLon=[dic[@"longitude"] doubleValue];
minLon=[dic[@"longitude"] doubleValue];
} else {
if (maxLat<[dic[@"latitude"] doubleValue]) {
maxLat=[dic[@"latitude"] doubleValue];
}
if (minLat>[dic[@"latitude"] doubleValue]) {
minLat=[dic[@"latitude"] doubleValue];
}
if (maxLon<[dic[@"longitude"] doubleValue]) {
maxLon=[dic[@"longitude"] doubleValue];
}
if (minLon>[dic[@"longitude"] doubleValue]) {
minLon=[dic[@"longitude"] doubleValue];
}
}
}
// 設定地圖範圍及中心
[self setMapRegionAndCenterWithMaxLatitude:maxLat minLatitude:minLat maxLongitude:maxLon minLongitude:minLon];
}
}
// 設定地圖的範圍
- (void)setMapRegionAndCenterWithMaxLatitude:(double)maxLat minLatitude:(double)minLat maxLongitude:(double)maxLon minLongitude:(double)minLon
{
CLLocationCoordinate2D center = CLLocationCoordinate2DMake((maxLat+minLat)/2, (maxLon+minLon)/2);
MACoordinateSpan span = MACoordinateSpanMake((maxLat-minLat)*1.5, (maxLon-minLon)*1.5);
MACoordinateRegion regin = MACoordinateRegionMake(center, span);
[_mapView setRegion:regin animated:YES];
}