[iOS开发]高德地图SDK
Posted Billy Miracle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[iOS开发]高德地图SDK相关的知识,希望对你有一定的参考价值。
写在前面
最近学习了一下高德地图的SDK的使用,确实挺神奇的,下面进行一个小总结:
准备工作
首先,我们要把需要的库导入项目,我使用 CocoaPods 安装了 SDK:
Podfile内容(详情参见官方说明):
platform :ios, '7.0'
target 'MapTest' do
pod 'AMap3DMap'
pod 'AMapSearch'
pod 'AMapLocation'
pod 'AMapTrack'
end
其次,我们要为我们的项目获取一个key,它是在高德开放控制平台申请的。如何获取。
开始肝活
添加权限:
开启定位权限。
在 TARGETS->Singings & Capabilities 中:
开启后台定位。
把地图显示到自己的view上:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// Override point for customization after application launch.
[AMapServices sharedServices].apiKey = @"one’s key";
return YES;
[AMapServices sharedServices].enableHTTPS = YES;
_mapView = [[MAMapView alloc] initWithFrame: CGRectMake(0, 100, self.view.bounds.size.width, self.view.bounds.size.height - 200)];
//把地图添加至view
[self.view addSubview:_mapView];
这样地图就显示出来了。
此外,地图还可以有一系列的附加属性可供自定义,下面给出一些示例:
_mapView.showsIndoorMap = YES; //设置显示室内地图
_mapView.zoomLevel = 18; //设置缩放比例
_mapView.zoomEnabled = YES; //NO表示禁用缩放手势,YES表示开启
_mapView.rotateEnabled= NO; //NO表示禁用旋转手势,YES表示开启
[_mapView setShowsCompass:NO]; //是否显示自带的指南针:NO
(PS:iOS虚拟机的双指缩放手势是按住 option 键,参考博客)
显示自己的位置:
//如果您需要进入地图就显示定位小蓝点,则需要下面两行代码
_mapView.showsUserLocation = YES;
_mapView.userTrackingMode = MAUserTrackingModeFollow;
效果如图,我们已经出现在地图上啦,嘻嘻😁。
接下来,如果对于我们的代表:小蓝点 不太满意的话,我们可以对它进行自定义:
#pragma mark - 自定义UserLocationRepresentation
MAUserLocationRepresentation *r = [[MAUserLocationRepresentation alloc] init];
r.showsAccuracyRing = NO;//精度圈是否显示,默认YES
r.showsHeadingIndicator = NO;//是否显示方向指示(MAUserTrackingModeFollowWithHeading模式开启)。默认为YES
r.fillColor = [UIColor redColor];//精度圈 填充颜色, 默认 kAccuracyCircleDefaultColor
r.strokeColor = [UIColor blueColor];//精度圈 边线颜色, 默认 kAccuracyCircleDefaultColor
r.lineWidth = 2;//精度圈 边线宽度,默认0
r.enablePulseAnnimation = NO;//内部蓝色圆点是否使用律动效果, 默认YES
r.locationDotBgColor = [UIColor greenColor];//定位点背景色,不设置默认白色
r.locationDotFillColor = [UIColor grayColor];//定位点蓝色圆点颜色,不设置默认蓝色
r.image = [UIImage imageNamed:@"你的图片"]; //定位图标, 与蓝色原点互斥
[_mapView updateUserLocationRepresentation: r];
对它肆意妄为😈。
添加标记点:
#pragma mark - 添加标记点
MAPointAnnotation *pointAnnotation = [[MAPointAnnotation alloc] init];
pointAnnotation.coordinate = CLLocationCoordinate2DMake(34.154305,108.90217);
pointAnnotation.title = @"西安邮电大学";
pointAnnotation.subtitle = @"好地方";
[_mapView addAnnotation:pointAnnotation];
为了找到你心仪❤️的点,可以使用:高德坐标拾取器
接下来,我们可以对大头针进行自定义:
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id <MAAnnotation>)annotation
if ([annotation isKindOfClass:[MAPointAnnotation class]] && ![annotation isKindOfClass:[MAUserLocation class]])
static NSString *pointReuseIndentifier = @"pointReuseIndentifier";
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;
return annotationView;
return nil;
其实,我们的小蓝点也可能被修改,所以才需要加上if ([annotation isKindOfClass:[MAPointAnnotation class]] && ![annotation isKindOfClass:[MAUserLocation class]])
条件来筛选。效果如下:
运动轨迹:
我们在学校经常会被要求跑步,还记入成绩,那么我们今天也来模仿,写一下这种功能,记录跑步距离,与配速。
我们的需求有三个条件:记录跑步经过各点,记录跑步时间,记录跑步距离。
实时更新位置:
- (void)location
if([CLLocationManager locationServicesEnabled])
locationManager = [[AMapLocationManager alloc]init];
[locationManager setDelegate:self];
//是否允许后台定位。默认为NO。只在iOS 9.0及之后起作用。设置为YES的时候必须保证 Background Modes 中的 Location updates 处于选中状态,否则会抛出异常。由于iOS系统限制,需要在定位未开始之前或定位停止之后,修改该属性的值才会有效果。
[locationManager setAllowsBackgroundLocationUpdates:NO];
//指定定位是否会被系统自动暂停。默认为NO。
[locationManager setPausesLocationUpdatesAutomatically:NO];
//设定定位的最小更新距离。单位米,默认为 kCLDistanceFilterNone,表示只要检测到设备位置发生变化就会更新位置信息
[locationManager setDistanceFilter:5];
//设定期望的定位精度。单位米,默认为 kCLLocationAccuracyBest
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
//开始定位服务
[locationManager startUpdatingLocation];
实现MAMapViewDelegate的函数:
#pragma mark - MAMapViewDelegate
- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation
_currentLocation = userLocation;
// NSLog(@"位置更新");
// NSLog(@"当前位置:%f,%f", userLocation.location.coordinate.latitude, userLocation.location.coordinate.longitude);
if (_longitudeArray.count == 0)
//更新距离信息
[self updateLength];
/*添加点信息*/
else
/*取轨迹最后一点信息,计算距离*/
//判断两个点的距离 大于等于1米时才画下一条路径
if (distance >= 1)
_trackLength = [NSNumber numberWithDouble:_trackLength.doubleValue + distance];
[self updateLength];
//构造commonPolylineCoords
//构造折线对象
MAPolyline *commonPolyline = [MAPolyline polylineWithCoordinates:commonPolylineCoords count:2];
//在地图上添加折线对象
_isRoute = NO;
[_mapView addOverlay: commonPolyline];
此外,我还添加了定时器。让配速一秒钟刷新一次:
//更新配速
- (void)updateSpeed
NSDate *currentDate = [NSDate date];
// 时间2与时间1之间的时间差(秒
double intervalTime = [currentDate timeIntervalSinceDate:_startDate];
if (_trackLength.doubleValue < 1)
_speedLabel.text = @"0分0秒";
else
_speedLabel.text = [NSString stringWithFormat:@"%d分%d秒", (int)(intervalTime / 60 / _trackLength.doubleValue * 1000), (int)((intervalTime / 60 / _trackLength.doubleValue * 1000 - (int)(intervalTime / 60 / _trackLength.doubleValue * 1000)) * 60)];
效果如图:
搜索功能:
搜索可以通过当前位置搜索附近内容,也可以通过输入关键字查找位置。
可以使用提供的 searchController 的 searchBar。
_searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
_searchController.searchBar.delegate = self;
也可以使用自己创建的 UITextField。
//搜索框激活时,使用提示搜索
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
//发起输入提示搜索
AMapInputTipsSearchRequest *tipsRequest = [[AMapInputTipsSearchRequest alloc] init];
//关键字
tipsRequest.keywords = _searchController.searchBar.text;
//城市
tipsRequest.city = _currentCity;
//执行搜索
[_search AMapInputTipsSearch: tipsRequest];
//实现输入提示的回调函数
- (void)onInputTipsSearchDone:(AMapInputTipsSearchRequest*)request response:(AMapInputTipsSearchResponse *)response
if(response.tips.count == 0)
return;
//通过AMapInputTipsSearchResponse对象处理搜索结果
//先清空数组
[self.searchList removeAllObjects];
for (AMapTip *p in response.tips)
//把搜索结果存在数组
[self.searchList addObject:p];
_isSelected = NO;
//刷新表视图
[self.searchTableView reloadData];
这样就可以实现搜索功能并把数据显示在屏幕上啦:
除了输入搜索目的地,我们还可以进行周边搜索。
- (void)searchAction
//初始化检索对象
_search = [[AMapSearchAPI alloc] init];
_search.delegate = self;
//构造AMapPOIAroundSearchRequest对象,设置周边请求参数
AMapPOIAroundSearchRequest *request = [[AMapPOIAroundSearchRequest alloc] init];
//当前位置
request.location = [AMapGeoPoint locationWithLatitude:_currentLocation.coordinate.latitude longitude:_currentLocation.coordinate.longitude];
//关键字
// request.keywords =
// types属性表示限定搜索POI的类别,默认为:餐饮服务|商务住宅|生活服务
// POI的类型共分为20种大类别,分别为:
// 汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|
// 医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|
// 交通设施服务|金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施
// request.types = @"餐饮服务|生活服务";
request.radius = 5000;//查询半径,范围:0-50000,单位:米 [default = 3000]
request.sortrule = 0;
request.requireExtension = YES;
//发起周边搜索
[_search AMapPOIAroundSearch:request];
//实现POI搜索对应的回调函数
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
if(response.pois.count == 0)
return;
//通过 AMapPOISearchResponse 对象处理搜索结果
[self.dataList removeAllObjects];
for (AMapPOI *p in response.pois)
//搜索结果存在数组
[self.dataList addObject:p];
_isSelected = YES;
[self.searchTableView reloadData];
这样以来,我们就可以对周边特定范围内的特定种类的地点进行搜索,效果如下:
路线的搜索与显示:
为了搜索路线,我们要给出起始点与终点。用它们来查找路线。
AMapDrivingRouteSearchRequest *navi = [[AMapDrivingRouteSearchRequest alloc] init];
/* 出发点. */
navi.origin = [AMapGeoPoint locationWithLatitude:self.currentLocation.coordinate.latitude longitude:self.currentLocation.coordinate.longitude];
/* 目的地. */
navi.destination = [AMapGeoPoint locationWithLatitude:poi.location.latitude longitude:poi.location.longitude];
navi.requireExtension = YES;
//发起路线规划
[self.searchAPI AMapDrivingRouteSearch:navi];
搜索完成调用函数:
- (void)onRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapRouteSearchResponse *)response
if (response.route == nil)
return;
if (response.count > 0)
//直接取第一个方案
AMapPath *path = response.route.paths[0];
//移除旧折线对象
[_mapView removeOverlay:_polyline];
//构造折线对象
_polyline = [self polylinesForPath:path];
//添加新的遮盖,然后会触发代理方法(- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id<MAOverlay>)overlay)进行绘制
_isRoute = YES;
[_mapView addOverlay:_polyline];
[_mapView showOverlays:@[_polyline] animated:NO];
其中,[_mapView showOverlays:@[_polyline] animated:NO];
这句话是为了能够让地图大小自适应,显示整条路线。
路线解析与坐标解析方法:
//路线解析
- (MAPolyline *)polylinesForPath:(AMapPath *)path
if (path == nil || path.steps.count == 0)
return nil;
NSMutableString *polylineMutableString = [@"" mutableCopy];
for (AMapStep *step in path.steps)
[polylineMutableString appendFormat:@"%@;",step.polyline];
NSUInteger count = 0;
CLLocationCoordinate2D *coordinates = [self coordinatesForString:polylineMutableString coordinateCount:&count parseToken:@";"];
MAPolyline *polyline = [MAPolyline polylineWithCoordinates:coordinates count:count];
free(coordinates);
coordinates = NULL;
return polyline;
//解析经纬度
- (CLLocationCoordinate2D *)coordinatesForString:(NSString *)string coordinateCount:(NSUInteger *)coordinateCount parseToken:(NSString *)token
if (string == nil)
return NULL;
if (token == nil)
token = @",";
NSString *str = @"";
if (![token isEqualToString:@","])
str = [string stringByReplacingOccurrencesOfString:token withString:@","];
else
str = [NSString stringWithString:string];
NSArray *components = [str componentsSeparatedByString:@","];
NSUInteger count = [components count] / 2;
if (coordinateCount != NULL)
*coordinateCount = count;
CLLocationCoordinate2D *coordinates = (CLLocationCoordinate2D*)malloc(count * sizeof(CLLocationCoordinate2D));
for (int i = 0; i < count; i++)
coordinates[i].longitude = [[components objectAtIndex:2 * i] doubleValue];
coordinates[i].latitude = [[components objectAtIndex:2 * i + 1] doubleValue];
return coordinates;
在绘制方法中自定义折线形状:
MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
if (_isRoute)
polylineRenderer.lineWidth = 8.f;
polylineRenderer.strokeColor = [UIColor systemGreenColor];
else
polylineRenderer.lineWidth = 5.f;
polylineRenderer.strokeColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:0.6];
polylineRenderer.lineJoinType = kMALineJoinRound;
polylineRenderer.lineCapType = kMALineCapRound;
效果:
小结:
博主萌新在写这个学习小demo时遇到过很多问题,但都有努力的去解决,希望我的博客可以帮助到大家,谢谢大家💖,喜欢的话可以点个赞和关注吧,我们一起学习,一起进步。
以上是关于[iOS开发]高德地图SDK的主要内容,如果未能解决你的问题,请参考以下文章