JCAddMapViewController.mm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*
  2. *
  3. 1、地理编码指的是将地址位置(中文地址)转换成经纬度,反地理编码指的是将经纬度转换成地址位置;
  4. 2、在百度地图中需要用到三个关键性的类:BMKGeoCodeSearch、BMKGeoCodeSearchOption、BMKReverseGeoCodeOption;
  5. 3、BMKGeoCodeSearch:地理编码主类,用来查询、返回结果信息(地址位置或经纬度);
  6. 4、BMKGeoCodeSearchOption:地理编码选项,即地理编码的数据模型,地址是通过该类传递进去的;
  7. 5、BMKReverseGeoCodeOption:反地理编码选项,即反地理编码的数据模型,经纬度就是通过该类传递进去的;
  8. 6、有了以上基本信息,开始做一个简单的示例:从手机页面上输入经纬度通过按钮事件将对应的地理位置输出到手机屏幕,反之亦然;
  9. *
  10. */
  11. #import "JCAddMapViewController.h"
  12. #define kScreenWidth [UIScreen mainScreen].bounds.size.width
  13. #define kScreenHeight [UIScreen mainScreen].bounds.size.height
  14. @interface JCAddMapViewController () <BMKMapViewDelegate, BMKLocationManagerDelegate, BMKGeoCodeSearchDelegate>
  15. {
  16. BMKMapView* mapView;//地图视图
  17. BMKLocationManager *locManager; //定位
  18. BMKPointAnnotation *pointAnnotation; // 一开始显示的大头针
  19. BOOL annotaionShow; // 使大头针仅显示一个
  20. UIPanGestureRecognizer *mapViewPan;
  21. BOOL mapPanGestureRecognizer; // 使地图仅在拖动停止时显示周边信息
  22. UIButton *locationBtn; //返回原定位坐标点按钮
  23. UITableView *myTableView;
  24. NSMutableArray *addressDataArray;
  25. NSString *_latitude; // 最终选择的坐标
  26. NSString *_longitude; // 最终选择的坐标
  27. NSString *_address; // 最终选择的地址
  28. NSString *_name; // 最终选择的名称
  29. NSString *_city; // 最终选择的城市
  30. NSString *screenAddress; // 筛选重复地址
  31. BMKGeoCodeSearch *_geoCodeSearch;
  32. }
  33. @end
  34. @implementation JCAddMapViewController
  35. - (void)viewDidLoad {
  36. [super viewDidLoad];
  37. self.title = @"位置";
  38. self.view.backgroundColor = [UIColor whiteColor];
  39. addressDataArray = [NSMutableArray arrayWithCapacity:1];
  40. mapPanGestureRecognizer = NO;
  41. [self loadMapView];
  42. if (!_isOnlyShowMap) {
  43. [self loadAddressTableView];
  44. }
  45. }
  46. - (void)viewWillAppear:(BOOL)animated {
  47. [super viewWillAppear:animated];
  48. mapView.delegate = self;
  49. }
  50. - (void)dealloc {
  51. mapView.delegate = nil;
  52. locManager.delegate = nil;
  53. _geoCodeSearch.delegate = nil;
  54. }
  55. #pragma mark - baiduMap
  56. - (void)loadMapView {
  57. annotaionShow = NO;
  58. if (_isOnlyShowMap) {
  59. mapView = [[BMKMapView alloc]initWithFrame:CGRectMake(0, 64, kScreenWidth, kScreenHeight)];
  60. } else {
  61. mapView = [[BMKMapView alloc]initWithFrame:CGRectMake(0, 64, kScreenWidth, kScreenHeight/2)];
  62. UIImageView *labelImage = [[UIImageView alloc] initWithFrame:CGRectMake((kScreenWidth-25 )/2, kScreenHeight/4-33, 25, 33)];
  63. labelImage.image = [UIImage imageNamed:@"icon_baidu_marker"];
  64. [mapView addSubview:labelImage];
  65. locationBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  66. locationBtn.frame = CGRectMake(10, kScreenHeight/2-60, 50, 50);
  67. locationBtn.backgroundColor = [UIColor lightGrayColor];
  68. [locationBtn setTitle:@"定位" forState:UIControlStateNormal];
  69. [locationBtn addTarget:self action:@selector(locationBtnClick) forControlEvents:UIControlEventTouchUpInside];
  70. [mapView addSubview:locationBtn];
  71. locationBtn.hidden = YES;
  72. }
  73. mapView.zoomLevel = 19;
  74. mapView.logoPosition = BMKLogoPositionRightBottom;
  75. mapView.userTrackingMode = BMKUserTrackingModeFollow;
  76. [self.view addSubview:mapView];
  77. mapViewPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panEd:)];
  78. [mapView addGestureRecognizer:mapViewPan];
  79. // 定位
  80. locManager = [[BMKLocationManager alloc]init];
  81. locManager.delegate = self;
  82. //启动LocationService
  83. [locManager startUpdatingLocation];
  84. }
  85. // 使屏幕显示坐标回到大头针位置
  86. - (void)locationBtnClick {
  87. CLLocationCoordinate2D coor;
  88. coor = pointAnnotation.coordinate;
  89. BMKCoordinateRegion region;
  90. region.center.latitude = coor.latitude;
  91. region.center.longitude = coor.longitude;
  92. region.span.latitudeDelta = 0;
  93. region.span.longitudeDelta = 0;
  94. [UIView animateWithDuration:1 animations:^{
  95. mapView.region = region;
  96. }];
  97. }
  98. #pragma mark 百度地图delegate
  99. // 标注大头针
  100. - (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
  101. {
  102. if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
  103. BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"];
  104. newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
  105. newAnnotationView.animatesDrop = YES;// 设置该标注点动画显示
  106. return newAnnotationView;
  107. }
  108. return nil;
  109. }
  110. // 使地图仅在拖动停止时显示周边信息
  111. - (void)panEd:(UIPanGestureRecognizer *)pan {
  112. mapPanGestureRecognizer = YES;
  113. [mapView removeGestureRecognizer:mapViewPan];
  114. }
  115. // 当地图停止拖动时显示周边信息
  116. - (void)mapView:(BMKMapView *)view regionDidChangeAnimated:(BOOL)animated {
  117. if (!mapPanGestureRecognizer) {
  118. return;
  119. }
  120. // 把停止拖动时地图的中心点转换成大头针的经纬度
  121. BMKCoordinateRegion region = (BMKCoordinateRegion)view.region;
  122. //——————————初始化反地理编码类————————————
  123. //注意:必须先初始化地理编码类
  124. _geoCodeSearch = [[BMKGeoCodeSearch alloc]init];
  125. _geoCodeSearch.delegate = self;
  126. //初始化反地理编码类
  127. BMKReverseGeoCodeSearchOption *reverseGeoCodeOption = [[BMKReverseGeoCodeSearchOption alloc] init];
  128. //需要反地理编码的坐标位置
  129. reverseGeoCodeOption.location = CLLocationCoordinate2DMake(region.center.latitude, region.center.longitude);
  130. // 调用反地址编码方法,让其在代理方法中输出
  131. BOOL flag = [_geoCodeSearch reverseGeoCode:reverseGeoCodeOption];
  132. if (!flag) {
  133. [locManager startUpdatingLocation];
  134. }
  135. }
  136. // 定位
  137. //处理位置坐标更新
  138. - (void)BMKLocationManager:(BMKLocationManager * _Nonnull)manager didUpdateLocation:(BMKLocation * _Nullable)location orError:(NSError * _Nullable)error
  139. {
  140. [locManager stopUpdatingLocation];
  141. NSLog(@"当前的坐标是: %f,%f",location.location.coordinate.latitude,location.location.coordinate.longitude);
  142. //注意:必须先初始化地理编码类
  143. _geoCodeSearch = [[BMKGeoCodeSearch alloc]init];
  144. _geoCodeSearch.delegate = self;
  145. BMKReverseGeoCodeSearchOption *reverseGeoCodeOption = [[BMKReverseGeoCodeSearchOption alloc] init];
  146. //需要反地理编码的坐标位置
  147. reverseGeoCodeOption.location = CLLocationCoordinate2DMake(location.location.coordinate.latitude, location.location.coordinate.longitude);
  148. // 调用反地址编码方法,让其在代理方法中输出
  149. BOOL flag = [_geoCodeSearch reverseGeoCode:reverseGeoCodeOption];
  150. if (!flag) {
  151. [locManager startUpdatingLocation];
  152. }else {
  153. }
  154. }
  155. #pragma mark 代理方法返回反地理编码结果
  156. - (void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeSearchResult *)result errorCode:(BMKSearchErrorCode)error
  157. {
  158. if (result) {
  159. [addressDataArray removeAllObjects];
  160. screenAddress = [NSString stringWithFormat:@"%@%@", result.addressDetail.streetName, result.addressDetail.streetNumber];
  161. _address = result.address;
  162. _name = result.addressDetail.streetName;
  163. _city = result.addressDetail.city;
  164. _latitude = [NSString stringWithFormat:@"%f", result.location.latitude];
  165. _longitude = [NSString stringWithFormat:@"%f", result.location.longitude];
  166. NSDictionary *dic = @{@"address":_address,@"name": _name, @"locationX":_latitude, @"locationY":_longitude, @"city":_city};
  167. [addressDataArray addObject:dic];
  168. }else{
  169. NSLog(@"找不到相对应的位置信息");
  170. }
  171. // 获取坐标周边信息
  172. int i = 0;
  173. for(BMKPoiInfo *poiInfo in result.poiList)
  174. {
  175. NSDictionary *dic = @{@"address":poiInfo.address, @"name":poiInfo.name, @"locationX":[NSString stringWithFormat:@"%f", poiInfo.pt.latitude], @"locationY":[NSString stringWithFormat:@"%f", poiInfo.pt.longitude], @"city":poiInfo.city};
  176. [addressDataArray addObject:dic];
  177. i++;
  178. if (i==result.poiList.count) {
  179. if (!annotaionShow) {
  180. annotaionShow = YES;
  181. locationBtn.hidden = NO;
  182. // 地图定位显示
  183. BMKCoordinateRegion region;
  184. if (_isOnlyShowMap) {
  185. region.center.latitude = _lat;
  186. region.center.longitude = _lon;
  187. } else {
  188. region.center.latitude = [_latitude doubleValue];
  189. region.center.longitude = [_longitude doubleValue];
  190. }
  191. region.span.latitudeDelta = 0;
  192. region.span.longitudeDelta = 0;
  193. [UIView animateWithDuration:1 animations:^{
  194. mapView.region = region;
  195. }];
  196. // 一开始显示的(大头针)
  197. pointAnnotation = [[BMKPointAnnotation alloc]init];
  198. CLLocationCoordinate2D coor;
  199. if (_isOnlyShowMap) {
  200. coor.latitude = _lat;
  201. coor.longitude = _lon;
  202. } else {
  203. coor.latitude = [_latitude doubleValue];
  204. coor.longitude = [_longitude doubleValue];
  205. }
  206. pointAnnotation.coordinate = coor;
  207. pointAnnotation.title = _name;
  208. [mapView addAnnotation:pointAnnotation];
  209. }
  210. [myTableView reloadData];
  211. }
  212. }
  213. }
  214. #pragma mark 地图底部tableView数据展示
  215. - (void)loadAddressTableView {
  216. myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, mapView.frame.origin.y+mapView.frame.size.height, kScreenWidth, kScreenHeight-mapView.frame.size.height-64) style:UITableViewStylePlain];
  217. myTableView.delegate = self;
  218. myTableView.dataSource = self;
  219. [self.view addSubview:myTableView];
  220. }
  221. #pragma mark - TableView delegate
  222. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  223. if (myTableView.contentOffset.y > 0) {
  224. [tableView setContentOffset:CGPointMake(0,0) animated:YES];
  225. }
  226. return addressDataArray.count;
  227. }
  228. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  229. return 60;
  230. }
  231. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  232. static NSString *identifier = @"cellId";
  233. AddMapTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
  234. if (cell == nil) {
  235. NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"AddMapTableViewCell" owner:nil options:nil];
  236. for (id oneObject in nib) {
  237. if ([oneObject isKindOfClass:[AddMapTableViewCell class]]) {
  238. cell = (AddMapTableViewCell *)oneObject;
  239. }
  240. }
  241. cell.selectionStyle = UITableViewCellSelectionStyleNone;
  242. }
  243. cell.cellImage.image = [UIImage imageNamed:@"定位2.png"];
  244. cell.cellLabelText.text = [addressDataArray[indexPath.row] objectForKey:@"name"];
  245. cell.cellDetailTextLabelText.text = [addressDataArray[indexPath.row] objectForKey:@"address"];
  246. if (indexPath.row == 0) {
  247. cell.cellImage.image = [UIImage imageNamed:@"定位1.png"];
  248. cell.cellLabelText.textColor = [UIColor orangeColor];
  249. cell.cellDetailTextLabelText.textColor = [UIColor orangeColor];
  250. }
  251. return cell;
  252. }
  253. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  254. NSDictionary *dic = addressDataArray[indexPath.row];
  255. _address = [dic objectForKey:@"address"];
  256. _name = [dic objectForKey:@"name"];
  257. _city = [dic objectForKey:@"city"];
  258. _latitude = [dic objectForKey:@"locationX"];
  259. _longitude = [dic objectForKey:@"locationY"];
  260. [self back];
  261. }
  262. - (void)back {
  263. if (_address!= nil && _latitude!= nil && _longitude!= nil && _city!= nil) {
  264. if (_name == nil) {
  265. _name = _address;
  266. }
  267. NSDictionary *dic = @{@"address":_address,@"name":_name, @"lat":_latitude, @"lon":_longitude, @"city":_city};
  268. if (self.addressBlock) {
  269. self.addressBlock(dic);
  270. }
  271. }
  272. [self.navigationController popViewControllerAnimated:YES];
  273. }
  274. @end