NeighbouringVC.m 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. //
  2. // NeighbouringVC.m
  3. // jiaPei
  4. //
  5. // Created by apple on 2017/6/27.
  6. // Copyright © 2017年 JCZ. All rights reserved.
  7. //
  8. #import "NeighbouringVC.h"
  9. #import "NeighbourTableView.h"
  10. #import "NeighbourCell.h"
  11. #import "NeighbourBMKPointAnnotation.h"
  12. #import "NeighbourBMKAnnotationView.h"
  13. #import "SchDetailVC.h"
  14. #import "SearchBase.h"
  15. #import "ApplyVC.h"
  16. #import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
  17. #import <BMKLocationkit/BMKLocationComponent.h>//引入定位功能所有的头文件(新)
  18. //#import <BaiduMapAPI_Utils/BMKUtilsComponent.h>
  19. #import "BMKClusterManager.h"//点聚合管理类
  20. #define kAlphaNum @"0123456789."//限制输入字符类型
  21. /*
  22. *点聚合Annotation
  23. */
  24. @interface ClusterAnnotation : NeighbourBMKPointAnnotation
  25. ///所包含annotation个数
  26. @property (nonatomic, assign) NSInteger size;
  27. @property (nonatomic, strong) NSArray *dataArr;
  28. @end
  29. @implementation ClusterAnnotation
  30. @synthesize size = _size;
  31. @end
  32. @interface NeighbouringVC ()<BMKMapViewDelegate,BMKLocationManagerDelegate,UITableViewDelegate,UITableViewDataSource,UIGestureRecognizerDelegate,UITextFieldDelegate>
  33. {
  34. BMKMapView *_mapView;
  35. CLLocation *myLocation;
  36. //搜索中心点
  37. BMKPointAnnotation *_movePoint;
  38. BMKPinAnnotationView *_movePointView;
  39. //点聚合
  40. BMKClusterManager *_clusterManager;//点聚合管理类
  41. NSInteger _clusterZoom;//聚合级别
  42. NSMutableArray *_clusterCaches;//点聚合缓存标注
  43. NSArray *_tableVDataSource;//点聚合对应数据
  44. ClusterAnnotation *_currentSelectedAnnotion;
  45. NeighbourTableView *mainTableView;
  46. UIButton *moreBtn;
  47. NSArray *dataArray;
  48. NSString *distanceString;//搜索范围
  49. NSString *searchHistoryDistance;//历史搜索输入记录
  50. CGFloat bothStateMapHeight;
  51. CGFloat mapDisY;
  52. NSInteger tableState; // 1全屏 2半屏 3消失
  53. BOOL isLoading;
  54. UIPanGestureRecognizer *mapPan;
  55. UIPanGestureRecognizer *tableViewPan;
  56. CGFloat bottomBar_height;//底部限制高度
  57. }
  58. @property (nonatomic, strong) NeighbourCell *detailCell;
  59. @property (nonatomic, strong) UIView *btnBar;
  60. @end
  61. @implementation NeighbouringVC
  62. - (void)dealloc{
  63. [_movePointView removeObserver:self forKeyPath:@"dragState"];
  64. }
  65. - (void)viewDidLoad {
  66. [super viewDidLoad];
  67. self.navigationItem.title = @"附近报名点";
  68. self.view.backgroundColor = backGroundColor;
  69. // [self configNavigationBar];
  70. bottomBar_height = _isPushed ? kSafeAreaBottomHeight : kTabBarHeight;
  71. if (_isPushed) {
  72. [self configNavigationBar];
  73. }
  74. [self myInit];
  75. }
  76. -(void)viewWillAppear:(BOOL)animated
  77. {
  78. [super viewWillAppear:animated];
  79. [_mapView viewWillAppear];
  80. _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
  81. if (IOS11) {
  82. mainTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  83. }else{
  84. self.automaticallyAdjustsScrollViewInsets = NO;
  85. }
  86. self.navigationController.navigationBar.translucent = YES;
  87. }
  88. -(void)viewWillDisappear:(BOOL)animated
  89. {
  90. self.navigationController.navigationBar.translucent = NO;
  91. [super viewWillDisappear:animated];
  92. self.hidesBottomBarWhenPushed = NO;
  93. [_mapView viewWillDisappear];
  94. _mapView.delegate = nil; // 不用时,置nil
  95. }
  96. - (void)myInit {
  97. UIBarButtonItem *item = [UIBarButtonItem rq_systemItemWithTitle:@"选择距离" titleColor:defGreen imageName:@"" target:self selector:@selector(changeDistance) textType:YES];
  98. self.navigationItem.rightBarButtonItem = item;
  99. bothStateMapHeight = (kSize.height - kNavOffSet - bottomBar_height)*0.4;
  100. /*
  101. 全屏地图的中心点:kSize.height/2.0 - 50 - bottomBar_height + kNavOffSet;
  102. 半屏地图的中心点:kNavOffSet + bothStateMapHeight/2.0;
  103. 差值:kSize.height/2.0 - 50 - bottomBar_height + kNavOffSet - kNavOffSet - bothStateMapHeight/2.0 =
  104. kSize.height/2.0 - 50 - bottomBar_height - bothStateMapHeight/2.0
  105. */
  106. mapDisY = kSize.height/2.0 - 50 - bottomBar_height - bothStateMapHeight/2.0;
  107. //查看更多地图
  108. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, kSize.height - bottomBar_height - 50 - mapDisY, kSize.width, 50)];
  109. [label setText:@"手指松开查看全屏地图" Font:FontLarger TextColor:kTitleColor Alignment:NSTextAlignmentCenter];
  110. [self.view addSubview:label];
  111. _mapView = [[BMKMapView alloc]initWithFrame:CGRectMake(0, kNavOffSet - mapDisY, kSize.width, kSize.height -kNavOffSet - bottomBar_height - 50)];
  112. _mapView.mapType = BMKMapTypeStandard;
  113. _mapView.showMapScaleBar = YES;
  114. _mapView.userTrackingMode = BMKUserTrackingModeNone;
  115. _mapView.zoomLevel = 14.7;
  116. _mapView.showsUserLocation = YES;
  117. BMKLocationViewDisplayParam *displayParam = [[BMKLocationViewDisplayParam alloc]init];
  118. displayParam.isRotateAngleValid = true;//跟随态旋转角度是否生效
  119. displayParam.isAccuracyCircleShow = false;//精度圈是否显示
  120. displayParam.locationViewOffsetX = 0;//定位偏移量(经度)
  121. displayParam.locationViewOffsetY = 0;//定位偏移量(纬度)
  122. [_mapView updateLocationViewWithParam:displayParam];
  123. [self.view addSubview:_mapView];
  124. //点聚合管理类
  125. _clusterManager = [[BMKClusterManager alloc] init];
  126. [self createClus];//点聚合缓存
  127. mapPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(mapGesTure)];
  128. [_mapView addGestureRecognizer:mapPan];
  129. isLoading = NO;
  130. tableState = 2;
  131. dataArray = [NSArray array];
  132. distanceString = @"3000";
  133. //定位功能
  134. [self getMylocation];
  135. UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
  136. btn.frame = CGRectMake(kSize.width-70, _mapView.height-60, 37, 37);
  137. btn.backgroundColor = [UIColor whiteColor];
  138. [btn setImage:[UIImage imageNamed:@"nei_meLocation.png"] forState:UIControlStateNormal];
  139. btn.contentEdgeInsets = UIEdgeInsetsMake(7, 7, 7, 7);
  140. btn.layer.cornerRadius = 37/2;
  141. btn.layer.shadowOffset = CGSizeMake(2, 2);
  142. btn.layer.shadowRadius = 2;
  143. btn.layer.shadowColor = [UIColor darkGrayColor].CGColor;//shadowColor阴影颜色
  144. btn.layer.shadowOpacity = 0.8;//阴影透明度,默认0
  145. [btn addTarget:self action:@selector(getMylocation) forControlEvents:UIControlEventTouchUpInside];
  146. [_mapView addSubview:btn];
  147. //表
  148. mainTableView = [[NeighbourTableView alloc] initWithFrame:CGRectMake(0, kNavOffSet + bothStateMapHeight, kSize.width, kSize.height - kNavOffSet - bottomBar_height) style:UITableViewStylePlain];
  149. mainTableView.delegate = self;
  150. mainTableView.dataSource = self;
  151. mainTableView.isCanPan = NO;
  152. mainTableView.rowHeight = 125;
  153. mainTableView.tableFooterView = [UIView new];
  154. [self.view addSubview:mainTableView];
  155. tableViewPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(tableViewGesTure:)];
  156. tableViewPan.delegate = self;
  157. [self.view addGestureRecognizer:tableViewPan];
  158. }
  159. - (void)changeDistance {
  160. UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:@"请选择搜索距离" preferredStyle:UIAlertControllerStyleAlert];
  161. UIAlertAction *search1Action = [UIAlertAction actionWithTitle:@"3km" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  162. distanceString = @"3000";
  163. [self getSchPoints];
  164. }];
  165. UIAlertAction *search2Action = [UIAlertAction actionWithTitle:@"4km" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  166. distanceString = @"4000";
  167. [self getSchPoints];
  168. }];
  169. UIAlertAction *search3Action = [UIAlertAction actionWithTitle:@"5km" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  170. distanceString = @"5000";
  171. [self getSchPoints];
  172. }];
  173. UIAlertAction *search4Action = [UIAlertAction actionWithTitle:@"10km" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  174. distanceString = @"10000";
  175. [self getSchPoints];
  176. }];
  177. UIAlertAction *search5Action = [UIAlertAction actionWithTitle:@"自定义 >" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
  178. [self setSearchDistance];
  179. }];
  180. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
  181. [alert addAction:search1Action];
  182. [alert addAction:search2Action];
  183. [alert addAction:search3Action];
  184. [alert addAction:search4Action];
  185. [alert addAction:search5Action];
  186. [alert addAction:cancelAction];
  187. [self presentViewController:alert animated:YES completion:nil];
  188. }
  189. -(void)setSearchDistance{
  190. UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:@"自定义搜索范围" message:@"例如:5.2km以内,则输入“5.2”" preferredStyle:UIAlertControllerStyleAlert];
  191. [alertFind addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
  192. textField.placeholder = @"请输入搜素范围公里数___(km)";
  193. if (searchHistoryDistance) {
  194. textField.placeholder = searchHistoryDistance;
  195. }
  196. textField.delegate = self;
  197. textField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
  198. }];
  199. [alertFind addAction:[UIAlertAction actionWithTitle:@"开始搜索" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  200. UITextField *tf = [alertFind textFields][0];
  201. if ([tf.text floatValue] == 0) {
  202. ShowMsg(@"未输入搜索范围");
  203. return;
  204. }
  205. searchHistoryDistance = tf.text;
  206. NSString *new = [NSString stringWithFormat:@"%lf",[tf.text floatValue]*1000];
  207. if ([new isEqualToString:distanceString]) {
  208. return;
  209. }
  210. distanceString = new;
  211. [self getSchPoints];
  212. }]];
  213. [alertFind addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  214. }]];
  215. [self presentViewController:alertFind animated:true completion:nil];
  216. }
  217. - (void)mapGesTure {
  218. //地图放至最大 表消失
  219. [self setUITableViewDis];
  220. }
  221. - (void)tableViewGesTure:(UIPanGestureRecognizer *)gesture {
  222. //获取滑动的距离 作出表格移动效果 如果向上移动 在最后 做mapDis操作 否则做tabdis操作
  223. CGPoint point = [gesture translationInView:self.view];//相对父视图的所有偏移量
  224. //NSLog(@"point-->(%f,%f)",point.x,point.y);
  225. if (bothStateMapHeight + point.y <= 0.0 || bothStateMapHeight + point.y > kSize.height - kNavOffSet - bottomBar_height - 50) {
  226. //滑到最上或者最下面了 直接调接口吧
  227. if (point.y > 0) {
  228. [self setUITableViewDis];
  229. }else {
  230. [self setUIMapDis];
  231. }
  232. return;
  233. }
  234. if (tableState == 1) {
  235. if (mainTableView.y < kNavOffSet + bothStateMapHeight) {
  236. mainTableView.y = kNavOffSet + 2.4*point.y;
  237. }else {
  238. mainTableView.y = kNavOffSet + point.y;
  239. }
  240. }else if (tableState == 2) {
  241. mainTableView.y = kNavOffSet + bothStateMapHeight + point.y;
  242. }else {
  243. mainTableView.y = CGRectGetMaxY(_mapView.frame);
  244. }
  245. if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateCancelled) {
  246. //滑动结束 判断滑动后最终状态
  247. if (point.y < -10) {
  248. [self setUIMapDis];
  249. }else if (point.y < 10){
  250. [self setUIBothApper];
  251. }else {
  252. [self setUITableViewDis];
  253. }
  254. }
  255. }
  256. - (void)setUIMapDis {
  257. [_mapView removeGestureRecognizer:mapPan];
  258. [self.view removeGestureRecognizer:tableViewPan];
  259. mainTableView.y = kNavOffSet;
  260. mainTableView.isCanPan = YES;
  261. tableState = 1;
  262. }
  263. - (void)setUITableViewDis {
  264. if (_currentSelectedAnnotion && _currentSelectedAnnotion.size > 1) {
  265. [_mapView deselectAnnotation:_currentSelectedAnnotion animated:YES];
  266. }
  267. [_mapView removeGestureRecognizer:mapPan];
  268. [self.view removeGestureRecognizer:tableViewPan];
  269. _mapView.y = kNavOffSet;
  270. mainTableView.y = CGRectGetMaxY(_mapView.frame);
  271. [self addLoadingMore];
  272. tableState = 3;
  273. }
  274. - (void)addLoadingMore {
  275. if (![self.view.subviews containsObject:moreBtn]) {
  276. moreBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, kSize.height - bottomBar_height - 50, kSize.width, 50)];
  277. moreBtn.backgroundColor = [UIColor whiteColor];
  278. [moreBtn setTitle:@"点击展开更多结果" textColor:kTitleColor font:Font17 fotState:UIControlStateNormal];
  279. [moreBtn target:self tag:1];
  280. [self.view addSubview:moreBtn];
  281. }
  282. }
  283. - (void)setUIBothApper {
  284. //移除
  285. if (moreBtn.superview) {
  286. [moreBtn removeFromSuperview];
  287. }
  288. //移除
  289. if ([self.view.subviews containsObject:self.detailCell]) {
  290. [self.detailCell removeFromSuperview];
  291. }
  292. //移除
  293. if ([self.view.subviews containsObject:self.btnBar]) {
  294. [self.btnBar removeFromSuperview];
  295. }
  296. if (mapPan) {
  297. [_mapView addGestureRecognizer:mapPan];
  298. }else {
  299. mapPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(mapGesTure)];
  300. [_mapView addGestureRecognizer:mapPan];
  301. }
  302. if (tableViewPan) {
  303. [self.view addGestureRecognizer:tableViewPan];
  304. }else {
  305. tableViewPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(tableViewGesTure:)];
  306. [self.view addGestureRecognizer:tableViewPan];
  307. }
  308. _mapView.y = kNavOffSet - mapDisY;
  309. mainTableView.y = kNavOffSet + bothStateMapHeight;
  310. mainTableView.isCanPan = NO;
  311. tableState = 2;
  312. }
  313. - (NeighbourCell *)detailCell {
  314. if (!_detailCell) {
  315. _detailCell = [[NeighbourCell alloc] initWithFrame:CGRectMake(0, kSize.height - bottomBar_height - 40 - 125 , kSize.width, 125)];
  316. _detailCell.contentView.backgroundColor = [UIColor whiteColor];
  317. UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0 , kSize.width, 125)];
  318. [btn target:self tag:2];
  319. [_detailCell.contentView addSubview:btn];
  320. }
  321. return _detailCell;
  322. }
  323. - (UIView *)btnBar {
  324. if (!_btnBar) {
  325. _btnBar = [[UIView alloc] initWithFrame:CGRectMake(0, kSize.height - bottomBar_height - 40, kSize.width, 40)];
  326. _btnBar.backgroundColor = [UIColor whiteColor];
  327. NSArray *titleArray = @[@" 电话",@" 搜驾校",@" 报名"];
  328. NSArray *imgArray = @[@"neighbour_tel",@"neighbour_search",@"neighbour_apply"];
  329. [_btnBar addSelfViewWithRect:CGRectMake(0, 0, _btnBar.width, 1) Color:KlineColor];
  330. for (int i = 0; i < titleArray.count; i ++) {
  331. UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(kSize.width/3.0*i, 0, kSize.width/3.0, 40)];
  332. [btn setImage:[UIImage imageNamed:imgArray[i]] withTitle:titleArray[i] Font:FontTitle forState:UIControlStateNormal];
  333. [btn target:self tag:3 + i];
  334. [_btnBar addSubview:btn];
  335. }
  336. }
  337. return _btnBar;
  338. }
  339. - (void)btnClick:(UIButton *)sender {
  340. if (sender.tag == 1) {
  341. if (dataArray.count == 0) {
  342. ShowMsg(@"指定范围没有报名点哦!");
  343. return;
  344. }
  345. _tableVDataSource = dataArray;
  346. [self setUIBothApper];
  347. }
  348. if (sender.tag == 2) {
  349. //跳转至详情页
  350. SchDetailVC *vc = [[SchDetailVC alloc] init];
  351. vc.schoolId = _detailCell.dataDic[@"SCHID"];
  352. [self navPushHideTabbarToVC:vc];
  353. }
  354. //三四五 分别是 电话 找驾校 报名
  355. if (sender.tag == 3) {
  356. //电话
  357. NSString *telephone = _detailCell.dataDic[@"PHONE"];
  358. if (!telephone || telephone.length == 0) {
  359. ShowMsg(@"暂未获取到联系电话");
  360. return;
  361. }
  362. UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:telephone preferredStyle:UIAlertControllerStyleAlert];
  363. UIAlertAction *telAction = [UIAlertAction actionWithTitle:@"呼叫" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  364. NSMutableString * url=[[NSMutableString alloc] initWithFormat:@"tel:%@",telephone];
  365. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
  366. }];
  367. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
  368. [alert addAction:telAction];
  369. [alert addAction:cancelAction];
  370. [self presentViewController:alert animated:YES completion:nil];
  371. }
  372. if (sender.tag == 4) {
  373. SearchBase *vc = [[SearchBase alloc] init];
  374. vc.type = 2;
  375. [self navPushHideTabbarToVC:vc];
  376. }
  377. if (sender.tag == 5) {
  378. ApplyVC *vc = [[ApplyVC alloc] init];
  379. vc.jxbh = _detailCell.dataDic[@"TSP_SCHOOL_ID"];
  380. vc.jxmc = _detailCell.dataDic[@"SCHOOLNAME"];
  381. [self navPushHideTabbarToVC:vc];
  382. }
  383. }
  384. #pragma mark textfiledDelegate
  385. //输入限制
  386. - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
  387. {
  388. //先设置只能输入的集合 invertedSet就是将咱们允许输入的字符串的字符找出
  389. NSCharacterSet *canInputSet = [[NSCharacterSet characterSetWithCharactersInString:kAlphaNum] invertedSet];
  390. //把允许输入的内容转化成数组,再转化成字符串
  391. NSString *str = [[string componentsSeparatedByCharactersInSet:canInputSet] componentsJoinedByString:@""];
  392. //判断输入的字符是否包含在允许输入的字符之内
  393. BOOL isSuccess = [string isEqualToString:str];
  394. //限制文本框输入内容的长度不得超过10且有输入内容的限制
  395. if (textField.text.length <= 5 && isSuccess){
  396. //返回值为YES的时候,文本框可以进行编辑
  397. return YES;
  398. }else{
  399. if (!isSuccess) {
  400. return NO;
  401. }
  402. if (str.length == 0) {
  403. return YES;
  404. }
  405. //str=nil 删除
  406. return NO;
  407. }
  408. }
  409. #pragma mark - 定位
  410. - (void)getMylocation {
  411. [[MapManager sharedManager] updateLocationWithCompleteBlock:^(BOOL success, CLLocation * _Nonnull location) {
  412. if (success) {
  413. [self->_mapView setCenterCoordinate:location.coordinate];
  414. self->myLocation = location;
  415. if (self->dataArray.count == 0) {
  416. [self addMovePointForSearchWith:self->myLocation.coordinate];
  417. //获取报名点信息
  418. [self getSchPoints];
  419. }
  420. }
  421. }];
  422. }
  423. #pragma mark -添加大头针
  424. -(void)addMovePointForSearchWith:(CLLocationCoordinate2D)coordinate{
  425. if (_movePoint) {
  426. if (_movePoint.coordinate.latitude == coordinate.latitude && _movePoint.coordinate.longitude == coordinate.longitude) {
  427. return;
  428. }
  429. _movePoint.coordinate = coordinate;
  430. return;
  431. }
  432. BMKPointAnnotation *point = [[BMKPointAnnotation alloc]init];
  433. _movePoint = point;
  434. point.title = @"在此点附近搜索";
  435. point.subtitle = @"(长按移动位置)";
  436. point.coordinate = coordinate;
  437. [_mapView addAnnotation:point];
  438. }
  439. #pragma mark 地图相关
  440. -(void)createClus{
  441. _clusterCaches = [[NSMutableArray alloc] init];
  442. for (NSInteger i = 3; i < 22; i++) {
  443. [_clusterCaches addObject:[NSMutableArray array]];
  444. }
  445. }
  446. //加标注点
  447. - (void)addAnnotation {
  448. //添加前先清理地图上之前的标注
  449. if (_mapView.annotations.count > 0) {
  450. [_clusterManager clearClusterItems];
  451. [self createClus];
  452. }
  453. [_mapView setCenterCoordinate:_movePoint.coordinate];
  454. for (NSDictionary *dic in dataArray) {
  455. BMKClusterItem *clusterItem = [[BMKClusterItem alloc] init];
  456. CLLocationCoordinate2D coor;
  457. coor = CLLocationCoordinate2DMake([dic[@"TSP_LAT"] floatValue], [dic[@"TSP_LNG"] floatValue]);
  458. if (coor.latitude>53 || coor.latitude<4 || coor.longitude<73 || coor.longitude>135) {
  459. continue;
  460. }
  461. clusterItem.coor = coor;
  462. clusterItem.dataDic = dic;
  463. [_clusterManager addClusterItem:clusterItem];
  464. }
  465. if (_movePoint) {//这个判断。。其实前面是定位成功才会走到这里面的
  466. // 添加圆形覆盖物
  467. [_mapView removeOverlays:_mapView.overlays];
  468. double radius = [distanceString doubleValue];
  469. BMKCircle *circle = [BMKCircle circleWithCenterCoordinate:_movePoint.coordinate radius:radius];
  470. [_mapView addOverlay:circle];
  471. //限制地图显示范围 以下方法只是计算个大概 测试还ok。所以就用了
  472. /*关于经纬度十进制表示法
  473. 对于两个点,在纬度相等的情况下:
  474. 经度每隔0.00001度,距离相差约1米;每隔0.0001度,距离相差约10米;每隔0.001度,距离相差约100米;每隔0.01度,距离相差约1000米;每隔0.1度,距离相差约10000米。
  475. 对于两个点,在经度相等的情况下:
  476. 纬度每隔0.00001度,距离相差约1.1米;每隔0.0001度,距离相差约11米;每隔0.001度,距离相差约111米;每隔0.01度,距离相差约1113米;每隔0.1度,距离相差约11132米。*/
  477. _mapView.maxZoomLevel = 21;
  478. _mapView.minZoomLevel = 3;
  479. CLLocationCoordinate2D center = _movePoint.coordinate;
  480. radius *= 1.3;
  481. CLLocationCoordinate2D left = CLLocationCoordinate2DMake(center.latitude-radius*0.00001, center.longitude);
  482. CLLocationCoordinate2D right = CLLocationCoordinate2DMake(center.latitude+radius*0.00001, center.longitude);
  483. BMKPointAnnotation *leftAn = [[BMKPointAnnotation alloc]init];
  484. leftAn.coordinate = left;
  485. BMKPointAnnotation *rightAN = [[BMKPointAnnotation alloc]init];
  486. rightAN.coordinate = right;
  487. [_mapView showAnnotations:@[leftAn,rightAN] animated:YES];
  488. }
  489. [self updateClusters];
  490. }
  491. //更新聚合状态
  492. - (void)updateClusters {
  493. _clusterZoom = (NSInteger)_mapView.zoomLevel;
  494. @synchronized(_clusterCaches) {
  495. __block NSMutableArray *clusters = [_clusterCaches objectAtIndex:_clusterZoom - 3];
  496. if (clusters.count > 0) {
  497. [self removeAnnotations];
  498. [_mapView addAnnotations:clusters];
  499. } else {
  500. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  501. ///获取聚合后的标注
  502. __block NSArray *array = [_clusterManager getClusters:_clusterZoom];
  503. if (array.count == 0) {
  504. return;
  505. }
  506. dispatch_async(dispatch_get_main_queue(), ^{
  507. for (BMKCluster *item in array) {
  508. ClusterAnnotation *annotation = [[ClusterAnnotation alloc] init];
  509. annotation.coordinate = item.coordinate;
  510. annotation.size = item.size;
  511. annotation.dataDic = item.dataDic;
  512. annotation.dataArr = item.dataArr;
  513. [clusters addObject:annotation];
  514. }
  515. [self removeAnnotations];
  516. [_mapView addAnnotations:clusters];
  517. [_clusterCaches replaceObjectAtIndex:_clusterZoom - 3 withObject:clusters];
  518. });
  519. });
  520. }
  521. }
  522. }
  523. //根据overlay生成对应的View
  524. - (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id <BMKOverlay>)overlay
  525. {
  526. if ([overlay isKindOfClass:[BMKCircle class]])
  527. {
  528. BMKCircleView* circleView = [[BMKCircleView alloc] initWithOverlay:overlay];
  529. circleView.fillColor = [UIColor colorWithRed:35/255.0 green:160/255.0 blue:227/255.0 alpha:0.1];
  530. // circleView.strokeColor = [UIColor lightGrayColor];
  531. // circleView.lineWidth = 0.5;
  532. return circleView;
  533. }
  534. return nil;
  535. }
  536. //标注的代理
  537. -(BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation
  538. {
  539. //普通annotation
  540. if (annotation == _movePoint) {
  541. NSString *AnnotationViewID = @"renameMark";
  542. BMKPinAnnotationView *annotationView = (BMKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
  543. if (annotationView == nil) {
  544. annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
  545. _movePointView = annotationView;
  546. // 设置颜色
  547. annotationView.pinColor = BMKPinAnnotationColorPurple;
  548. // 设置可拖拽
  549. annotationView.draggable = YES;
  550. [annotationView addObserver:self forKeyPath:@"dragState" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
  551. }
  552. return annotationView;
  553. }
  554. if ([annotation isKindOfClass:[NeighbourBMKPointAnnotation class]]) {
  555. NeighbourBMKAnnotationView *view = [NeighbourBMKAnnotationView annotationViewWithMapView:mapView Annotation:(BMKPointAnnotation *)annotation];
  556. view.block = ^(NeighbourBMKPointAnnotation *clickedAnnotation) {
  557. NSDictionary *dic = clickedAnnotation.dataDic;
  558. BMKOpenDrivingRouteOption *opt = [[BMKOpenDrivingRouteOption alloc] init];
  559. opt.appScheme = @"baidumapsdk://mapsdk.baidu.com";
  560. opt.isSupportWeb = YES;//调起百度地图客户端失败后,是否支持调起web地图,默认:YES
  561. //指定起点
  562. BMKPlanNode *start = [[BMKPlanNode alloc]init];
  563. start.pt = myLocation.coordinate;
  564. opt.startPoint = start;
  565. //指定终点名称
  566. BMKPlanNode *end = [[BMKPlanNode alloc]init];
  567. end.pt = CLLocationCoordinate2DMake([dic[@"TSP_LAT"] floatValue], [dic[@"TSP_LNG"] floatValue]);
  568. opt.endPoint = end;
  569. BMKOpenErrorCode code = [BMKOpenRoute openBaiduMapDrivingRoute:opt];
  570. if (code == 1 || code == 0) {
  571. }else{
  572. ShowMsg(@"打开百度地图失败");
  573. }
  574. };
  575. ClusterAnnotation *cluster = (ClusterAnnotation*)annotation;
  576. view.annotation = cluster;//这一步如果不写的话 拿到的view。annotation == nil;按道理是应该在前面获取view的地方已经传入了annotation
  577. view.size = cluster.size;//size依赖annotati的值
  578. return view;
  579. }
  580. return nil;
  581. }
  582. /**
  583. * 当选中一个annotation views时,调用此接口
  584. * @param mapView 地图View
  585. * @param views 选中的annotation views
  586. */
  587. - (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view
  588. {
  589. //NeighbourBMKAnnotationView 点击处理
  590. if ([view isKindOfClass:[NeighbourBMKAnnotationView class]]) {
  591. _currentSelectedAnnotion = (ClusterAnnotation *)view.annotation;
  592. [self setUITableViewDis];
  593. ClusterAnnotation *annotation = (ClusterAnnotation *)view.annotation;
  594. if (annotation.dataArr.count > 1) {
  595. _tableVDataSource = annotation.dataArr;
  596. [mainTableView reloadData];
  597. [self setUIBothApper];
  598. return;
  599. }else{
  600. NeighbourBMKPointAnnotation *annotation = (NeighbourBMKPointAnnotation *)view.annotation;
  601. if (![self.view.subviews containsObject:self.detailCell]) {
  602. //不知道为什么初始化时候的设置没起到作用
  603. self.detailCell.frame = CGRectMake(0, kSize.height - bottomBar_height - 40 - 125 , kSize.width, 125);
  604. [self.view addSubview:self.detailCell];
  605. }
  606. self.detailCell.dataDic = annotation.dataDic;
  607. if (![self.view.subviews containsObject:self.btnBar]) {
  608. [self.view addSubview:self.btnBar];
  609. }
  610. }
  611. }
  612. }
  613. /**
  614. *地图初始化完毕时会调用此接口
  615. *@param mapView 地图View
  616. */
  617. - (void)mapViewDidFinishLoading:(BMKMapView *)mapView {
  618. [self updateClusters];
  619. }
  620. /**
  621. * 选中气泡调用方法
  622. * @param mapView 地图
  623. * @param view annotation
  624. */
  625. - (void)mapView:(BMKMapView *)mapView annotationViewForBubble:(BMKAnnotationView *)view
  626. {
  627. if (view == _movePointView) {
  628. [_mapView deselectAnnotation:view.annotation animated:YES];
  629. [self changeDistance];
  630. return;
  631. }
  632. if ([view isKindOfClass:[NeighbourBMKAnnotationView class]]) {
  633. ClusterAnnotation *annotation = (ClusterAnnotation *)view.annotation;
  634. NSDictionary *dic = annotation.dataDic;
  635. SchDetailVC *vc = [[SchDetailVC alloc] init];
  636. vc.schoolId = dic[@"SCHID"];
  637. [self navPushHideTabbarToVC:vc];
  638. }
  639. }
  640. /**
  641. *地图渲染每一帧画面过程中,以及每次需要重绘地图时(例如添加覆盖物)都会调用此接口
  642. *@param mapView 地图View
  643. *@param status 此时地图的状态
  644. */
  645. - (void)mapView:(BMKMapView *)mapView onDrawMapFrame:(BMKMapStatus *)status {
  646. if (_clusterZoom != 0 && _clusterZoom != (NSInteger)mapView.zoomLevel) {
  647. [self updateClusters];
  648. }
  649. }
  650. - (void)mapView:(BMKMapView *)mapView onClickedMapBlank:(CLLocationCoordinate2D)coordinate{
  651. //移除
  652. if ([self.view.subviews containsObject:self.detailCell]) {
  653. [self.detailCell removeFromSuperview];
  654. }
  655. if ([self.view.subviews containsObject:self.btnBar]) {
  656. [self.btnBar removeFromSuperview];
  657. }
  658. [self setUITableViewDis];
  659. }
  660. //移除anantions
  661. - (void)removeAnnotations{
  662. NSMutableArray *annotations = [NSMutableArray arrayWithArray:_mapView.annotations];
  663. if ([annotations containsObject:_movePoint]) {
  664. [annotations removeObject:_movePoint];
  665. }
  666. [_mapView removeAnnotations:annotations];
  667. }
  668. #pragma mark - 监听movePoint的拖动状态
  669. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
  670. if([keyPath isEqualToString:@"dragState"])
  671. {
  672. // NSLog(@"赋值后--%lu",(unsigned long)_movePointView.dragState);
  673. // NSLog(@"新的值--%@",change[@"new"]);
  674. // NSLog(@"以前的值--%@",change[@"old"]);
  675. NSString *new = [NSString stringWithFormat:@"%@",change[@"new"]];
  676. NSString *old = [NSString stringWithFormat:@"%@",change[@"old"]];
  677. if ([new integerValue] == BMKAnnotationViewDragStateEnding && [old integerValue] == BMKAnnotationViewDragStateDragging) {
  678. [_mapView selectAnnotation:_movePoint animated:YES];
  679. }
  680. }
  681. }
  682. #pragma mark tableview
  683. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  684. return _tableVDataSource.count;
  685. }
  686. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  687. NeighbourCell *cell = [tableView dequeueReusableCellWithIdentifier:@"neighbourCell"];
  688. if (cell == nil) {
  689. cell = [[NeighbourCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"neighbourCell"];
  690. }
  691. cell.dataDic = _tableVDataSource[indexPath.row];
  692. return cell;
  693. }
  694. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  695. NSDictionary *dic = _tableVDataSource[indexPath.row];
  696. SchDetailVC *vc = [[SchDetailVC alloc] init];
  697. vc.schoolId = dic[@"SCHID"];
  698. [self navPushHideTabbarToVC:vc];
  699. }
  700. #pragma mark 数据请求
  701. -(void)getSchPoints
  702. {
  703. [self setUITableViewDis];
  704. if ([distanceString floatValue] == 0) {
  705. return;
  706. }
  707. if (![Util connectedToNetWork]) {
  708. showMsgUnconnect();
  709. return;
  710. }
  711. if (isLoading) {
  712. return;
  713. }
  714. isLoading = YES;
  715. NSMutableArray *arr=[NSMutableArray array];
  716. [arr addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f",_movePoint.coordinate.latitude] ,@"lat", nil]];
  717. [arr addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%f",_movePoint.coordinate.longitude] ,@"lng", nil]];
  718. [arr addObject:[NSDictionary dictionaryWithObjectsAndKeys:distanceString,@"mile", nil]];
  719. NSString* method = @"getSchPoints";
  720. [MBProgressHUD showMessage:@"正在搜索报名点..." toView:self.view];
  721. self.navigationItem.rightBarButtonItem.enabled = NO;
  722. [jiaPeiManager requestAnythingWithURL:method array:arr data:nil completion:^(NSDictionary * root) {
  723. self.navigationItem.rightBarButtonItem.enabled = YES;
  724. [MBProgressHUD hideHUDForView:self.view];
  725. isLoading = NO;
  726. if (!root)
  727. {
  728. ShowMsgFailed();
  729. return;
  730. }
  731. if ( 1 == [root[@"code"] integerValue]) {
  732. ShowMsg(root[@"body"]);
  733. return;
  734. }
  735. if ([root[@"body"] isKindOfClass:[NSString class]]) {
  736. NSString *string = root[@"body"];
  737. NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
  738. NSError *error;
  739. dataArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
  740. }else {
  741. dataArray = [NSArray arrayWithArray:root[@"body"]];
  742. }
  743. //NSLog(@"附近的报名点-----><>%@",dataArray);
  744. if ([dataArray isKindOfClass:[NSArray class]]) {
  745. if (dataArray.count!=0) {
  746. [self setUIBothApper];
  747. }else{
  748. ShowMsg(@"附近暂无报名点");
  749. [self setUITableViewDis];
  750. }
  751. _tableVDataSource = dataArray;
  752. [mainTableView reloadData];
  753. [self addAnnotation];
  754. }
  755. /*
  756. {"PRICE":"2980", 价格
  757. "TSP_MEMO":"价格5500", 备注
  758. "STAR":"4", 报名点星级
  759. "TSP_LOGOUT":"0",
  760. "DIS":"3198.5", 距离
  761. "SCHOOLNAME":"沈阳市八棵树汽车驾驶员培训有限公司",
  762. "WATCH":"799", 关注度
  763. "PHONE":"15960109842", 电话
  764. "TSP_LNG":"119.268745", 经度
  765. "SHORTNAME":"沈阳八棵树驾校", 驾校简称
  766. "TSP_NAME":"软件园报名点", 报名点名称
  767. "TSP_ADDRESS":"福州市鼓楼区软件园B区12号楼", 地址
  768. "TSP_ID":"10042",
  769. "TSP_LAT":"26.115313", 纬度
  770. "TSP_SCHOOL_ID":"2101000003"}。 驾校ID
  771. */
  772. //将附近点加入标注 并且刷新表
  773. }];
  774. }
  775. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  776. // NSLog(@"scroll-->>%f-%f",scrollView.contentOffset.x,scrollView.contentOffset.y);
  777. if (scrollView.contentOffset.y < -70) {
  778. [UIView animateWithDuration:.3 animations:^{
  779. mainTableView.y = kNavOffSet + bothStateMapHeight;
  780. } completion:^(BOOL finished) {
  781. [self setUIBothApper];
  782. }];
  783. }
  784. }
  785. - (void)didReceiveMemoryWarning {
  786. [super didReceiveMemoryWarning];
  787. NSLog(@"didReceiveMemoryWarning BMKMap");
  788. }
  789. @end