//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];
}
ps:
1、需要用到 Cluster 中的一些类(BMKClusterAlgorithm、BMKClusterItem、BMKClusterManager、BMKClusterQuadtree)
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]];
}