// // SportPathVC.m // LN_School // // Created by EchoShacolee on 2017/8/7. // Copyright © 2017年 Danson. All rights reserved. // #import "SportPathVC.h" #import "DateView.h" // 运动结点信息类 @interface BMKSportNode : NSObject //经纬度 @property (nonatomic, assign) CLLocationCoordinate2D coordinate; //方向(角度) @property (nonatomic, assign) CGFloat angle; //距离 @property (nonatomic, assign) CGFloat distance; //速度 @property (nonatomic, assign) CGFloat speed; @end @implementation BMKSportNode @synthesize coordinate = _coordinate; @synthesize angle = _angle; @synthesize distance = _distance; @synthesize speed = _speed; @end // 自定义BMKAnnotationView,用于显示运动者 @interface SportAnnotationView : BMKAnnotationView @property (nonatomic, strong) UIImageView *imageView; @end @implementation SportAnnotationView @synthesize imageView = _imageView; - (id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; if (self) { [self setBounds:CGRectMake(0.f, 0.f, 22.f, 22.f)]; _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.f, 0.f, 22.f, 22.f)]; _imageView.image = [UIImage imageNamed:@"sportarrow.png"]; [self addSubview:_imageView]; } return self; } @end @interface SportPathVC () { BMKPolyline* polyline; BMKPointAnnotation *sportAnnotation; SportAnnotationView *sportAnnotationView; NSMutableArray *sportNodes;//轨迹点 NSInteger sportNodeNum;//轨迹点数 NSInteger currentIndex;//当前结点 NSString *theDate; } /**播放速度系数 最大1.9 最小0.1 */ @property (nonatomic, assign) CGFloat playSpeedFactor; @end @implementation SportPathVC - (void)viewDidLoad { [super viewDidLoad]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd"]; self.title = [dateFormatter stringFromDate:[NSDate date]]; [self goBackByNavigation]; //适配ios7 if( ([[[UIDevice currentDevice] systemVersion] doubleValue]>=7.0)) { self.navigationController.navigationBar.translucent = NO; } _mapView.zoomLevel = 15; _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放 theDate = self.title; sportNodes = [[NSMutableArray alloc] init]; //初始化轨迹点 [self getTrackPlayBack]; // [self initSportNodes];//测试用 // [self createRightBtn]; } -(void)createRightBtn{ self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"列表" style:UIBarButtonItemStylePlain target:self action:@selector(running)]; self.navigationItem.rightBarButtonItem.tintColor = RQMianColor; } -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [_mapView viewWillAppear]; _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放 } -(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [_mapView viewWillDisappear]; _mapView.delegate = nil; // 不用时,置nil } - (void)dealloc { if (_mapView) { _mapView = nil; } } //初始化轨迹点 测试用 - (void)initSportNodes { #if 0 //读取数据 //@RQ-MARK NSString *path = [[NSBundle mainBundle]pathForResource:@"test3" ofType:@"txt"]; NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:path]; NSData *data = [fh readDataToEndOfFile]; if (data) { NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil][@"body"]; for (NSDictionary *dic in array) { if ([dic[@"GPI_BD_LATITUDE"] length] < 1 || [dic[@"GPI_BD_LONGITUDE"] length] < 1) { continue; } BMKSportNode *sportNode = [[BMKSportNode alloc] init]; sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"lat"] doubleValue], [dic[@"lon"] doubleValue]); if ([dic[@"GPI_BD_LATITUDE"] floatValue] > [dic[@"GPI_BD_LONGITUDE"] floatValue]) { //这种情况是服务器经纬度反了 @RQ-MARK sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"GPI_BD_LONGITUDE"] floatValue], [dic[@"GPI_BD_LATITUDE"] floatValue]); } // sportNode.angle = [dic[@"angle"] doubleValue]; // sportNode.distance = [dic[@"distance"] doubleValue]; // sportNode.speed = [dic[@"speed"] doubleValue]; [sportNodes addObject:sportNode]; } } sportNodeNum = sportNodes.count; #else //读取数据 NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sport_path" ofType:@"json"]]; if (jsonData) { NSArray *array = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil]; for (NSDictionary *dic in array) { BMKSportNode *sportNode = [[BMKSportNode alloc] init]; sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"lat"] doubleValue], [dic[@"lon"] doubleValue]); sportNode.angle = [dic[@"angle"] doubleValue]; sportNode.distance = [dic[@"distance"] doubleValue]; sportNode.speed = [dic[@"speed"] doubleValue]; [sportNodes addObject:sportNode]; NSLog(@"xxxx-- %f",sportNode.distance); } } sportNodeNum = sportNodes.count; #endif } //添加内置覆盖物 - (void)addOverlayView { CLLocationCoordinate2D paths[sportNodeNum]; for (NSInteger i = 0; i < sportNodeNum; i++) { BMKSportNode *node = sportNodes[i]; paths[i] = node.coordinate; } polyline = [BMKPolyline polylineWithCoordinates:paths count:sportNodeNum]; [_mapView addOverlay:polyline]; if (!sportAnnotation) { sportAnnotation = [[BMKPointAnnotation alloc]init]; } sportAnnotation.coordinate = paths[0]; sportAnnotation.title = self.carNum; [_mapView addAnnotation:sportAnnotation]; currentIndex = 0; } //runing - (void)running { if (sportNodeNum == 0) { return; } BMKSportNode *node = [sportNodes objectAtIndex:currentIndex % sportNodeNum]; sportAnnotationView.imageView.transform = CGAffineTransformMakeRotation(node.angle); // double time = 3; // if (node.speed != 0) { // time = node.distance/node.speed*1000;//真实时间*10 *100? // if (time>10) { // time = 10; // } // NSLog(@"zz--- %lf",time); // } CGFloat time = 0.1; if (sportNodeNum < 60) { time = 0.2; }else if (sportNodeNum < 120) { time = 0.1; }else if (sportNodeNum < 240) { time = 0.05; }else if (sportNodeNum < 480) { time = 0.025; }else if (sportNodeNum < 960) { time = 0.0125; }else { time = 0.01; } [UIView animateWithDuration:time*_playSpeedFactor animations:^{ currentIndex++; BMKSportNode *node = [sportNodes objectAtIndex:currentIndex % sportNodeNum]; sportAnnotation.coordinate = node.coordinate; } completion:^(BOOL finished) { if (currentIndex == sportNodeNum) { currentIndex = 0; return; } [self running]; }]; } #pragma mark - btnClick - (IBAction)playBtn:(id)sender { if (sportNodes.count == 0) { ShowMsg([NSString stringWithFormat:@"车辆“%@”在%@当天没有轨迹记录,请重新选择日期",self.carNum,self.title]); return; } if (currentIndex != 0) { return;//运动中 } [self running]; } - (IBAction)selectDate:(id)sender { DateView *dateV = [[DateView alloc] init]; [dateV setStyle:0]; [dateV showWithComplete:^(NSString * result) { //更新UI theDate = result; self.title = result; [_mapView removeAnnotation:sportAnnotation]; [_mapView removeOverlay:polyline]; [sportNodes removeAllObjects]; sportNodeNum = 0; [self getTrackPlayBack]; }]; } - (IBAction)speedUpAction:(UIButton *)sender { if (_playSpeedFactor > 0.1) { _playSpeedFactor -= 0.1; }else { ShowMsg(@"已达最大速度!"); } } - (IBAction)slowDownAction:(UIButton *)sender { if (_playSpeedFactor < 1.9) { _playSpeedFactor += 0.1; }else { ShowMsg(@"已达最小速度!"); } } #pragma mark - BMKMapViewDelegate //- (void)mapViewDidFinishLoading:(BMKMapView *)mapView { // [self addOverlayView]; //} //根据overlay生成对应的View - (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id )overlay { if ([overlay isKindOfClass:[BMKPolyline class]]) { BMKPolylineView* polygonView = [[BMKPolylineView alloc] initWithOverlay:overlay]; polygonView.strokeColor = [[UIColor blackColor] initWithRed:0.0 green:0.5 blue:0.0 alpha:0.6]; polygonView.lineWidth = 1.5; return polygonView; } return nil; } // 根据anntation生成对应的View - (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id )annotation { if (sportAnnotationView == nil) { sportAnnotationView = [[SportAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"sportsAnnotation"]; sportAnnotationView.draggable = NO; BMKSportNode *node = [sportNodes firstObject]; sportAnnotationView.imageView.transform = CGAffineTransformMakeRotation(node.angle); } return sportAnnotationView; } - (void)mapView:(BMKMapView *)mapView didAddAnnotationViews:(NSArray *)views { [self running]; } #pragma mark 网络请求 -(void)getTrackPlayBack{ if (![NetManager connectedToNetWork]) { showMsgUnconnect(); return; } NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [dic setObject:self.simStr forKey:@"sim"]; [dic setObject:theDate forKey:@"cdTime"]; NSString *method = @"getTrackPlayBack"; [NetManager requestAnythingWithURL:method dictionary:dic dataArray:nil completion:^(NSDictionary *root) { if (!root) { ShowMsg(@"数据请求失败,请重试"); return; } if ([root[@"code"] integerValue] == 1) { ShowMsg(root[@"msg"]); return; } BOOL isSetCenter = NO; NSArray *array = root[@"body"]; if (array.count > 0) { for (NSDictionary *dic in array) { if ([dic[@"LAT"] length] < 1 || [dic[@"LON"] length] < 1) { continue; } BMKSportNode *sportNode = [[BMKSportNode alloc] init]; sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"LAT"] doubleValue], [dic[@"LON"] doubleValue]); sportNode.angle = [dic[@"DIRECTION"] doubleValue]; sportNode.distance = [dic[@"MILEAGE"] doubleValue]; sportNode.speed = [dic[@"LOCATIONSPEED"] doubleValue]; [sportNodes addObject:sportNode];//调接口前有做清零 if (!isSetCenter) { _mapView.centerCoordinate = sportNode.coordinate; isSetCenter = YES; } // NSLog(@"xxxx-- 方向%f 距离%f 速度%f",sportNode.angle,sportNode.distance,sportNode.speed); } _playSpeedFactor = 1.0; sportNodeNum = sportNodes.count; [self addOverlayView]; }else{ //没有运动轨迹 ShowMsg([NSString stringWithFormat:@"车辆“%@”在%@当天没有轨迹记录,请重新选择日期",self.carNum,self.title]); } }]; } @end