当前位置: 首页 > news >正文

IOS 百度地图点聚合使用

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

//xxx.m 文件
#import "BasicMapAnnotation.h"
#import "BMKClusterManager.h"

/*
 *点聚合Annotation
 */
@interface ClusterAnnotation : BMKPointAnnotation

///所包含annotation个数
@property (nonatomic, assign) NSInteger size;

@end

@implementation ClusterAnnotation

@synthesize size = _size;

@end


/*
 *点聚合AnnotationView
 */
@interface ClusterAnnotationView : BMKPinAnnotationView {
    
}

@property (nonatomic, assign) NSInteger size;
@property (nonatomic, strong) UILabel *label;

@end

@implementation ClusterAnnotationView

@synthesize size = _size;
@synthesize label = _label;

- (id)initWithAnnotation:(id<BMKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
    if (self) {
        [self setBounds:CGRectMake(0.f, 0.f, 55.f, 55.f)];
        _label = [[UILabel alloc] initWithFrame:CGRectMake(0.f, 0.f, 22.f, 22.f)];
        _label.textColor = [UIColor whiteColor];
        _label.font = [UIFont systemFontOfSize:11];
        _label.textAlignment = NSTextAlignmentCenter;
        [self addSubview:_label];
        self.alpha = 1;
    }
    return self;
}

- (void)setSize:(NSInteger)size {
    _size = size;
    if (_size == 1) {
        self.label.hidden = YES;
        self.pinColor = BMKPinAnnotationColorRed;
        return;
    }
    self.label.hidden = NO;
    if (size > 20) {
        self.label.backgroundColor = [UIColor redColor];
    } else if (size > 10) {
        self.label.backgroundColor = [UIColor purpleColor];
    } else if (size > 5) {
        self.label.backgroundColor = [UIColor blueColor];
    } else {
        self.label.backgroundColor = [UIColor greenColor];
    }
    _label.text = [NSString stringWithFormat:@"%ld", (long)size];
}

@end

@interface WrapperMainViewController ()<UIScrollViewDelegate, UISearchBarDelegate, CitySelDelegate,UITableViewDataSource,UITableViewDelegate,BMKMapViewDelegate>
{
    IBOutlet BMKMapView* _mapView;
    BMKClusterManager *_clusterManager;//点聚合管理类
    NSInteger _clusterZoom;//聚合级别
    NSMutableArray *_clusterCaches;//点聚合缓存标注
}
@end

@implementation WrapperMainViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Do any additional setup after loading the view from its nib.
    //[super.navigationController setNavigationBarHidden:NO animated:FALSE];
//    [self.navigationController setNavigationBarHidden:YES];
    
//    [self.scrollViewMain addSubview:viewMain];
    [self.scrollViewMain setContentSize:CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height - 106)];

    
    mutableArrayButton = [[NSMutableArray alloc] init];
    
    [self addHeader];
    
    labelCity.text = [[AppDelegate instance].dicCurrentCity valueForKeyPath:@"cname"];
    labelCity.textAlignment = NSTextAlignmentCenter;
    //[btnCity setTitle:[[AppDelegate instance].dicCurrentCity valueForKeyPath:@"cname"] forState:UIControlStateNormal];
    
    [[LocationManagement sharedInstance] startGPS];
    [LocationManagement sharedInstance].delegate = self;
    
    [super getAPPVersion:NO AppId:@"1"];
    UITapGestureRecognizer *click = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(disappear)];
    [blackAlpha addGestureRecognizer:click];
    blackAlpha.frame = CGRectMake(0, 568, self.view.bounds.size.width, self.view.bounds.size.height);
    
    [self.view addSubview:blackAlpha];
    
    weatherTableView.frame = CGRectMake(0, 568, weatherTableView.bounds.size.width, 200);
   
    [self.view addSubview:weatherTableView];
    
    if (iPhone4s) {
        scrollViewMain.contentSize = CGSizeMake(scrollViewMain.contentSize.width, 548);
    }
    
    _clusterCaches = [[NSMutableArray alloc] init];
    for (NSInteger i = 3; i < 21; i++) {
        [_clusterCaches addObject:[NSMutableArray array]];
    }
    
    //点聚合管理类(初始化)
    _clusterManager = [[BMKClusterManager alloc] init];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewWillAppear:(BOOL)animated
{
    [_mapView viewWillAppear];
    _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
}

- (void)viewWillDisappear:(BOOL)animated
{
    [_mapView viewWillDisappear];
    _mapView.delegate = nil; // 不用时,置nil
}

