代码中包含大头针,定位等
一切尽在Demo中,第一次觉得百度地图的API写得是如此的好!
//
// YSPartyMapVC.m
// YSBaseProject
//
// Created by YuanWei on 2018/8/14.
// Copyright © 2018年 YunShuWeiLai. All rights reserved.
//
#import "YSPartyMapVC.h"
#import "YSPartyBranchInfoVC.h"
/// Model
#import "YSMapDeptModel.h"
/// View
#import "YSSearchView.h"
/// Tool
#import <BaiduMapAPI_Map/BMKMapComponent.h>
#import <BaiduMapAPI_Location/BMKLocationComponent.h>
#import <BaiduMapAPI_Map/BMKPointAnnotation.h>
#import <BaiduMapAPI_Map/BMKLocationViewDisplayParam.h>
//#import <BaiduMapAPI_Search/BMKSearchComponent.h>
@interface YSPartyMapVC () <UIGestureRecognizerDelegate, BMKMapViewDelegate, BMKLocationServiceDelegate>
{
BMKLocationService *_locService; //定位服务
BMKUserLocation *_userLocation;//用户当前位置
CLLocationCoordinate2D _mapCenterCoor;//地图中心坐标
CLLocationCoordinate2D _tempCenter;// 临时的中心坐标
}
/**
* XIB视图
*/
// 基本地图视
@property (weak, nonatomic) IBOutlet BMKMapView *mapView;
// 定位按钮
@property (weak, nonatomic) IBOutlet UIButton *locationBtn;
// 底部视图
@property (weak, nonatomic) IBOutlet UIView *bottomView;
/**
* 自定义视图
*/
/** 搜索框 */
@property (nonatomic, strong) YSSearchView *searchView;
/**
* 数据源
*/
/** 组织数据源 */
@property (nonatomic, strong) NSArray *deptModelArr;
// 组织名称数据源,用于查找当前选中的大头针在 deptModelArr 中的位置
@property (nonatomic, strong) NSMutableArray *deptNameArr;
/** 临时选中的组织模型 */
@property (nonatomic, strong) YSMapDeptModel *tempModel;
@end
@implementation YSPartyMapVC
- (void)dealloc {
if (_mapView) {
_mapView = nil;
}
}
- (void)viewWillAppear:(BOOL)animated {
[_mapView viewWillAppear];
_mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
_locService.delegate = self;
}
- (void)viewWillDisappear:(BOOL)animated {
[_mapView viewWillDisappear];
_mapView.delegate = nil; // 不用时,置nil
_locService.delegate = nil;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
[_bottomView setHidden:YES];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title = @"党建地图";
[self setUpUI];
[self getUserLocation];
//[self addCustomGestures];//添加自定义的手势
}
// UI初始化
- (void)setUpUI {
// 设置mapView
_mapView.buildingsEnabled = YES;//设定地图是否现显示3D楼块效果
_mapView.overlookEnabled = YES; //设定地图View能否支持俯仰角
_mapView.showMapScaleBar = YES; // 设定是否显式比例尺
//_mapView.overlooking = -45;// 地图俯视角度,在手机上当前可使用的范围为-45~0度
//_mapView.zoomLevel = 12;//设置放大级别
// 这里设置默认中心点为自贡市坐标(lat:29.359157, long:104.776071)
BMKMapStatus *status = [[BMKMapStatus alloc] init];
status.fLevel = 15;
status.targetGeoPt = CLLocationCoordinate2DMake(29.359157, 104.776071);
[_mapView setMapStatus:status];
_mapView.userTrackingMode = BMKUserTrackingModeNone;//设置定位的状态
_mapView.showsUserLocation = YES;//显示定位图层
}
//用户位置定位
- (void)getUserLocation {
_userLocation = [[BMKUserLocation alloc] init];
_locService = [[BMKLocationService alloc] init];
_locService.delegate = self;
//设定定位的最小更新距离,这里设置 100m 定位一次,频繁定位会增加耗电量
_locService.distanceFilter = 100;
//设定定位精度(百米)
_locService.desiredAccuracy = kCLLocationAccuracyHundredMeters;
//开启定位服务
[_locService startUserLocationService];
// LocationView在mapview上显示的层级
BMKLocationViewDisplayParam *userlocationStyle = [[BMKLocationViewDisplayParam alloc] init];
userlocationStyle.isRotateAngleValid = YES;
userlocationStyle.isAccuracyCircleShow = NO;
}
#pragma mark - * * * * * action * * * * *
// 定位按钮事件
- (IBAction)locationBtnAction:(UIButton *)sender {
// YSLog(@"定位按钮事件:进入普通定位态");
if (_userLocation) {
[_mapView setCenterCoordinate:_userLocation.location.coordinate];// 设置为当前地图的中心点
}
//[_locService startUserLocationService];
}
// 底部视图事件
- (IBAction)bottomBtnAction:(UIButton *)sender {
// 拨打电话
if (sender.tag == 101) {
NSString *phoneNumber = [NSString stringWithFormat:@"tel:%@", _tempModel.phone];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];
}
// 支部详情
else {
}
}
// 自定义精度圈
//- (void)customLocationAccuracyCircle {
// BMKLocationViewDisplayParam *param = [[BMKLocationViewDisplayParam alloc] init];
// param.accuracyCircleStrokeColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.5];
// param.accuracyCircleFillColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.3];
// [_mapView updateLocationViewWithParam:param];
//}
#pragma mark - * * * * * BMKMapViewDelegate * * * * *
// 地图初始化完毕时会调用此接口
- (void)mapViewDidFinishLoading:(BMKMapView *)mapView {
YSLog(@"地图加载完成");
}
// 点中底图空白处会回调此接口
- (void)mapView:(BMKMapView *)mapView onClickedMapBlank:(CLLocationCoordinate2D)coordinate {
YSLog(@"地图视图:单击空白");
}
// 双击地图时会回调此接口
- (void)mapview:(BMKMapView *)mapView onDoubleClick:(CLLocationCoordinate2D)coordinate {
YSLog(@"地图视图:双击");
}
// 当取消选中一个大头针时,调用此接口
- (void)mapView:(BMKMapView *)mapView didDeselectAnnotationView:(BMKAnnotationView *)view {
[_bottomView setHidden:YES];
_tempModel = nil;
}
// 当选中一个大头针时,调用此接口
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view {
YSLog(@"选中了大头针");
// 获取大头针的坐标
//self.coor = view.annotation.coordinate;
[_bottomView setHidden:NO];
// 刷新尾部视图数据
BMKPointAnnotation *annotation = view.annotation;
NSString *obj = [NSString stringWithFormat:@"%@%.5f%.5f", annotation.title, annotation.coordinate.latitude, annotation.coordinate.longitude];
NSInteger index = [_deptNameArr indexOfObject:obj];
_tempModel = [_deptModelArr objectAtIndex:index];
YSLog(@"%@", _tempModel.name);
}
// 当点击大头针弹出的泡泡时,调用此接口
- (void)mapView:(BMKMapView *)mapView annotationViewForBubble:(BMKAnnotationView *)view {
YSLog(@"点击了大头针的泡泡");
}
// 地图区域改变完成后会调用此接口
- (void)mapView:(BMKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
_mapCenterCoor = mapView.centerCoordinate;
YSLog(@"地图当前中心坐标:lat精度 %f,long纬度 %f",_mapCenterCoor.latitude, _mapCenterCoor.longitude);
[self getDeptListByGeoPositionNetworkRequest];
}
// 在地图上把 大头针替换成小红旗
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
static NSString *reuseIndetifier = @"annotationReuseIndetifier";
BMKAnnotationView *annotationView = (BMKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIndetifier];
if (annotationView == nil) {
annotationView = [[BMKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:reuseIndetifier];
}
annotationView.image = [UIImage imageNamed:@"partyMap.png"];
return annotationView;
}
return nil;
}
#pragma mark - * * * * * BMKLocationServiceDelegate * * * * *
// 在地图View将要启动定位时,会调用此函数
- (void)willStartLocatingUser
{
YSLog(@"开始定位");
}
/**
* 用户方向更新后,会调用此函数
* @param userLocation 新的用户位置
*/
- (void)didUpdateUserHeading:(BMKUserLocation *)userLocation
{
[_mapView updateLocationData:userLocation];
//YSLog(@"用户方向更新后 %@",userLocation.heading);
}
/**
* 用户位置更新后,会调用此函数
* @param userLocation 新的用户位置
*/
- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation
{
YSLog(@"用户位置更新 lat精度 %f,long纬度 %f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);
[_mapView updateLocationData:userLocation];// 动态更新我的位置数据
if (!_userLocation) {
_userLocation = userLocation;
[_mapView setCenterCoordinate:_userLocation.location.coordinate];// 设置为当前地图的中心点
}
_userLocation = userLocation;
}
// 在地图View停止定位后,会调用此函数
- (void)didStopLocatingUser
{
YSLog(@"停止定位");
}
// 定位失败后,会调用此函数
- (void)didFailToLocateUserWithError:(NSError *)error
{
[_locationBtn setEnabled:YES];
YSLog(@"定位失败, %@", error);
}
#pragma mark - * * * * * 网络请求 * * * * *
// 根据经纬度和范围获取机构列表
- (void)getDeptListByGeoPositionNetworkRequest {
// 在赤道上经度差1度对应的实际距离是111千米;
if (fabs(_tempCenter.latitude - _mapCenterCoor.latitude) < 0.01 &&
fabs(_tempCenter.longitude - _mapCenterCoor.longitude) < 0.01) {
YSLog(@"移动距离不足1千米,无需重新加载该范围的组织");
return;
}
_tempCenter = _mapCenterCoor;
// 移除地图内所有大头针(清空地图)
[_mapView removeOverlays:_mapView.overlays];
[_mapView removeAnnotations:_mapView.annotations];
[self.deptNameArr removeAllObjects];
kWeakSelf
// 范围:radius, 经度:longitude, 纬度:latitude
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
[parameters setValue:@100 forKey:@"radius"];
[parameters setValue:@(_mapCenterCoor.longitude) forKey:@"longitude"];
[parameters setValue:@(_mapCenterCoor.latitude) forKey:@"latitude"];
[YSNetworkingManager requestWithUrl:@"/app/sys/dept/getDeptListByGeoPosition" requestMethod:RequestBody parameters:parameters successHandler:^(YSResponse *response) {
// YSLog(@"%@", response.dataObj);
if ([response.dataObj[@"deptList"] count] > 0) {
weakSelf.deptModelArr = [NSArray modelArrayWithClass:[YSMapDeptModel class] json:response.dataObj[@"deptList"]];
// 在地图上插上小红旗,当然是彩旗飘飘啦!
NSMutableArray *annotaionArr = [[NSMutableArray alloc] init];
for (YSMapDeptModel *dept in weakSelf.deptModelArr) {
BMKPointAnnotation *annotaion = [[BMKPointAnnotation alloc] init];
annotaion.coordinate = CLLocationCoordinate2DMake(dept.latitude, dept.longitude);
annotaion.title = dept.name;
annotaion.subtitle = dept.address;
[annotaionArr addObject:annotaion];
// 将组织名称&经纬度拼接成索引
[weakSelf.deptNameArr addObject:[NSString stringWithFormat:@"%@%.5f%.5f", dept.name, dept.latitude, dept.longitude]];
}
//添加标注大头针
[weakSelf.mapView addAnnotations:annotaionArr];
[weakSelf.mapView updateLocationData:_userLocation];
}
} errorHandler:nil];
}
#pragma mark - * * * * * getter * * * * *
- (NSMutableArray *)deptNameArr {
if (!_deptNameArr) {
_deptNameArr = [NSMutableArray array];
}
return _deptNameArr;
}
#pragma mark - * * * * * 添加自定义的手势(若不自定义手势,不需要下面的代码) * * * * *
//- (void)addCustomGestures {
// /*
// * 注意:
// * 添加自定义手势时,必须设置UIGestureRecognizer的属性cancelsTouchesInView 和 delaysTouchesEnded 为NO,
// * 否则影响地图内部的手势处理
// */
// UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
// doubleTap.delegate = self;
// doubleTap.numberOfTapsRequired = 2;
// doubleTap.cancelsTouchesInView = NO;
// doubleTap.delaysTouchesEnded = NO;
//
// [self.view addGestureRecognizer:doubleTap];
//
// /*
// * 注意:
// * 添加自定义手势时,必须设置UIGestureRecognizer的属性cancelsTouchesInView 和 delaysTouchesEnded 为NO,
// * 否则影响地图内部的手势处理
// */
// UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
// singleTap.delegate = self;
// singleTap.cancelsTouchesInView = NO;
// singleTap.delaysTouchesEnded = NO;
// [singleTap requireGestureRecognizerToFail:doubleTap];
// [self.view addGestureRecognizer:singleTap];
//}
//
//- (void)handleSingleTap:(UITapGestureRecognizer *)theSingleTap {
// NSLog(@"自定义的单击手势");
//}
//
//- (void)handleDoubleTap:(UITapGestureRecognizer *)theDoubleTap {
// NSLog(@"自定义的双击手势");
//}
@end