iOS 高德地图运动轨迹
关于运动轨迹,之前研究了一下,发现其实就是对地图定位的记录以及画线,以高德地图为例,高德地图封装了各种各样的方法且为中文注释,所以方法的易读性极高。废话不多说开始正题。
高德的SDK及相关说明文档请移步到高德官网:http://lbs.amap.com
申请相关的key,需要绑定对应的bundle id 。
我创建了一个用户定位的模型 UserLocation 用来储存定位得到的经纬度。本文还添加了改变高德地图原始小圆点的图标及地图截屏。
相关代码:
#import "ViewController.h"
#import <MAMapKit/MAMapKit.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
#import "UserLocation.h"
@interface ViewController ()
@property (nonatomic, strong) MAMapView *mapView;
@property (nonatomic, strong) MAAnnotationView *userLocationAnnotationView;
@property (nonatomic, strong) NSMutableArray *pointArray;
@property (nonatomic, strong) NSMutableArray *lineArray;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_pointArray = [NSMutableArray arrayWithCapacity:0];
_lineArray = [NSMutableArray arrayWithCapacity:0];
[AMapServices sharedServices].apiKey = @"ba0b6cd431e80e8d33fa1c9b3b9472cf"; ///地图需要v4.5.0及以上版本才必须要打开此选项(v4.5.0以下版本,需要手动配置info.plist)
[AMapServices sharedServices].enableHTTPS = YES;
//初始化地图
_mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
_mapView.delegate = self;
//把地图添加至view
[self.view addSubview:_mapView];
//开启定位
_mapView.showsUserLocation = YES;
//开启追踪用户的location更新模式
_mapView.userTrackingMode = MAUserTrackingModeFollow;
/* 标准地图 MAMapTypeStandard
卫星地图 MAMapTypeSatellite
夜景模式地图 MAMapTypeStandardNight
导航模式地图 MAMapTypeStandardNavi
*/
[self.mapView setMapType:MAMapTypeStandard];
//地图截屏按钮
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 20, 30, 30)];
[btn addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];
[btn setBackgroundColor:[UIColor redColor]];
[self.view addSubview:btn];
//展示截屏的视图
UIImageView *ima = [[UIImageView alloc] initWithFrame:self.view.bounds];
ima.hidden = YES;
ima.tag = 1;
[self.view addSubview:ima];
}
- (void)screenCapture
{
__block UIImage *screenshotImage = nil;
__block NSInteger resState = 0;
[self.mapView takeSnapshotInRect:self.view.bounds withCompletionBlock:^(UIImage *resultImage, NSInteger state) {
screenshotImage = resultImage;
resState = state; // state表示地图此时是否完整,0-不完整,1-完整 }];
__block UIImageView *ima = (UIImageView *)[self.view viewWithTag:1];
ima.hidden = NO;
ima.image = screenshotImage;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
ima.hidden = YES;
}); }
- (void)btnClicked{
[self screenCapture];
}
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation{
if ([annotation isKindOfClass:[MAUserLocation class]])
{
static NSString *userLocationStyleReuseIndetifier = @"userLocationStyleReuseIndetifier";
MAAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:userLocationStyleReuseIndetifier];
if (annotationView == nil)
{
annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:userLocationStyleReuseIndetifier];
}
annotationView.image = [UIImage imageNamed:@"21"]; self.userLocationAnnotationView = annotationView;
return annotationView;
}
return nil;
}
- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{
// 让定位箭头随着方向旋转
if (!updatingLocation && self.userLocationAnnotationView != nil)
{ [UIView animateWithDuration:0.1 animations:^{
double degree = userLocation.heading.trueHeading - self.mapView.rotationDegree; self.userLocationAnnotationView.transform = CGAffineTransformMakeRotation(degree * M_PI / 180.f);
UserLocation *u = [[UserLocation alloc] init];
u.latitude = userLocation.location.coordinate.latitude;
u.longitude = userLocation.location.coordinate.longitude;
if (_pointArray.count == 0) {
[_pointArray addObject:u];
}
else
{
UserLocation *u11 = [_pointArray lastObject];
MAMapPoint point1 = MAMapPointForCoordinate(CLLocationCoordinate2DMake(u11.latitude,u11.longitude)); MAMapPoint point2 = MAMapPointForCoordinate(CLLocationCoordinate2DMake(u.latitude,u.longitude)); CLLocationDistance distance = MAMetersBetweenMapPoints(point1,point2);
//判断两个点的距离 大于等于2米时才画下一条路径
if (distance >=2)
{
[_pointArray addObject:u];
UserLocation *u1 = [_pointArray objectAtIndex:_pointArray.count - 2];
UserLocation *u2 = _pointArray.lastObject; CLLocationCoordinate2D commonPolylineCoords[2]; commonPolylineCoords[0].latitude = u1.latitude; commonPolylineCoords[0].longitude = u1.longitude; commonPolylineCoords[1].latitude = u2.latitude; commonPolylineCoords[1].longitude = u2.longitude;
//构造折线对象
MAPolyline *commonPolyline = [MAPolyline polylineWithCoordinates:commonPolylineCoords count:2];
//在地图上添加折线对象
[_mapView addOverlay: commonPolyline];
//设置地图中心位置
_mapView.centerCoordinate = userLocation.location.coordinate;;
}
}
}];
}
}
#pragma mark - MAMapViewDelegate
- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[MAPolyline class]])
{
MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
polylineRenderer.lineWidth = 2.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;
return polylineRenderer;
}
return nil;
}
注:
1.请在网络良好的情况下测试 。
2.请开启定位权限
3.在TARGETS->Build Settings->Other Linker Flags 中添加-ObjC,C大写。