SportPathVC.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. //
  2. // SportPathVC.m
  3. // LN_School
  4. //
  5. // Created by EchoShacolee on 2017/8/7.
  6. // Copyright © 2017年 Danson. All rights reserved.
  7. //
  8. #import "SportPathVC.h"
  9. #import "DateView.h"
  10. // 运动结点信息类
  11. @interface BMKSportNode : NSObject
  12. //经纬度
  13. @property (nonatomic, assign) CLLocationCoordinate2D coordinate;
  14. //方向(角度)
  15. @property (nonatomic, assign) CGFloat angle;
  16. //距离
  17. @property (nonatomic, assign) CGFloat distance;
  18. //速度
  19. @property (nonatomic, assign) CGFloat speed;
  20. @end
  21. @implementation BMKSportNode
  22. @synthesize coordinate = _coordinate;
  23. @synthesize angle = _angle;
  24. @synthesize distance = _distance;
  25. @synthesize speed = _speed;
  26. @end
  27. // 自定义BMKAnnotationView,用于显示运动者
  28. @interface SportAnnotationView : BMKAnnotationView
  29. @property (nonatomic, strong) UIImageView *imageView;
  30. @end
  31. @implementation SportAnnotationView
  32. @synthesize imageView = _imageView;
  33. - (id)initWithAnnotation:(id<BMKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
  34. self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
  35. if (self) {
  36. [self setBounds:CGRectMake(0.f, 0.f, 22.f, 22.f)];
  37. _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.f, 0.f, 22.f, 22.f)];
  38. _imageView.image = [UIImage imageNamed:@"sportarrow.png"];
  39. [self addSubview:_imageView];
  40. }
  41. return self;
  42. }
  43. @end
  44. @interface SportPathVC ()<BMKMapViewDelegate>
  45. {
  46. BMKPolyline* polyline;
  47. BMKPointAnnotation *sportAnnotation;
  48. SportAnnotationView *sportAnnotationView;
  49. NSMutableArray *sportNodes;//轨迹点
  50. NSInteger sportNodeNum;//轨迹点数
  51. NSInteger currentIndex;//当前结点
  52. NSString *theDate;
  53. }
  54. /**播放速度系数 最大1.9 最小0.1 */
  55. @property (nonatomic, assign) CGFloat playSpeedFactor;
  56. @end
  57. @implementation SportPathVC
  58. - (void)viewDidLoad {
  59. [super viewDidLoad];
  60. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  61. [dateFormatter setDateFormat:@"yyyy-MM-dd"];
  62. self.title = [dateFormatter stringFromDate:[NSDate date]];
  63. [self goBackByNavigation];
  64. //适配ios7
  65. if( ([[[UIDevice currentDevice] systemVersion] doubleValue]>=7.0)) {
  66. self.navigationController.navigationBar.translucent = NO;
  67. }
  68. _mapView.zoomLevel = 15;
  69. _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
  70. theDate = self.title;
  71. sportNodes = [[NSMutableArray alloc] init];
  72. //初始化轨迹点
  73. [self getTrackPlayBack];
  74. // [self initSportNodes];//测试用
  75. // [self createRightBtn];
  76. }
  77. -(void)createRightBtn{
  78. self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"列表" style:UIBarButtonItemStylePlain target:self action:@selector(running)];
  79. self.navigationItem.rightBarButtonItem.tintColor = RQMianColor;
  80. }
  81. -(void)viewWillAppear:(BOOL)animated {
  82. [super viewWillAppear:animated];
  83. [_mapView viewWillAppear];
  84. _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
  85. }
  86. -(void)viewWillDisappear:(BOOL)animated {
  87. [super viewWillDisappear:animated];
  88. [_mapView viewWillDisappear];
  89. _mapView.delegate = nil; // 不用时,置nil
  90. }
  91. - (void)dealloc {
  92. if (_mapView) {
  93. _mapView = nil;
  94. }
  95. }
  96. //初始化轨迹点 测试用
  97. - (void)initSportNodes {
  98. #if 0
  99. //读取数据
  100. //@RQ-MARK
  101. NSString *path = [[NSBundle mainBundle]pathForResource:@"test3" ofType:@"txt"];
  102. NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:path];
  103. NSData *data = [fh readDataToEndOfFile];
  104. if (data) {
  105. NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil][@"body"];
  106. for (NSDictionary *dic in array) {
  107. if ([dic[@"GPI_BD_LATITUDE"] length] < 1 || [dic[@"GPI_BD_LONGITUDE"] length] < 1) {
  108. continue;
  109. }
  110. BMKSportNode *sportNode = [[BMKSportNode alloc] init];
  111. sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"lat"] doubleValue], [dic[@"lon"] doubleValue]);
  112. if ([dic[@"GPI_BD_LATITUDE"] floatValue] > [dic[@"GPI_BD_LONGITUDE"] floatValue]) {
  113. //这种情况是服务器经纬度反了 @RQ-MARK
  114. sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"GPI_BD_LONGITUDE"] floatValue], [dic[@"GPI_BD_LATITUDE"] floatValue]);
  115. }
  116. // sportNode.angle = [dic[@"angle"] doubleValue];
  117. // sportNode.distance = [dic[@"distance"] doubleValue];
  118. // sportNode.speed = [dic[@"speed"] doubleValue];
  119. [sportNodes addObject:sportNode];
  120. }
  121. }
  122. sportNodeNum = sportNodes.count;
  123. #else
  124. //读取数据
  125. NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sport_path" ofType:@"json"]];
  126. if (jsonData) {
  127. NSArray *array = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
  128. for (NSDictionary *dic in array) {
  129. BMKSportNode *sportNode = [[BMKSportNode alloc] init];
  130. sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"lat"] doubleValue], [dic[@"lon"] doubleValue]);
  131. sportNode.angle = [dic[@"angle"] doubleValue];
  132. sportNode.distance = [dic[@"distance"] doubleValue];
  133. sportNode.speed = [dic[@"speed"] doubleValue];
  134. [sportNodes addObject:sportNode];
  135. NSLog(@"xxxx-- %f",sportNode.distance);
  136. }
  137. }
  138. sportNodeNum = sportNodes.count;
  139. #endif
  140. }
  141. //添加内置覆盖物
  142. - (void)addOverlayView {
  143. CLLocationCoordinate2D paths[sportNodeNum];
  144. for (NSInteger i = 0; i < sportNodeNum; i++) {
  145. BMKSportNode *node = sportNodes[i];
  146. paths[i] = node.coordinate;
  147. }
  148. polyline = [BMKPolyline polylineWithCoordinates:paths count:sportNodeNum];
  149. [_mapView addOverlay:polyline];
  150. if (!sportAnnotation) {
  151. sportAnnotation = [[BMKPointAnnotation alloc]init];
  152. }
  153. sportAnnotation.coordinate = paths[0];
  154. sportAnnotation.title = self.carNum;
  155. [_mapView addAnnotation:sportAnnotation];
  156. currentIndex = 0;
  157. }
  158. //runing
  159. - (void)running {
  160. if (sportNodeNum == 0) {
  161. return;
  162. }
  163. BMKSportNode *node = [sportNodes objectAtIndex:currentIndex % sportNodeNum];
  164. sportAnnotationView.imageView.transform = CGAffineTransformMakeRotation(node.angle);
  165. // double time = 3;
  166. // if (node.speed != 0) {
  167. // time = node.distance/node.speed*1000;//真实时间*10 *100?
  168. // if (time>10) {
  169. // time = 10;
  170. // }
  171. // NSLog(@"zz--- %lf",time);
  172. // }
  173. CGFloat time = 0.1;
  174. if (sportNodeNum < 60) {
  175. time = 0.2;
  176. }else if (sportNodeNum < 120) {
  177. time = 0.1;
  178. }else if (sportNodeNum < 240) {
  179. time = 0.05;
  180. }else if (sportNodeNum < 480) {
  181. time = 0.025;
  182. }else if (sportNodeNum < 960) {
  183. time = 0.0125;
  184. }else {
  185. time = 0.01;
  186. }
  187. [UIView animateWithDuration:time*_playSpeedFactor animations:^{
  188. currentIndex++;
  189. BMKSportNode *node = [sportNodes objectAtIndex:currentIndex % sportNodeNum];
  190. sportAnnotation.coordinate = node.coordinate;
  191. } completion:^(BOOL finished) {
  192. if (currentIndex == sportNodeNum) {
  193. currentIndex = 0;
  194. return;
  195. }
  196. [self running];
  197. }];
  198. }
  199. #pragma mark - btnClick
  200. - (IBAction)playBtn:(id)sender {
  201. if (sportNodes.count == 0) {
  202. ShowMsg([NSString stringWithFormat:@"车辆“%@”在%@当天没有轨迹记录,请重新选择日期",self.carNum,self.title]);
  203. return;
  204. }
  205. if (currentIndex != 0) {
  206. return;//运动中
  207. }
  208. [self running];
  209. }
  210. - (IBAction)selectDate:(id)sender {
  211. DateView *dateV = [[DateView alloc] init];
  212. [dateV setStyle:0];
  213. [dateV showWithComplete:^(NSString * result) {
  214. //更新UI
  215. theDate = result;
  216. self.title = result;
  217. [_mapView removeAnnotation:sportAnnotation];
  218. [_mapView removeOverlay:polyline];
  219. [sportNodes removeAllObjects];
  220. sportNodeNum = 0;
  221. [self getTrackPlayBack];
  222. }];
  223. }
  224. - (IBAction)speedUpAction:(UIButton *)sender {
  225. if (_playSpeedFactor > 0.1) {
  226. _playSpeedFactor -= 0.1;
  227. }else {
  228. ShowMsg(@"已达最大速度!");
  229. }
  230. }
  231. - (IBAction)slowDownAction:(UIButton *)sender {
  232. if (_playSpeedFactor < 1.9) {
  233. _playSpeedFactor += 0.1;
  234. }else {
  235. ShowMsg(@"已达最小速度!");
  236. }
  237. }
  238. #pragma mark - BMKMapViewDelegate
  239. //- (void)mapViewDidFinishLoading:(BMKMapView *)mapView {
  240. // [self addOverlayView];
  241. //}
  242. //根据overlay生成对应的View
  243. - (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay
  244. {
  245. if ([overlay isKindOfClass:[BMKPolyline class]])
  246. {
  247. BMKPolylineView* polygonView = [[BMKPolylineView alloc] initWithOverlay:overlay];
  248. polygonView.strokeColor = [[UIColor blackColor] initWithRed:0.0 green:0.5 blue:0.0 alpha:0.6];
  249. polygonView.lineWidth = 1.5;
  250. return polygonView;
  251. }
  252. return nil;
  253. }
  254. // 根据anntation生成对应的View
  255. - (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
  256. {
  257. if (sportAnnotationView == nil) {
  258. sportAnnotationView = [[SportAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"sportsAnnotation"];
  259. sportAnnotationView.draggable = NO;
  260. BMKSportNode *node = [sportNodes firstObject];
  261. sportAnnotationView.imageView.transform = CGAffineTransformMakeRotation(node.angle);
  262. }
  263. return sportAnnotationView;
  264. }
  265. - (void)mapView:(BMKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
  266. [self running];
  267. }
  268. #pragma mark 网络请求
  269. -(void)getTrackPlayBack{
  270. if (![NetManager connectedToNetWork]) {
  271. showMsgUnconnect();
  272. return;
  273. }
  274. NSMutableDictionary *dic = [NSMutableDictionary dictionary];
  275. [dic setObject:self.simStr forKey:@"sim"];
  276. [dic setObject:theDate forKey:@"cdTime"];
  277. NSString *method = @"getTrackPlayBack";
  278. [NetManager requestAnythingWithURL:method dictionary:dic dataArray:nil completion:^(NSDictionary *root) {
  279. if (!root) {
  280. ShowMsg(@"数据请求失败,请重试");
  281. return;
  282. }
  283. if ([root[@"code"] integerValue] == 1) {
  284. ShowMsg(root[@"msg"]);
  285. return;
  286. }
  287. BOOL isSetCenter = NO;
  288. NSArray *array = root[@"body"];
  289. if (array.count > 0) {
  290. for (NSDictionary *dic in array) {
  291. if ([dic[@"LAT"] length] < 1 || [dic[@"LON"] length] < 1) {
  292. continue;
  293. }
  294. BMKSportNode *sportNode = [[BMKSportNode alloc] init];
  295. sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"LAT"] doubleValue], [dic[@"LON"] doubleValue]);
  296. sportNode.angle = [dic[@"DIRECTION"] doubleValue];
  297. sportNode.distance = [dic[@"MILEAGE"] doubleValue];
  298. sportNode.speed = [dic[@"LOCATIONSPEED"] doubleValue];
  299. [sportNodes addObject:sportNode];//调接口前有做清零
  300. if (!isSetCenter) {
  301. _mapView.centerCoordinate = sportNode.coordinate;
  302. isSetCenter = YES;
  303. }
  304. // NSLog(@"xxxx-- 方向%f 距离%f 速度%f",sportNode.angle,sportNode.distance,sportNode.speed);
  305. }
  306. _playSpeedFactor = 1.0;
  307. sportNodeNum = sportNodes.count;
  308. [self addOverlayView];
  309. }else{
  310. //没有运动轨迹
  311. ShowMsg([NSString stringWithFormat:@"车辆“%@”在%@当天没有轨迹记录,请重新选择日期",self.carNum,self.title]);
  312. }
  313. }];
  314. }
  315. @end