iOS开发 - 关于百度地图的使用

代码中包含大头针,定位等

效果图

一切尽在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

推荐阅读更多精彩内容