SportPathVC.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  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. BMKPolygon * polygo;//围栏
  48. BMKPointAnnotation *sportAnnotation;
  49. SportAnnotationView *sportAnnotationView;
  50. NSMutableArray *sportNodes;//轨迹点
  51. NSInteger sportNodeNum;//轨迹点数
  52. NSInteger currentIndex;//当前结点
  53. NSString *theDate;
  54. }
  55. /**播放速度系数 最大1.9 最小0.1 */
  56. @property (nonatomic, assign) CGFloat playSpeedFactor;
  57. @end
  58. @implementation SportPathVC
  59. - (void)viewDidLoad {
  60. [super viewDidLoad];
  61. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  62. [dateFormatter setDateFormat:@"yyyy-MM-dd"];
  63. self.title = [dateFormatter stringFromDate:[NSDate date]];
  64. [self goBackByNavigation];
  65. //适配ios7
  66. if( ([[[UIDevice currentDevice] systemVersion] doubleValue]>=7.0)) {
  67. self.navigationController.navigationBar.translucent = NO;
  68. }
  69. _mapView.zoomLevel = 19;
  70. _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
  71. theDate = self.title;
  72. sportNodes = [[NSMutableArray alloc] init];
  73. //初始化轨迹点
  74. [self getTrackPlayBack];
  75. // [self initSportNodes];//测试用
  76. // [self createRightBtn];
  77. //围栏
  78. [self getSchoolRegionList];
  79. }
  80. -(void)createRightBtn{
  81. UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
  82. btn.frame = CGRectMake(0, 0, 43, 44);
  83. btn.titleLabel.font = [UIFont systemFontOfSize:17];
  84. [btn setTitle:@"列表" forState:UIControlStateNormal];
  85. [btn setTitleColor:defGreen forState:UIControlStateNormal];
  86. [btn addTarget:self action:@selector(running) forControlEvents:UIControlEventTouchUpInside];
  87. self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
  88. }
  89. -(void)viewWillAppear:(BOOL)animated {
  90. [super viewWillAppear:animated];
  91. [_mapView viewWillAppear];
  92. _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
  93. }
  94. -(void)viewWillDisappear:(BOOL)animated {
  95. [super viewWillDisappear:animated];
  96. [_mapView viewWillDisappear];
  97. _mapView.delegate = nil; // 不用时,置nil
  98. }
  99. - (void)dealloc {
  100. if (_mapView) {
  101. _mapView = nil;
  102. }
  103. }
  104. //初始化轨迹点
  105. //测试用
  106. - (void)initSportNodes {
  107. #if 0
  108. //读取数据
  109. NSString *path = [[NSBundle mainBundle]pathForResource:@"test3" ofType:@"txt"];
  110. NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:path];
  111. NSData *data = [fh readDataToEndOfFile];
  112. if (data) {
  113. NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil][@"body"];
  114. for (NSDictionary *dic in array) {
  115. if ([dic[@"GPI_BD_LATITUDE"] length] < 1 || [dic[@"GPI_BD_LONGITUDE"] length] < 1) {
  116. continue;
  117. }
  118. BMKSportNode *sportNode = [[BMKSportNode alloc] init];
  119. sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"lat"] doubleValue], [dic[@"lon"] doubleValue]);
  120. if ([dic[@"GPI_BD_LATITUDE"] floatValue] > [dic[@"GPI_BD_LONGITUDE"] floatValue]) {
  121. //这种情况是服务器经纬度反了 @lee
  122. sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"GPI_BD_LONGITUDE"] floatValue], [dic[@"GPI_BD_LATITUDE"] floatValue]);
  123. }
  124. // sportNode.angle = [dic[@"angle"] doubleValue];
  125. // sportNode.distance = [dic[@"distance"] doubleValue];
  126. // sportNode.speed = [dic[@"speed"] doubleValue];
  127. [sportNodes addObject:sportNode];
  128. }
  129. }
  130. sportNodeNum = sportNodes.count;
  131. #else
  132. //读取数据
  133. NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sport_path" ofType:@"json"]];
  134. if (jsonData) {
  135. NSArray *array = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
  136. for (NSDictionary *dic in array) {
  137. BMKSportNode *sportNode = [[BMKSportNode alloc] init];
  138. sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"lat"] doubleValue], [dic[@"lon"] doubleValue]);
  139. sportNode.angle = [dic[@"angle"] doubleValue];
  140. sportNode.distance = [dic[@"distance"] doubleValue];
  141. sportNode.speed = [dic[@"speed"] doubleValue];
  142. [sportNodes addObject:sportNode];
  143. NSLog(@"xxxx-- %f",sportNode.distance);
  144. }
  145. }
  146. sportNodeNum = sportNodes.count;
  147. #endif
  148. }
  149. //添加内置覆盖物
  150. - (void)addOverlayView {
  151. CLLocationCoordinate2D paths[sportNodeNum];
  152. for (NSInteger i = 0; i < sportNodeNum; i++) {
  153. BMKSportNode *node = sportNodes[i];
  154. paths[i] = node.coordinate;
  155. }
  156. polyline = [BMKPolyline polylineWithCoordinates:paths count:sportNodeNum];
  157. [_mapView addOverlay:polyline];
  158. if (!sportAnnotation) {
  159. sportAnnotation = [[BMKPointAnnotation alloc]init];
  160. }
  161. sportAnnotation.coordinate = paths[0];
  162. sportAnnotation.title = self.carNum;
  163. [_mapView addAnnotation:sportAnnotation];
  164. currentIndex = 0;
  165. }
  166. //runing
  167. - (void)running {
  168. if (sportNodeNum == 0) {
  169. return;
  170. }
  171. BMKSportNode *node = [sportNodes objectAtIndex:currentIndex % sportNodeNum];
  172. sportAnnotationView.imageView.transform = CGAffineTransformMakeRotation(node.angle);
  173. // double time = 3;
  174. // if (node.speed != 0) {
  175. // time = node.distance/node.speed*1000;//真实时间*10 *100?
  176. // if (time>10) {
  177. // time = 10;
  178. // }
  179. // NSLog(@"zz--- %lf",time);
  180. // }
  181. CGFloat time = 0.1;
  182. if (sportNodeNum < 60) {
  183. time = 0.2;
  184. }else if (sportNodeNum < 120) {
  185. time = 0.1;
  186. }else if (sportNodeNum < 240) {
  187. time = 0.05;
  188. }else if (sportNodeNum < 480) {
  189. time = 0.025;
  190. }else if (sportNodeNum < 960) {
  191. time = 0.0125;
  192. }else {
  193. time = 0.01;
  194. }
  195. [UIView animateWithDuration:time*_playSpeedFactor animations:^{
  196. currentIndex++;
  197. BMKSportNode *node = [sportNodes objectAtIndex:currentIndex % sportNodeNum];
  198. sportAnnotation.coordinate = node.coordinate;
  199. } completion:^(BOOL finished) {
  200. if (currentIndex == sportNodeNum) {
  201. currentIndex = 0;
  202. return;
  203. }
  204. [self running];
  205. }];
  206. }
  207. #pragma mark - btnClick
  208. - (IBAction)playBtn:(id)sender {
  209. if (sportNodes.count == 0) {
  210. ShowMsg([NSString stringWithFormat:@"车辆“%@”在%@当天没有轨迹记录,请重新选择日期",self.carNum,self.title]);
  211. return;
  212. }
  213. if (currentIndex != 0) {
  214. return;//运动中
  215. }
  216. [self running];
  217. }
  218. - (IBAction)selectDate:(id)sender {
  219. DateView *dateV = [[DateView alloc] init];
  220. [dateV setStyle:0];
  221. [dateV showWithComplete:^(NSString * result) {
  222. //更新UI
  223. theDate = result;
  224. self.title = result;
  225. [_mapView removeAnnotation:sportAnnotation];
  226. [_mapView removeOverlay:polyline];
  227. [sportNodes removeAllObjects];
  228. sportNodeNum = 0;
  229. [self getTrackPlayBack];
  230. }];
  231. }
  232. - (IBAction)speedUpAction:(UIButton *)sender {
  233. if (_playSpeedFactor > 0.1) {
  234. _playSpeedFactor -= 0.1;
  235. }else {
  236. ShowMsg(@"已达最大速度!");
  237. }
  238. }
  239. - (IBAction)slowDownAction:(UIButton *)sender {
  240. if (_playSpeedFactor < 1.9) {
  241. _playSpeedFactor += 0.1;
  242. }else {
  243. ShowMsg(@"已达最小速度!");
  244. }
  245. }
  246. #pragma mark 电子围栏相关
  247. -(void)creatDZWLWithZuoBiaoStr:(NSString *)str{
  248. NSString *newStr = [str stringByReplacingOccurrencesOfString:@"#" withString:@"\""];
  249. NSData *data = [newStr dataUsingEncoding:NSUTF8StringEncoding];
  250. if (!data) {
  251. ShowMsg(@"数据异常,解析失败");
  252. }
  253. NSArray * arr = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
  254. CLLocationCoordinate2D * coords = malloc(arr.count*sizeof(CLLocationCoordinate2D));
  255. for (int i = 0; i < arr.count; i++) {
  256. NSDictionary * locationDic = arr[i];
  257. coords[i].latitude = [locationDic[@"lat"] floatValue];
  258. coords[i].longitude = [locationDic[@"lng"] floatValue];
  259. if (i==1) {
  260. _mapView.centerCoordinate = coords[i];
  261. }
  262. }
  263. polygo = [BMKPolygon polygonWithCoordinates:coords count:arr.count];
  264. [_mapView addOverlay: polygo];
  265. }
  266. #pragma mark - BMKMapViewDelegate
  267. //- (void)mapViewDidFinishLoading:(BMKMapView *)mapView {
  268. // [self addOverlayView];
  269. //}
  270. //根据overlay生成对应的View
  271. - (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay
  272. {
  273. if ([overlay isKindOfClass:[BMKPolyline class]])
  274. {
  275. BMKPolylineView* polygonView = [[BMKPolylineView alloc] initWithOverlay:overlay];
  276. polygonView.strokeColor = [[UIColor blackColor] initWithRed:0.0 green:0.5 blue:0.0 alpha:0.6];
  277. polygonView.lineWidth = 1.5;
  278. return polygonView;
  279. }
  280. if ([overlay isKindOfClass:[BMKPolygon class]]){
  281. BMKPolygonView* polygonView = [[BMKPolygonView alloc] initWithOverlay:overlay];
  282. polygonView.strokeColor = [[UIColor alloc] initWithRed:0.0 green:0 blue:0.5 alpha:1];
  283. polygonView.fillColor = [[UIColor alloc] initWithRed:0 green:1 blue:1 alpha:0.2];
  284. polygonView.lineWidth =2.0;
  285. polygonView.lineDash = YES;//是否为虚线样式 (overlay == polygo)
  286. return polygonView;
  287. }
  288. return nil;
  289. }
  290. // 根据anntation生成对应的View
  291. - (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
  292. {
  293. if (sportAnnotationView == nil) {
  294. sportAnnotationView = [[SportAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"sportsAnnotation"];
  295. sportAnnotationView.draggable = NO;
  296. BMKSportNode *node = [sportNodes firstObject];
  297. sportAnnotationView.imageView.transform = CGAffineTransformMakeRotation(node.angle);
  298. }
  299. return sportAnnotationView;
  300. }
  301. - (void)mapView:(BMKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
  302. [self running];
  303. }
  304. #pragma mark 网络请求
  305. //轨迹
  306. -(void)getTrackPlayBack{
  307. if (![NetManager connectedToNetWork]) {
  308. showMsgUnconnect();
  309. return;
  310. }
  311. NSMutableDictionary *dic = [NSMutableDictionary dictionary];
  312. [dic setObject:self.simStr forKey:@"sim"];
  313. [dic setObject:theDate forKey:@"cdTime"];
  314. NSString *method = @"getTrackPlayBack";
  315. [MBProgressHUD showLoadToView:self.view];
  316. [NetManager requestAnythingWithURL:method dictionary:dic dataArray:nil completion:^(NSDictionary *root) {
  317. [MBProgressHUD hideHUDForView:self.view];
  318. if (!root) {
  319. ShowMsg(@"数据请求失败,请重试");
  320. return;
  321. }
  322. if ([root[@"code"] integerValue] == 1) {
  323. ShowMsg(root[@"msg"]);
  324. return;
  325. }
  326. BOOL isSetCenter = NO;
  327. NSArray *array = root[@"body"];
  328. if (array.count > 0) {
  329. for (NSDictionary *dic in array) {
  330. if ([dic[@"LAT"] length] < 1 || [dic[@"LON"] length] < 1) {
  331. continue;
  332. }
  333. BMKSportNode *sportNode = [[BMKSportNode alloc] init];
  334. sportNode.coordinate = CLLocationCoordinate2DMake([dic[@"LAT"] doubleValue], [dic[@"LON"] doubleValue]);
  335. sportNode.angle = [dic[@"DIRECTION"] doubleValue];
  336. sportNode.distance = [dic[@"MILEAGE"] doubleValue];
  337. sportNode.speed = [dic[@"LOCATIONSPEED"] doubleValue];
  338. [sportNodes addObject:sportNode];//调接口前有做清零
  339. if (!isSetCenter) {
  340. _mapView.centerCoordinate = sportNode.coordinate;
  341. isSetCenter = YES;
  342. }
  343. // NSLog(@"xxxx-- 方向%f 距离%f 速度%f",sportNode.angle,sportNode.distance,sportNode.speed);
  344. }
  345. _playSpeedFactor = 1.0;
  346. sportNodeNum = sportNodes.count;
  347. [self addOverlayView];
  348. }else{
  349. //没有运动轨迹
  350. ShowMsg([NSString stringWithFormat:@"车辆“%@”在%@当天没有轨迹记录,请重新选择日期",self.carNum,self.title]);
  351. }
  352. }];
  353. }
  354. //围栏
  355. -(void)getSchoolRegionList{
  356. if (![NetManager connectedToNetWork]) {
  357. showMsgUnconnect();
  358. return;
  359. }
  360. NSMutableDictionary *dic = [NSMutableDictionary dictionary];
  361. [dic setObject:self.deviceId forKey:@"devid"];
  362. NSString *method = @"getSchoolRegionList";
  363. [MBProgressHUD showLoadToView:self.view];
  364. [NetManager requestAnythingWithURL:method dictionary:dic dataArray:nil completion:^(NSDictionary *root) {
  365. [MBProgressHUD hideHUDForView:self.view];
  366. if (!root) {
  367. ShowMsg(@"数据请求失败,请重试");
  368. return;
  369. }
  370. if ([root[@"code"] integerValue] == 1) {
  371. ShowMsg(root[@"msg"]);
  372. return;
  373. }
  374. NSArray *arr = root[@"body"];
  375. for (NSDictionary *dic in arr) {
  376. [self creatDZWLWithZuoBiaoStr:dic[@"DZWL"]];
  377. }
  378. }];
  379. }
  380. @end