最近稍微学了学iOS调用高德的SDK,就随便做做笔记。注意:本篇博客基于高德地图SDK的3D地图来写的,若使用的是2D地图可能有的方法可能有所不同,比如自定义定位蓝点之类的。
一、准备工作:
具体的准备工作高德的SDK的入门指南上将步骤都一一给出了,具体看看:iOS 高德地图-SDK
下面那我就大概说说步骤:
1.获取最新版的XCode
Xcode版本至少在8.0之上。
2.获取CocoaPods
有这个环境的就可以不用管,没有的话可以看看这两篇:2021年CocoaPods安装方法 和 Getting Started。
3.使用CocoaPods安装SDK
- 如果该程序是第一次使用CocoaPods的话,就先使用下面代码创建一个工程:
$ touch Podfile
- 编辑Podfile文件
platform :ios, '15.0' //手机的系统,比它高的版本也可以
target '调用地图' do //这里引号里是你自己程序的名字
pod 'AMap2DMap' //2D地图,2D地图不可以和3D一起使用,将2改为3就是3D地图了
pod 'AMapSearch' //搜索功能
end
- 安装SDK
$pod install --repo-update
- 如果不是最新版的SDK,使用下面指令更新
pod repo update
- 重启Xcode
记得打开的一定要是这样的程序:
4.获取高德Key
在上述工作做完了之后你的程序还不能够使用高德的SDK,这里我们需要为我们的项目获取一个key,它是在高德开放控制平台申请的。
申请方法:获取Key
5.Hello AMap
- 配置Info.plist 文件
在Info
中添加:
NSAppTransportSecurity
NSAllowsArbitraryLoads
- 配置高德Key至AppDelegate.m文件
在你程序的AppDelegate.m
文件中的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
添加:
[AMapServices sharedServices].apiKey = @"你的Key";
- 加载地图
(1)加头文件
#import <MAMapKit/MAMapKit.h>
(2)构造MAMapView对象
MAMapView *_mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
(3)将MAMapView添加到Subview中
[self.view addSubview:_mapView];
6.连接iOS设备
7.开肝
以上就是使用高德地图SDK的一些准备工作,其他的可以自己去iOS 地图SDK了解了解。
二、高德SDK基础操作:
基于3D地图的使用!!!
1.配置头文件:
#import <MAMapKit/MAMapKit.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
2.显示地图:
注意: 若初始化地图并添加到View上后并没有显示到视图上的话,并且出现
Error Domain=AMapFoundationErrorPrivacyShowUnknow Code=555570 “(null)” UserInfo={info=使用MAMapKit3D SDK 功能前请设置隐私权政策是否弹窗告知用户}
该错误,那么请在初始化地图之前添加下面两行代码:
//检查隐私合规
[MAMapView updatePrivacyShow:AMapPrivacyShowStatusDidShow privacyInfo:AMapPrivacyInfoStatusDidContain];
[MAMapView updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree];
详细原因请看高德地图给的开发者注意事项。
//地图需要v4.5.0及以上版本才必须要打开此选项(v4.5.0以下版本,需要手动配置info.plist)
[[AMapServices sharedServices] setEnableHTTPS:YES];
//初始化地图
self.showMapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 0, myWidth, myHeight)];
[self.view addSubview:self.showMapView];
地图的控件设置方法:
(1)显示室内地图:
这个只对3D地图有用,2D没有室内地图
self.showMapView.showsIndoorMap = YES; //YES:显示室内地图;NO:不显示;
(2)更改logo位置:
logo高德地图
只能移动不能移除,同时logo的大小也是不能更改的,它是一个只读属性。
self.showMapView.logoCenter = CGPointMake(CGRectGetWidth(self.view.bounds) - 55, 450);
(3)指南针控件:
这个指南针就是高德地图右上角的那个指南针,并且这个指南针也是只能改变位置,不能改变大小,大小是一个只读属性,但是可以选择显示或者不显示。
self.showMapView.showsCompass = YES; //设置成NO表示关闭指南针;YES表示显示指南针
self.showMapView.compassOrigin = CGPointMake(self.showMapView.compassOrigin.x, 222); //设置指南针位置
(4)比例尺控件:
比例尺也是只能改位置不能改大小,大小为只读属性。
self.showMapView.showsScale = YES; //设置成NO表示不显示比例尺;YES表示显示比例尺
self.showMapView.scaleOrigin = CGPointMake(self.showMapView.scaleOrigin.x, 222); //设置比例尺位置
3.显示定位蓝点:
//进入地图就显示定位小蓝点
self.showMapView.showsUserLocation = YES;
self.showMapView.userTrackingMode = MAUserTrackingModeFollow;
注意: 在加载定位蓝点时一定要将下面的三个key都添加在Info中:
Privacy - Location Always Usage Description
始终允许访问位置信息
Privacy - Location Usage Description
永不允许访问位置信息
Privacy - Location When In Use Usage Description
使用应用期间允许访问位置信息
自定义定位蓝点:
自定义蓝点我吃了不少亏,因为我一开始使用的是2D地图,自定义一直不成功,也不知道为什么,后来偶然看到一篇博客说这个只对3D地图有用,我又专门去看了人家的SDK说明,人家果然在一开始说过,哎,白白浪费我好几天。。。。。。下面就是人家的说明:
那么现在就可以根据自己的需求对定位蓝点进行相应的修改了。
- 初始化 MAUserLocationRepresentation 对象:
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:@"你的图片"]; ///定位图标, 与蓝色原点互斥
- 执行:
[self.mapView updateUserLocationRepresentation:r];
三、绘制运动轨迹:
1.大体思路:
绘制运动轨迹想必大家都不陌生吧,毕竟经常饱受跑步的折磨,这里我就大概讲讲绘制运动轨迹的思路吧,首先,因为是在一个地图上,那么确认一个位置一定是要一个坐标才能确认的,所以我们就可以想到获取当点位置的经纬度,这不就确定下来坐标了吗,对没错,这是第一步,其次,因为你是在运动时的时候你的坐标位置不停在改变,这就又用到OC中的定时器了,每隔多少秒获取一次位置,然后保存到数组不就可以了,那么基础的思路有了,万事具备只欠东风了,最终,我们通过高德地图给我们的绘制折线这个方法,将最后记录的点和最后一个点之前的点获取到,绘制他们两个位置的折线,这不就大功告成了。
小问题:
思路现在有了,那么是时候考虑考虑程序后续启动运行的问题了:
(1)一开始启动定时器,那个数组中只有没有位置信息,通过第一次定时器函数之后才有了第一个位置信息,这没办法设计一个统一的算法啊,咋办?
这里我们不妨使用一个标识flag,用于判断是不是第一次使用这个定时器函数,如果是第一次,那么我们只添加数据不绘制折线,之后的每次一不就相同了!!!就可以使用同一个算法了!!!
(2)因为不停的向经纬度数组里添加位置信息,那么时间越长是不是就占用的内存就越多了???
通过我们之前的思路,我们可以知道,每次我们都是使用最后两个坐标点进行折线的绘制,那么其他的坐标信息是不是就没有什么用处了!!所以我们可以将其他位置信息删除掉,每次就只保留最后两个坐标位置!!!
好了,思路有了,问题也解决了,那就话不多说,肝着!!!
2.开肝:
ShowMapViewController.h
#import <UIKit/UIKit.h>
#import <MAMapKit/MAMapKit.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ShowMapViewController : UIViewController<MAMapViewDelegate>
@property (nonatomic, strong) MAMapView *showMapView; //创建地图变量
//两个数组用来存放经纬度
@property (nonatomic, strong) NSMutableArray *arrayOfLongitude; //精度
@property (nonatomic, strong) NSMutableArray *arrayOfLatitude; //纬度
//定时器
@property (nonatomic, strong) NSTimer *addDataTimer;
//标识,用于判断是否为第一次记录数据
@property (nonatomic, assign) NSInteger addFlag;
@end
NS_ASSUME_NONNULL_END
ShowMapViewController.m
#import "ShowMapViewController.h"
#define myWidth [UIScreen mainScreen].bounds.size.width
#define myHeight [UIScreen mainScreen].bounds.size.height
@interface ShowMapViewController ()
@end
@implementation ShowMapViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor orangeColor];
self.title = @"地图";
self.navigationController.navigationBar.translucent = NO;
self.navigationController.navigationBar.backgroundColor = [UIColor blueColor];
//检查隐私合规
[MAMapView updatePrivacyShow:AMapPrivacyShowStatusDidShow privacyInfo:AMapPrivacyInfoStatusDidContain];
[MAMapView updatePrivacyAgree:AMapPrivacyAgreeStatusDidAgree];
[self showMap];
}
- (void)showMap {
//初始化
self.arrayOfLongitude = [[NSMutableArray alloc] init];
self.arrayOfLatitude = [[NSMutableArray alloc] init];
self.addFlag = 0;
//地图需要v4.5.0及以上版本才必须要打开此选项(v4.5.0以下版本,需要手动配置info.plist)
[[AMapServices sharedServices] setEnableHTTPS:YES];
//初始化地图
self.showMapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 0, myWidth, myHeight)];
self.showMapView.delegate = self;
//进入地图就显示定位小蓝点
self.showMapView.showsUserLocation = YES;
//定位用户位置的模式
self.showMapView.userTrackingMode = MAUserTrackingModeFollow;
//缩放级别(默认3-19,有室内地图时为3-20)
self.showMapView.zoomLevel = 19;
[self.view addSubview:self.showMapView];
//启动定时器,获取当前位置经纬度点
self.addDataTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(addDataForArray) userInfo:@"shuaigege" repeats:YES];
}
//使用定时器来添加当前位置经纬度点,用来绘制折线
- (void)addDataForArray {
//精度
NSNumber *tempLongitude = [NSNumber numberWithDouble:self.showMapView.userLocation.coordinate.longitude];
//纬度
NSNumber *tempLatitude = [NSNumber numberWithDouble:self.showMapView.userLocation.coordinate.latitude];
[self.arrayOfLongitude addObject:tempLongitude];
[self.arrayOfLatitude addObject:tempLatitude];
if (self.addFlag == 1) {
//下方为绘制折线的代码(添加两个点,然后在两个点间绘制折线(也可以添加多个点,在多个点中绘制折线))
CLLocationCoordinate2D commonPolylineCoords[2];
//添加的第一个经纬度点
commonPolylineCoords[0].latitude = [self.arrayOfLatitude[0] doubleValue];
commonPolylineCoords[0].longitude = [self.arrayOfLongitude[0] doubleValue];
//添加的第二个经纬度点
commonPolylineCoords[1].latitude = [self.arrayOfLatitude[1] doubleValue];
commonPolylineCoords[1].longitude = [self.arrayOfLongitude[1] doubleValue];
//构造折线对象
MAPolyline *commonPolyline = [MAPolyline polylineWithCoordinates:commonPolylineCoords count:2];
//在地图上添加折线对象
[self.showMapView addOverlay:commonPolyline];
[self.arrayOfLongitude removeObjectAtIndex:0];
[self.arrayOfLatitude removeObjectAtIndex:0];
}
self.addFlag = 1;
}
//设置折线样式
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id<MAOverlay>)overlay {
if ([overlay isKindOfClass:[MAPolyline class]]) {
MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
polylineRenderer.lineWidth = 8.f;
polylineRenderer.strokeColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.6];
polylineRenderer.lineJoinType = kMALineJoinRound;
polylineRenderer.lineCapType = kMALineCapRound;
return polylineRenderer;
}
return nil;
}
@end
好了,这就是高德地图SDK的基础用法了,如果你就觉得就单单记录一个路线图不过瘾的话,那么你也可以自己试试其他高端操作,做个箭步趣跑mini版,那么思路就很简单了,都是位置的数据的转换,现在你的位置有了,那是不是就可以通过两个经纬度点来计算出距离?距离有了,那么你是不是可以再通过一个变量来记录时间,每次调用一次定时器都是相同的时间间隔,就自己看着加,最后进行一个数据的转换和计算展示到屏幕上,这不就箭步趣跑mini版大功告成!!!哈哈哈哈哈