//更新聚合状态
- (void)updateClusters {
    _clusterZoom = (NSInteger)_mapView.zoomLevel;
    @synchronized(_clusterCaches) {
        __block NSMutableArray *clusters = [_clusterCaches objectAtIndex:(_clusterZoom - 3)];
        
        if (clusters.count > 0) {
            [_mapView removeAnnotations:_mapView.annotations];
            [_mapView addAnnotations:clusters];
        } else {
            dispatch_async(dispatch_get_global_queue(0, 0), ^{
                
                ///获取聚合后的标注
                __block NSArray *array = [_clusterManager getClusters:_clusterZoom];
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    for (int i=0;i<[array count];i++) {
                        BMKCluster *item=array[i];
                        ClusterAnnotation *annotation = [[ClusterAnnotation alloc] init];
                        annotation.coordinate = item.coordinate;
                        annotation.size = item.size;
//                        annotation.title = [NSString stringWithFormat:@"我是%ld个", (unsigned long)item.size];
                        annotation.title = [NSString stringWithFormat:@"%d",i];
                        ParkEntity *entity = homeEntity.mutableArrayPark[i];
                        annotation.subtitle = entity.album_thumb;
                        [clusters addObject:annotation];
                    }
                    [_mapView removeAnnotations:_mapView.annotations];
                    [_mapView addAnnotations:clusters];
                });
            });
        }
    }
}

#pragma mark - BMKMapViewDelegate
 Override (单个标注)
//-(BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation{
//    if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
//        BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"];
//        newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
//        newAnnotationView.animatesDrop = YES;// 设置该标注点动画显示
//        newAnnotationView.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:annotation.subtitle]]];
        newAnnotationView.image=[UIImage imageNamed:@"地图图标_景点@2x"];
//        return newAnnotationView;
//    }
//
//    return nil;
//}

// 根据anntation生成对应的View
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
    //普通annotation
    NSString *AnnotationViewID = @"ClusterMark";
    ClusterAnnotation *cluster = (ClusterAnnotation*)annotation;
    ClusterAnnotationView *annotationView = [[ClusterAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
    annotationView.size = cluster.size;
    annotationView.canShowCallout = NO;//在点击大头针的时候会弹出那个黑框框
    annotationView.draggable = NO;//禁止标注在地图上拖动
    annotationView.annotation = cluster;
    annotationView.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:annotation.subtitle]]];
    return annotationView;
    
}

/**
 *当点击annotation view弹出的泡泡时,调用此接口
 *@param mapView 地图View
 *@param view 泡泡所属的annotation view
 */
- (void)mapView:(BMKMapView *)mapView annotationViewForBubble:(BMKAnnotationView *)view {
    if ([view isKindOfClass:[ClusterAnnotationView class]]) {
        ClusterAnnotation *clusterAnnotation = (ClusterAnnotation*)view.annotation;
        if (clusterAnnotation.size > 1) {
            [mapView setCenterCoordinate:view.annotation.coordinate];
            [mapView zoomIn];
        }
    }
}

/**
 *地图初始化完毕时会调用此接口
 *@param mapview 地图View
 */
- (void)mapViewDidFinishLoading:(BMKMapView *)mapView {
    [self updateClusters];
}

/**
 *地图渲染每一帧画面过程中,以及每次需要重绘地图时(例如添加覆盖物)都会调用此接口
 *@param mapview 地图View
 *@param status 此时地图的状态
 */
- (void)mapView:(BMKMapView *)mapView onDrawMapFrame:(BMKMapStatus *)status {
    if (_clusterZoom != 0 && _clusterZoom != (NSInteger)mapView.zoomLevel) {
        [self updateClusters];
    }
}

//标注 单击事件
-(void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view {
   if ([view isKindOfClass:[ClusterAnnotationView class]]) {
        ClusterAnnotation *clusterAnnotation = (ClusterAnnotation*)view.annotation;
        if (clusterAnnotation.size > 1) {
            [mapView setCenterCoordinate:view.annotation.coordinate];
            [mapView zoomIn];
        }else {
            ParkEntity *entity = [homeEntity.mutableArrayPark objectAtIndex:[clusterAnnotation.title integerValue]];
            if ([entity.is_business isEqualToString:@"0"] == YES) {
                IntroduceViewController *vc = [[IntroduceViewController alloc] init];
                vc.parkEntity = entity;
                [self.navigationController pushViewController:vc animated:YES];
            } else {
                WrapperViewController *vc = [[WrapperViewController alloc] init];
                vc.parkEntity = entity;
                [self.navigationController pushViewController:vc animated:YES];
            }
        }
    }

}

@end
//核心代码
//添加单点标注
for(int i=0;i<[homeEntity.mutableArrayPark count];i++){
    ParkEntity *entity = homeEntity.mutableArrayPark[i];
    // 添加一个PointAnnotation (景点标注)
    BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];
    CLLocationCoordinate2D coor;
    coor.latitude = [entity.latitude floatValue];
    coor.longitude = [entity.longitude floatValue];
    annotation.coordinate = coor;
    annotation.title = entity.title;
    annotation.subtitle=entity.album_thumb;
    [_mapView addAnnotation:annotation];
    }
   
