You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

840 lines
33 KiB

//
// TrackInfoViewController.m
// watch
//
// Created by xTT on 2017/7/21.
// Copyright © 2017xTT. All rights reserved.
//
#import "TrackInfoViewController.h"
#import "CustomAnnotationView.h"
#import "MKPointAnnotation+NewTemp.h"
//高德
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapSearchKit/AMapSearchKit.h>
#define kAnimationDuration 3
#define kSpeed 50 // 每秒多少像素
//关键帧旋转动画
#define RotationAnimationKey @"transform.rotation.z"
//关键帧位移动画
#define PositionAnimationKey @"position"
//关键帧划线动画
#define StrokeEndAnimationKey @"strokeEnd"
#import "TracingPoint.h"
#import "Util.h"
@interface TrackInfoViewController ()<CAAnimationDelegate,MKMapViewDelegate,AMapSearchDelegate>
{
//当前选中的 位置
Locate *curLocate;
}
//动画持续的时间 (不超过5) 时速 每秒 320
@property(nonatomic,assign) NSTimeInterval durationTime;
// 路线动画
@property(nonatomic,strong) CAAnimation *shapeLayerAnimation;
// 头部光点动画
@property(nonatomic,strong) CAKeyframeAnimation *headLayerAnimation;
@property(nonatomic,assign) NSInteger currentIndex ;
//路径点的指针数组
@property(nonatomic,assign) CGPoint *pathPoints;
//路径点的指针数组
@property(nonatomic,strong) NSMutableArray <TracingPoint *>*pathPointsModels;
// angele数组 每个点的指向
@property(nonatomic,strong) NSMutableArray <NSNumber *>*angeleValues;
@property(nonatomic,assign) double SumJuli;
@property(nonatomic,strong) MKPolyline *routeLine;
@property(nonatomic,strong) MKPolylineRenderer *routeLineView;
@property(nonatomic,strong) NSMutableArray<MKPointAnnotation*>* pointAnnotationArr;
//
@property(nonatomic,strong) NSArray *animations;
@property(nonatomic,strong) NSArray *juliArr;
/**
轨迹回放的layer
*/
@property(nonatomic,strong) CAShapeLayer * shapeLayer;
/**
头部的光点
*/
//@property(nonatomic,strong) CAShapeLayer * headView;
@property(nonatomic,strong) UIImageView * headView;
@property(nonatomic,strong) NSArray<UIBezierPath*>* beziePaths;
/**
轨迹回放图层
*/
@property(nonatomic,strong) UIView *trackView;
@property (nonatomic, strong) AMapSearchAPI *searchAPI;
@end
@implementation TrackInfoViewController
- (NSMutableArray *)mapPoints{
if (!_mapPoints) {
_mapPoints = [[NSMutableArray alloc] init];
}
return _mapPoints;
}
-(NSMutableArray *)pointAnnotationArr{
if(!_pointAnnotationArr){
_pointAnnotationArr = [NSMutableArray array];
}
return _pointAnnotationArr;
}
-(UIView *)trackView{
if(!_trackView){
_trackView = [[UIView alloc] initWithFrame: self.mapView.bounds];
_trackView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.1];
[self.mapView addSubview:_trackView];
}
return _trackView;
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
//做一些必要的清除
self.startAndStopBtn.selected = NO;
[self startAndStopBtnAction:self.startAndStopBtn];
if(self.headView){
[self.headView.layer removeAllAnimations];
self.headView = nil;
}
if(self.pathPoints){
free(self.pathPoints);
self.pathPoints = nil;
}
[self.mapView removeFromSuperview];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.zx_hideBaseNavBar = YES;
self.mapView.userInteractionEnabled = NO;
self.mapView.delegate = self;
//禁止旋转
self.mapView.rotateEnabled = NO;
self.searchAPI = [[AMapSearchAPI alloc] init];
self.searchAPI.delegate = self;
self.startAndStopBtn.layer.masksToBounds = YES;
self.startAndStopBtn.layer.cornerRadius = 10;
[self.startAndStopBtn addTarget:self action:@selector(startAndStopBtnAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view bringSubviewToFront: self.startAndStopBtn];
//放大和缩小 VIew
self.zoomBtnView.layer.cornerRadius = 10;
self.zoomBtnView.layer.masksToBounds = YES;
}
//MARK: 重新加载地图轨迹数据
- (void)loadWithInfoTrack:(Track*)track Back:(BlockCall)blockCall{
self.startAndStopBtn.selected = NO;
[self startAndStopBtnAction:self.startAndStopBtn];
self.title = track.date;
[self.mapView removeAnnotations:self.pointAnnotationArr];
[self.mapView removeOverlay:self.routeLine];
[self.mapPoints removeAllObjects];
self.mapPoints = nil;
self.trackView = nil;
self.routeLine = nil;
self.routeLineView = nil;
self.pointAnnotationArr = nil;
[self.headView removeFromSuperview];
self.headView = nil;
WEAKSELF
[track getTrackInfoSuccess:^(NSMutableArray *arr) {
[weakSelf.mapPoints addObjectsFromArray:arr];
[weakSelf addLocate:arr];
if(arr.count>1){
weakSelf.startAndStopBtn.selected = YES;
[weakSelf startAndStopBtnAction:weakSelf.startAndStopBtn];
}
//默认选中 起点
CustomAnnotationView *tempView = [CustomAnnotationView new];
tempView.annotation = weakSelf.pointAnnotationArr.lastObject;
[weakSelf mapView:weakSelf.mapView didSelectAnnotationView:tempView];
if(blockCall){
blockCall();
}
} failure:^{
if(blockCall){
blockCall();
}
}];
}
//缩小地图
- (IBAction)subtractBtnAction:(id)sender {
if(!self.startAndStopBtn.isSelected){
return;
}
//设置地图范围
//设置中心点为当前地图范围的中心点
CLLocationCoordinate2D center = self.mapView.region.center;
//设置跨度为当前地图范围的跨度 * 比例系数
MKCoordinateSpan span = MKCoordinateSpanMake(self.mapView.region.span.latitudeDelta * 2, self.mapView.region.span.longitudeDelta * 2);
//设置范围
@try {
MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
xLog(@"span %@",[NSValue valueWithMKCoordinateSpan:span])
xLog(@"center %@",[NSValue valueWithMKCoordinate:center])
[self.mapView setRegion: region animated:YES];
} @catch (NSException *exception) {
xLog(@"error: %@",exception.description);
} @finally {
}
}
//放大地图
- (IBAction)addZoomBtnAction:(id)sender {
if(!self.startAndStopBtn.isSelected){
return;
}
// 设置范围
// 设置中心点
CLLocationCoordinate2D center = self.mapView.region.center;
// 设置跨度 : 跨度变小,地图显示缩大 (地图的范围跨度 * 比例系数)
MKCoordinateSpan span = MKCoordinateSpanMake(self.mapView.region.span.latitudeDelta * 0.5, self.mapView.region.span.longitudeDelta * 0.5);
//设置地图范围
[self.mapView setRegion:MKCoordinateRegionMake(center, span) animated:YES];
}
-(void)startAndStopBtnAction:(UIButton *)sender{
if(sender.isSelected){
[self.mapView removeAnnotations:self.pointAnnotationArr];
[self.mapView removeOverlay:self.routeLine];
self.currentIndex = 0;
//经纬度的区域坐标
if(self.routeLine){
MKMapRect mapShowRect = [self.routeLine boundingMapRect];
xLog(@"停止按钮:mapShowRect X: %f Y:%f Width: %f, Height: %f", mapShowRect.origin.x,mapShowRect.origin.y,mapShowRect.size.width,mapShowRect.size.height);
//显示区域
[self.mapView setVisibleMapRect:mapShowRect edgePadding:UIEdgeInsetsMake(50, 50, 50, 50) animated:NO];
}
[self initShapeLayerWithPath:[self pathForPoints:self.pathPoints count:self.pointAnnotationArr.count]];
}else{
// [self.mapView removeAnnotations:self.pointAnnotationArr];
// [self.mapView removeOverlay:self.routeLine];
[self.trackView removeFromSuperview];
self.trackView = nil;
self.currentIndex = 0;
[self.mapView addAnnotations:self.pointAnnotationArr];
}
[sender setSelected:!sender.isSelected];
self.mapView.userInteractionEnabled = sender.isSelected;
}
#pragma mark - 构造shapeLayer
- (void)initShapeLayerWithPath:(CGPathRef)path{
if(_shapeLayer){
[self.shapeLayer removeAllAnimations];
[self.shapeLayer removeFromSuperlayer];
[self.headView.layer removeAllAnimations];
[self.headView.layer removeFromSuperlayer];
[self.headView removeFromSuperview];
self.shapeLayer = nil;
self.headView = nil;
}
self.shapeLayer = [[CAShapeLayer alloc] init];
self.shapeLayer.frame = self.trackView.bounds;
self.shapeLayer.frame = self.mapView.bounds;
self.shapeLayer.strokeColor = mainColor.CGColor;
self.shapeLayer.fillColor = [UIColor clearColor].CGColor;
self.shapeLayer.lineJoin = kCALineJoinRound;
self.shapeLayer.lineCap = kCALineCapRound;
self.shapeLayer.lineWidth = 3;
self.shapeLayer.path = path;
self.shapeLayer.lineDashPhase = 10;
NSArray *arr = @[@(10),@(10)];
self.shapeLayer.lineDashPattern = arr;
self.headView = [[UIImageView alloc] init];
self.headView.frame = CGRectMake(-20, -20, 10, 10);
self.headView.backgroundColor = [UIColor whiteColor];
self.headView.layer.cornerRadius = 5;
self.headView.layer.masksToBounds = YES;
// self.headView.image = [UIImage imageNamed:@"icon_enter_the_footprint"];
if(self.angeleValues.count>1){
self.headView.transform = CGAffineTransformMakeRotation(self.angeleValues[self.angeleValues.count-1].doubleValue);
}
[self.trackView.layer addSublayer:self.shapeLayer];
[self.trackView.layer addSublayer: self.headView.layer];
self.shapeLayerAnimation = [self constructShapeLayerAnimation];
self.shapeLayerAnimation.delegate = self;
self.shapeLayerAnimation.removedOnCompletion = NO;
self.shapeLayerAnimation.fillMode = kCAFillModeForwards;
[self.shapeLayer addAnimation:self.shapeLayerAnimation forKey:@"shape"];
self.animations = [self constructHeadLayerAnimationWithBeziePaths:self.beziePaths];
if(self.animations.count != 0){
self.headLayerAnimation = self.animations[self.currentIndex];
self.headLayerAnimation.removedOnCompletion = NO;
self.headLayerAnimation.delegate = self;
[self.headView.layer addAnimation:self.headLayerAnimation forKey:[NSString stringWithFormat:@"headPosition%d",self.currentIndex]];
// [self.mapView addAnnotation:self.pointAnnotationArr.lastObject];
[self addTrackViewPoint:self.pathPoints[0] Type:0 Angle:0];
}
}
//MARK: 动画的代理方法 ----------CAAnimationDelegate------------
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
if([anim isKindOfClass:[CABasicAnimation class]]){
if(self.routeLine){
[self.mapView addOverlay:self.routeLine];
}
}
if([anim isKindOfClass:[CAKeyframeAnimation class]]){
self.currentIndex++;
if (self.currentIndex <self.pointAnnotationArr.count){
MKPointAnnotation * tempAnn = (MKPointAnnotation *)[[self.pointAnnotationArr reverseObjectEnumerator] allObjects][self.currentIndex];
CustomAnnotationView * tempView = [CustomAnnotationView new];
tempView.annotation = tempAnn;
[self mapView:self.mapView didSelectAnnotationView:tempView];
}
if(self.currentIndex >= self.animations.count){
self.currentIndex = 0;
if(self.pathPoints){
[self addTrackViewPoint:self.pathPoints[self.pointAnnotationArr.count-1] Type:2 Angle:0];
[self.headView.layer removeFromSuperlayer];
if(!self.startAndStopBtn.isSelected){
[self startAndStopBtnAction:self.startAndStopBtn];
}
}
return;
}
CAKeyframeAnimation *nextAnim = self.animations[self.currentIndex];
nextAnim.removedOnCompletion = NO;
nextAnim.delegate = self;
// [self.headView addAnimation:nextAnim forKey:[NSString stringWithFormat:@"headPosition%d",currentIndex]];
[self.headView.layer addAnimation:nextAnim forKey:@"headPosition"];
if(self.pathPoints){
CGPoint currentPoint = self.pathPoints[self.currentIndex];
if (self.currentIndex == 0){
//第一
[self addTrackViewPoint:currentPoint Type:0 Angle:0];
double angle = self.angeleValues[self.angeleValues.count-1].doubleValue;
self.headView.transform = CGAffineTransformMakeRotation(angle);
}else if(self.currentIndex == self.pointAnnotationArr.count-1){
//最后一个
[self addTrackViewPoint:currentPoint Type:2 Angle:0];
}else{
NSInteger tempIndex = self.angeleValues.count-self.currentIndex-1;
if(tempIndex < 0){
tempIndex = 0;
}
double angle = self.angeleValues[tempIndex].doubleValue;
// if(self.currentIndex == 1){
// self.headView.transform = CGAffineTransformMakeRotation(angle);
// }
[self addTrackViewPoint:currentPoint Type:1 Angle:angle ];
self.headView.transform = CGAffineTransformMakeRotation(angle);
}
}
}
}
//MARK: 添加 在TrackView 上的点
/**
添加 在TrackView 上的点
@param centerPoint 点的坐标
@param type 类型 起点 0 平常 1 终点 2
@param angle 图标旋转的 弧度
*/
-(void)addTrackViewPoint:(CGPoint)centerPoint Type:(int)type Angle:(double)angle{
if(!_trackView){
return;
}
CGFloat Width = 12;
CGFloat height = 12;
__block UIImageView *view = [UIImageView new];
view.contentMode = UIViewContentModeScaleAspectFit;
switch (type) {
case 0:
view.frame = CGRectMake(0, 0, 30, 30);
view.image = [UIImage imageNamed:@"起点"];
view.center = CGPointMake(centerPoint.x, centerPoint.y-15);
break;
case 1:
view.frame = CGRectMake(0, 0, Width,height);
view.image = [UIImage imageNamed:@"icon_enter_the_footprint"];
// xLog(@"radian: %f", angle);
view.transform = CGAffineTransformRotate(view.transform, angle);
view.center = centerPoint;
break;
case 2:
view.frame = CGRectMake(0, 0, 30, 30);
view.image = [UIImage imageNamed:@"终点"];
view.center = CGPointMake(centerPoint.x, centerPoint.y-15);
break;
default:
break;
}
[_trackView addSubview:view];
//自定义动画
// view.transform = CGAffineTransformScale(view.transform, 0.5, 0.5);
// // 弹簧动画,参数分别为:时长,延时,弹性(越小弹性越大),初始速度
// [UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.3 initialSpringVelocity:0.3 options:UIViewAnimationOptionLayoutSubviews animations:^{
// //因为先缩放了所以得 20.5*2 = 1
// view.transform = CGAffineTransformScale(view.transform, 2, 2);
// } completion:^(BOOL finished) {
//
// }];
}
#pragma mark - 经纬度转屏幕坐标, 调用者负责释放内存!
- (CGPoint *)pointsForCoordinates:(CLLocationCoordinate2D *)coordinates count:(NSUInteger)count{
if (coordinates == NULL || count <= 1)
{
return NULL;
}
/* 申请屏幕坐标存储空间. */
CGPoint *points = (CGPoint *)malloc(count * sizeof(CGPoint));
/* 经纬度转换为屏幕坐标. */
for (int i = 0; i < count; i++)
{
points[i] = [self.mapView convertCoordinate:coordinates[i] toPointToView:self.mapView];
}
return points;
}
#pragma mark - 构建path, 调用者负责释放内存!
- (CGPathRef)pathForPoints:(CGPoint *)points count:(NSUInteger)count{
if (points == NULL || count <= 1){
return NULL;
}
UIBezierPath *layerPathBezier = [UIBezierPath bezierPath];
[layerPathBezier moveToPoint:points[0]];
//贝塞尔路线数组
NSMutableArray *mbeziePaths = [NSMutableArray array];
//上一个点
CGPoint lastPoint = points[0];
double sumJuli = 0;
NSMutableArray *juliArr = [NSMutableArray array];
for (int i = 1 ; i < count; i++) {
UIBezierPath *beziePath = [UIBezierPath bezierPath];
[beziePath moveToPoint:lastPoint];
[beziePath addLineToPoint:points[i]];
[layerPathBezier addLineToPoint:points[i]];
CGPoint nowPiont = points[i];
CGFloat xDist = lastPoint.x - nowPiont.x;
CGFloat yDist = lastPoint.y - nowPiont.y;
double juli = sqrt((xDist*xDist)+(yDist*yDist));
[juliArr addObject:@(juli)];
//计算总的距离(相对在屏幕上的距离)
sumJuli += juli;
lastPoint = points[i];
[mbeziePaths addObject:beziePath];
}
self.juliArr = [juliArr copy];
self.SumJuli = sumJuli;
self.durationTime = sumJuli/(kSpeed); //每秒 320/2 dp 距离
// if(self.durationTime > 5.00){
// self.durationTime = 5.00;
// }
self.beziePaths = [mbeziePaths copy];
return layerPathBezier.CGPath;
}
#pragma mark - 构建shapeLayer的basicAnimation
- (CAAnimation *)constructShapeLayerAnimation{
CABasicAnimation *theStrokeAnimation = [CABasicAnimation animationWithKeyPath:StrokeEndAnimationKey]; //画线
theStrokeAnimation.duration = self.durationTime;
theStrokeAnimation.fromValue = @0.f;
theStrokeAnimation.toValue = @1.f;
theStrokeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
return theStrokeAnimation;
}
#pragma mark - 构建动画轨迹头部发光点 关键帧动画
- (NSArray *)constructHeadLayerAnimationWithBeziePaths:(NSArray<UIBezierPath*>*)beziePaths{
if(self.juliArr.count != beziePaths.count){
return [NSArray array];
}
NSMutableArray *arr = [NSMutableArray array];
CAAnimationGroup *group = [CAAnimationGroup animation];
for (int i=0; i<beziePaths.count; i++) {
CAKeyframeAnimation *headKeyAnimation = [CAKeyframeAnimation animationWithKeyPath:PositionAnimationKey]; //位置
NSNumber *julinumber = self.juliArr[i];
double juli = julinumber.doubleValue;
double duration = juli/self.SumJuli* self.durationTime;
headKeyAnimation.duration = duration;
headKeyAnimation.path = beziePaths[i].CGPath;
// headKeyAnimation.values = [arr copy];
headKeyAnimation.calculationMode = kCAAnimationPaced ;
headKeyAnimation.fillMode = kCAFillModeForwards ;
// headKeyAnimation.rotationMode = kCAAnimationRotateAutoReverse;
// headKeyAnimation.rotationMode = kCAAnimationRotateAuto;
[arr addObject:headKeyAnimation];
}
group.animations = arr;
return arr;
}
- (void)addLocate:(NSArray<Locate *>*)arr{
WEAKSELF
NSMutableArray *pointArr = [NSMutableArray array];
self.pathPointsModels = [NSMutableArray array];
self.angeleValues = [NSMutableArray array];
TracingPoint * firstTp = [[TracingPoint alloc] init];
Locate *firstLocate = arr.firstObject;
firstTp.coordinate = CLLocationCoordinate2DMake([firstLocate.lat doubleValue],
[firstLocate.lon doubleValue]);
//
firstTp.course = [self.pathPointsModels firstObject].course;
[self.pathPointsModels addObject:firstTp];
[self.angeleValues addObject:@(0)];
for (int i = 1; i<arr.count; i++)
{
//此点坐标
Locate *tempLocate = arr[i];
CLLocationCoordinate2D tempCoordinate = CLLocationCoordinate2DMake([tempLocate.lat doubleValue],
[tempLocate.lon doubleValue]);
//上一个点的坐标 (arr.length > 2)
Locate *tempLocate2 = arr[i-1];
CLLocationCoordinate2D tempCoordinate2 = CLLocationCoordinate2DMake([tempLocate2.lat doubleValue],
[tempLocate2.lon doubleValue]);
TracingPoint * tp = [[TracingPoint alloc] init];
//此点的坐标
tp.coordinate = tempCoordinate;
//此点相对于上个点的偏移角
tp.course = [Util calculateCourseFromCoordinate:tempCoordinate to:tempCoordinate2];
// 角度转换
double radian = [Util fixNewDirection: tp.course basedOnOldDirection:0];
//计算弧度 角度*弧度值 DegToRad
[self.angeleValues addObject:@(radian*DegToRad)];
[self.pathPointsModels addObject:tp];
}
// self.angeleValues = [NSMutableArray array];
// NSArray *tempArr = [self.pathPointsModels copy];
// for (int i = 0; i < tempArr.count; i++) {
// TracingPoint *tp = tempArr[i];
// //angle
// double currDir = [Util fixNewDirection:tp.course basedOnOldDirection:0];
// //DegToRad 1弧度对应多少度
// [self.angeleValues addObject:@(currDir * DegToRad)];
// }
[arr enumerateObjectsUsingBlock:^(Locate * _Nonnull locate, NSUInteger idx, BOOL * _Nonnull stop) {
MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc] init];
pointAnnotation.tempLocate = locate;
pointAnnotation.tracingPoint = self.pathPointsModels[idx];
// xLog(@"idx: %d, tp.course:%f ", idx, pointAnnotation.tracingPoint.course);
CLLocationCoordinate2D tempCoordinate = CLLocationCoordinate2DMake([locate.lat doubleValue],
[locate.lon doubleValue]);
pointAnnotation.coordinate = tempCoordinate;
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[locate.timestamp doubleValue]];
NSString *dateStr = [myHelper getDateFormatWithStr:@"M月d日 HH:mm"
date:date];
if (locate.loc_type) {
pointAnnotation.title = [NSString stringWithFormat:@"定位类型:%@ %@",locate.loc_type,dateStr];
}else{
pointAnnotation.title = [NSString stringWithFormat:@"%@",dateStr];
}
pointAnnotation.subtitle = locate.address;
CLLocation * pointLocation = [[CLLocation alloc] initWithLatitude:[locate.lat doubleValue] longitude:[locate.lon doubleValue]];
[pointArr addObject:pointLocation];
// [weakSelf setMapZoom:pointAnnotation.coordinate];
[weakSelf.pointAnnotationArr addObject:pointAnnotation];
// [weakSelf.mapView addAnnotation:pointAnnotation];
}];
if(arr.count > 1){
[self drawLineWithLocationArray:[pointArr copy]];
[self.startAndStopBtn setHidden:NO];
}else{
[self.startAndStopBtn setHidden:YES];
if(self.pointAnnotationArr && self.pointAnnotationArr.count > 0){
[self.mapView addAnnotations:self.pointAnnotationArr];
self.mapView.userInteractionEnabled = YES;
[self.mapView showAnnotations:self.pointAnnotationArr animated:YES];
[self.mapView selectAnnotation:self.pointAnnotationArr[0] animated:YES];
}
}
}
#pragma mark - 画线
- (void)drawLineWithLocationArray:(NSArray *)locationArray
{
NSInteger pointCount = [locationArray count];
CLLocationCoordinate2D *coordinateArray = (CLLocationCoordinate2D *)malloc(pointCount * sizeof(CLLocationCoordinate2D));
for (int i = 0; i < pointCount; ++i) {
CLLocation *location = [locationArray objectAtIndex:i];
coordinateArray[(pointCount-1)-i] = [location coordinate];
}
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:pointCount];
//经纬度的区域坐标
MKMapRect mapShowRect = [self.routeLine boundingMapRect];
xLog(@"mapShowRect X: %f Y:%f Width: %f, Height: %f", mapShowRect.origin.x,mapShowRect.origin.y,mapShowRect.size.width,mapShowRect.size.height);
//显示区域
[self.mapView setVisibleMapRect:mapShowRect edgePadding:UIEdgeInsetsMake(50, 50, 50, 50) animated:NO];
//把路径点变成在 屏幕上的坐标点
self.pathPoints = [self pointsForCoordinates:coordinateArray count:pointCount];
free(coordinateArray);
coordinateArray = NULL;
}
#pragma mark - 地图控件代理方法
#pragma mark 显示大头针时调用,注意方法中的annotation参数是即将显示的大头针对象
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
//由于当前位置的标注也是一个大头针,所以此时需要判断,此代理方法返回nil使用默认大头针视图
static NSString *key1=@"AnnotationKey1";
CustomAnnotationView *annotationView = (CustomAnnotationView*)[_mapView dequeueReusableAnnotationViewWithIdentifier:key1];
MKPointAnnotation *pointAnnotation = (MKPointAnnotation*)annotation;
//如果缓存池中不存在则新建
if (!annotationView) {
annotationView=[[CustomAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:key1];
annotationView.canShowCallout=NO;//不允许交互点击
}else{
//重新设置此类大头针视图的大头针模型(因为有可能是从缓存池中取出来的,位置是放到缓存池时的位置)
annotationView.annotation = annotation;
}
if([annotation isEqual:self.pointAnnotationArr.firstObject]&&self.pointAnnotationArr.count>1){
//修改大头针视图 设置终点
[annotationView setImageWithString:@"终点"];
//设置大小
annotationView.frame = CGRectMake(0, 0, 30, 30);
//设置中心偏移量
annotationView.centerOffset = CGPointMake(0, -15);
annotationView.calloutOffset=CGPointMake(0, 1);//定义详情视图偏移量
return annotationView;
}
if([annotation isEqual:self.pointAnnotationArr.lastObject]){
//修改大头针视图 设置起点
[annotationView setImageWithString:@"起点"];
//设置大小
annotationView.frame = CGRectMake(0, 0, 30, 30);
//设置中心偏移量
annotationView.centerOffset = CGPointMake(0, -15);
annotationView.calloutOffset=CGPointMake(0, 1);//定义详情视图偏移量
return annotationView;
}
[annotationView setImageWithString:@"icon_enter_the_footprint"];
double radian = [Util fixNewDirection:pointAnnotation.tracingPoint.course basedOnOldDirection:0];
// xLog(@"radian %f", radian*DegToRad);
[annotationView setRadian:radian*DegToRad];
//设置大小
annotationView.frame = CGRectMake(0, 0, 12, 12);
//设置中心偏移量
annotationView.centerOffset = CGPointMake(3, -3);
annotationView.calloutOffset=CGPointMake(0, 0);//定义详情视图偏移量
return annotationView;
}
//MARK: 点击地图 中的 标点 触发的方法
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
if([view isKindOfClass:[CustomAnnotationView class]]){
if([view.annotation isKindOfClass:[MKPointAnnotation class]]){
MKPointAnnotation *pointAnnotation = (MKPointAnnotation*)view.annotation;
curLocate = pointAnnotation.tempLocate;
if(!curLocate){
return;
}
}else{
return;
}
//自定义动画
view.transform = CGAffineTransformScale(view.transform, 0.5, 0.5);
// 弹簧动画,参数分别为:时长,延时,弹性(越小弹性越大),初始速度
[UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.3 initialSpringVelocity:0.3 options:UIViewAnimationOptionLayoutSubviews animations:^{
view.transform = CGAffineTransformScale(view.transform, 2, 2);
} completion:^(BOOL finished) {
}];
// 设备点
self.locationTypeLabel.text = curLocate.loc_type;
if ([curLocate.loc_type isEqualToString:@"LBS"]) {
self.locationTypeImageView.image = [UIImage imageNamed:@"icon_base_station"];
}else if([curLocate.loc_type isEqualToString:@"GPS"]){
self.locationTypeImageView.image = [UIImage imageNamed:@"icon_positioning_g"];
}else if([curLocate.loc_type isEqualToString:@"WIFI"]){
self.locationTypeImageView.image = [UIImage imageNamed:@"icon_wifi"];
}else{
//是空的 LBS
self.locationTypeImageView.image = [UIImage imageNamed:@"icon_base_station"];
self.locationTypeLabel.text = @"LBS";
}
if(curLocate.address.length > 0){
NSString *dateStr = [myHelper getDateFormatWithStr:@"HH:mm"
date:[NSDate dateWithTimeIntervalSince1970:[curLocate.timestamp doubleValue]]];
NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@",curLocate.address,dateStr]];
[att addAttribute:NSForegroundColorAttributeName
value:mainColor
range:NSMakeRange(att.length-dateStr.length,dateStr.length)];
self.locationAddressLabel.attributedText = att;
}else{
AMapReGeocodeSearchRequest *regeo = [[AMapReGeocodeSearchRequest alloc] init];
regeo.location = [AMapGeoPoint locationWithLatitude:[curLocate.lat floatValue] longitude:[curLocate.lon floatValue]];
[self.searchAPI AMapReGoecodeSearch:regeo];
}
}
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKCircle class]])
{
MKCircleRenderer *circle = [[MKCircleRenderer alloc] initWithOverlay:overlay];
circle.strokeColor = [UIColor clearColor];
circle.fillColor = [[UIColor blueColor] colorWithAlphaComponent:0.1];
// circle.lineWidth = 1;
return circle;
}
if (overlay == self.routeLine) {
if(nil == self.routeLineView) {
self.routeLineView = [[MKPolylineRenderer alloc] initWithPolyline:self.routeLine] ;
//虚线===
//self.routeLineView.lineDashPhase = 10;
//NSArray* array = [NSArray arrayWithObjects:[NSNumber numberWithInt:15] , [NSNumber numberWithInt:15],nil]; // 2
//self.routeLineView.lineDashPattern = array; // 3
//====
self.routeLineView.fillColor = mainColor;
self.routeLineView.strokeColor = mainColor;
self.routeLineView.lineWidth = 4;
}
return self.routeLineView;
}
return nil;
}
#pragma mark ====高德地图位置解析回调====
-(void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response{
if (response.regeocode != nil)
{
NSString *name = response.regeocode.formattedAddress;
//解析response获取地址描述,具体解析见 Demo
// //获取市
// NSString *city = response.regeocode.addressComponent.city;
// NSString *province = response.regeocode.addressComponent.province;
// if(city && city.length>0){
// name = [name componentsSeparatedByString:city].lastObject;
// if([city isEqualToString:province]){
// //直辖市
// name = [NSString stringWithFormat:@"%@ %@",name,city];
// }else{
// //普通市
// name = [NSString stringWithFormat:@"%@ %@ %@",name,city,province];
// }
// }
NSString *dateStr = [myHelper getDateFormatWithStr:@"HH:mm"
date:[NSDate dateWithTimeIntervalSince1970:[curLocate.timestamp doubleValue]]];
NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@",name,dateStr]];
[att addAttribute:NSForegroundColorAttributeName
value:mainColor
range:NSMakeRange(att.length-dateStr.length,dateStr.length)];
self.locationAddressLabel.attributedText = att;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
switch (self.mapView.mapType) {
case MKMapTypeHybrid:
{
self.mapView.mapType = MKMapTypeStandard;
}
break;
case MKMapTypeStandard:
{
self.mapView.mapType = MKMapTypeHybrid;
}
break;
default:
break;
}
self.mapView.mapType = MKMapTypeStandard;
}
-(void)dealloc{
xLog(@"销毁 历史轨迹展示页面")
}
@end