标签:
//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 = YES; 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]; } //添加多点标注(点聚合) 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]; }
ps:
1、需要用到 Cluster 中的一些类(BMKClusterAlgorithm、BMKClusterItem、BMKClusterManager、BMKClusterQuadtree)
2、annotationView.image 设置标注图片的时候,缩小地图汇出现图片重叠的问题。
可以通过设置 BMKClusterAlgorithm.m 文件中的 #define MAX_DISTANCE_IN_DP 400 //300dp 来设置点聚合算法的距离
标签:
原文地址:http://my.oschina.net/jack088/blog/525406