[_clusterManager clearClusterItems];//清除点聚合元素                       
//添加多点标注(点聚合)
for(int i=0;i<[homeEntity.mutableArrayPark count];i++){
    ParkEntity *entity = homeEntity.mutableArrayPark[i];
    BMKClusterItem *clusterItem = [[BMKClusterItem alloc] init];
    clusterItem.coor = CLLocationCoordinate2DMake([entity.latitude floatValue],[entity.longitude floatValue]);
    [_clusterManager addClusterItem:clusterItem];
}


172643_oVkx_2320053.png

ps:

1、需要用到 Cluster 中的一些类(BMKClusterAlgorithm、BMKClusterItem、BMKClusterManager、BMKClusterQuadtree)

172222_6soh_2320053.png

2、annotationView.image  设置标注图片的时候,缩小地图汇出现图片重叠的问题。

可以通过设置 BMKClusterAlgorithm.m 文件中的 #define MAX_DISTANCE_IN_DP    400 //300dp  来设置点聚合算法的距离

3、[_clusterManager clearClusterItems];//清除点聚合元素

                            for(int i=0;i<[homeEntity.mutableArrayPark count];i++){

                                ParkEntity *entity = homeEntity.mutableArrayPark[i];

                                BMKClusterItem *clusterItem = [[BMKClusterItem alloc] init];

                                clusterItem.coor = CLLocationCoordinate2DMake([entity.latitude floatValue],[entity.longitude floatValue]);

                                [_clusterManager addClusterItem:clusterItem];

                            }

//移动地图

ParkEntity *entity = homeEntity.mutableArrayPark[0];

                          CLLocation *location = [[CLLocation alloc] initWithLatitude:[entity.latitude doubleValue] longitude:[entity.longitude doubleValue]];

                          [_mapView setCenterCoordinate:location.coordinate animated:YES];

                          [self updateClusters];

4、

//删除标注

    NSArray* array = [NSArray arrayWithArray:_mapView.annotations];

    [_mapView removeAnnotations:array];

//清除地图缓存

    [_clusterCaches removeAllObjects];

    for (NSInteger i = 3; i < 21; i++) {

        [_clusterCaches addObject:[NSMutableArray array]];

    }


转载于:https://my.oschina.net/jack088/blog/525406

相关文章:

  • PHP和MySQL Web开发从新手到高手,第2天-怎样用zend创建PHP项目
  • 支持 Windows 10 最新 PerMonitorV2 特性的 WPF 多屏高 DPI 应用开发
  • 如何使用 Quagga BGP(边界网关协议)路由器来过滤 BGP 路由
  • 常用正则表达式(高亮,markdown)
  • 一些资料
  • Selenium库简介
  • shell 相关操作
  • Android 内存分析
  • ASP.NET的几个试题(《C#与.NET程序员面试宝典》)
  • 可以使你成为更优秀程序员的5个好习惯
  • HBase生产环境配置与使用优化不完全指南
  • co模块的前端实现
  • 【转】【支付 . 技术控】最全最强解析:支付宝系统架构内部剖析(架构图)...
  • 写给正在入坑linux系统的伙伴
  • 关于Activity销毁,而绘制UI的子线程未销毁出现的问题
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • Android 控件背景颜色处理
  • CentOS 7 防火墙操作
  • js中forEach回调同异步问题
  • react-native 安卓真机环境搭建
  • 编写高质量JavaScript代码之并发
  • 读懂package.json -- 依赖管理
  • 基于 Babel 的 npm 包最小化设置
  • 理解在java “”i=i++;”所发生的事情
  • 码农张的Bug人生 - 初来乍到
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 微信开放平台全网发布【失败】的几点排查方法
  • 物联网链路协议
  • 异常机制详解
  • 原生Ajax
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 国内开源镜像站点
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • #define,static,const,三种常量的区别
  • #if 1...#endif
  • %@ page import=%的用法
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (6)添加vue-cookie
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (day6) 319. 灯泡开关
  • (Git) gitignore基础使用
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (poj1.2.1)1970(筛选法模拟)
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (笔试题)分解质因式
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (循环依赖问题)学习spring的第九天
  • (转) Android中ViewStub组件使用
  • (转)ORM
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