点聚合
功能场景
通过该功能可以避免因Marker绘制过多呈现拥挤的情况,获得更优的展示效果,常用于充电桩、房产等app中。
//mapopen-website-wiki.bj.bcebos.com/demos/AndroidVideos/Android点聚合.mp4
addItems(Collection<T> items
setOnClusterClickListener(OnClusterClickListener<T> listener)
setOnClusterItemClickListener(OnClusterItemClickListener<T> listener)
mBaiduMap.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
// 添加marker
initCluster();
addMarkers();
// 设置初始中心点为北京
LatLng center = new LatLng(39.963175, 116.400244);
// 需要更新下地图状态,聚合点才会显示出来
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLngZoom(center, 10);
mBaiduMap.setMapStatus(mapStatusUpdate);
}
});
复制成功
private void initCluster() {
// 定义点聚合管理类ClusterManager
mClusterManager = new ClusterManager<MyItem>(this, mBaiduMap);
mBaiduMap.setOnMapStatusChangeListener(mClusterManager);
mBaiduMap.setOnMarkerClickListener(mClusterManager);
mClusterManager
.setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MyItem>() {
@Override
public boolean onClusterClick(Cluster<MyItem> cluster) {
Toast.makeText(ClusterMarkerActivity.this, "有" + cluster.getSize() + "个点",
Toast.LENGTH_SHORT).show();
return false;
}
});
mClusterManager.setOnClusterItemClickListener(
new ClusterManager.OnClusterItemClickListener<MyItem>() {
@Override
public boolean onClusterItemClick(MyItem item) {
Toast.makeText(ClusterMarkerActivity.this, "点击单个Item", Toast.LENGTH_SHORT)
.show();
return false;
}
});
}
复制成功
/**
* 向地图添加Marker点
*/
public void addMarkers() {
// 添加Marker点
List<MyItem> items = getMaytiems();
mClusterManager.addItems(items);
}
复制成功
//mapopen-website-wiki.bj.bcebos.com/demos/iosVideos/iOS点聚合.mov
- (void)clearClusterItems;
- (NSArray<BMKCluster *> *)getClusters:(CGFloat)zoomLevel;
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation;
- (void)mapViewDidFinishLoading:(BMKMapView *)mapView;
- (void)mapView:(BMKMapView *)mapView onDrawMapFrame:(BMKMapStatus *)status;
地图渲染每一帧画面过程中,以及每次需要重新绘制地图时(例如添加覆盖物)都会调用此方法
/** 更新标注展示. */
- (void)updateClusters {
_clusterZoom = (NSInteger)_mapView.zoomLevel;
@synchronized(_clusterManager.clusterCaches) {
NSMutableArray *clusters = [_clusterManager.clusterCaches objectAtIndex:(_clusterZoom - 3)];
if (clusters.count > 0) {
// 移除一组标注
[_mapView removeAnnotations:_mapView.annotations];
//将一组标注添加到当前地图View中
[_mapView addAnnotations:clusters];
} else {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 获取聚合后的标注
__block NSArray *array = [weakSelf.clusterManager getClusters:weakSelf.clusterZoom];
dispatch_async(dispatch_get_main_queue(), ^{
for (BMKCluster *item in array) {
ClusterAnnotation *annotation = [[ClusterAnnotation alloc] init];
// 设置标注的经纬度坐标
annotation.coordinate = item.coordinate;
annotation.size = item.size;
// 设置标注的标题
annotation.title = [NSString stringWithFormat:@"我是%lu个", (unsigned long)item.size];
[clusters addObject:annotation];
}
// 移除一组标注
[weakSelf.mapView removeAnnotations:weakSelf.mapView.annotations];
// 将一组标注添加到当前地图View中
[weakSelf.mapView addAnnotations:clusters];
});
});
}
}
}
#pragma mark - BMKMapViewDelegate
/** 根据anntation生成对应的View. */
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation {
ClusterAnnotation *cluster = (ClusterAnnotation*)annotation;
BMKPinAnnotationView *annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationViewIdentifier];
UILabel *annotationLabel = [[UILabel alloc] init];
annotationLabel.textColor = [UIColor whiteColor];
annotationLabel.font = [UIFont systemFontOfSize:11];
annotationLabel.textAlignment = NSTextAlignmentCenter;
annotationLabel.hidden = NO;
annotationLabel.text = [NSString stringWithFormat:@"%ld", (long)cluster.size];
annotationLabel.backgroundColor = [UIColor greenColor];
annotationView.alpha = 0.8;
[annotationView addSubview:annotationLabel];
// 此处为了方便展示使用了简易的大头针标注,开发者可以根据自身需求来自定义标注,圆角设置建议使用圆形图片
if (cluster.size == 1) {
annotationLabel.hidden = YES;
annotationView.pinColor = BMKPinAnnotationColorRed;
}
if (cluster.size >= 500) {
annotationLabel.frame = CGRectMake(0, 0, 100, 100);
annotationLabel.layer.cornerRadius = 50;
annotationLabel.layer.masksToBounds = YES;
annotationLabel.backgroundColor = [UIColor redColor];
[annotationView setBounds:CGRectMake(0, 0, 100, 100)];
} else if (cluster.size >= 200 && cluster.size < 500) {
annotationLabel.frame = CGRectMake(0, 0, 80, 80);
annotationLabel.layer.cornerRadius = 40;
annotationLabel.layer.masksToBounds = YES;
annotationLabel.backgroundColor = [UIColor purpleColor];
[annotationView setBounds:CGRectMake(0, 0, 80, 80)];
} else if (cluster.size > 50) {
annotationLabel.frame = CGRectMake(0, 0, 60, 60);
annotationLabel.layer.cornerRadius = 30;
annotationLabel.layer.masksToBounds = YES;
annotationLabel.backgroundColor = [UIColor orangeColor];
[annotationView setBounds:CGRectMake(0, 0, 60, 60)];
} else if (cluster.size > 20) {
annotationLabel.frame = CGRectMake(0, 0, 40, 40);
annotationLabel.layer.cornerRadius = 20;
annotationLabel.layer.masksToBounds = YES;
annotationLabel.backgroundColor = [UIColor blueColor];
[annotationView setBounds:CGRectMake(0, 0, 40, 40)];
} else {
annotationLabel.frame = CGRectMake(0, 0, 20, 20);
annotationLabel.layer.cornerRadius = 10;
annotationLabel.layer.masksToBounds = YES;
annotationLabel.backgroundColor = [UIColor greenColor];
[annotationView setBounds:CGRectMake(0, 0, 20, 20)];
}
annotationView.draggable = YES;
annotationView.annotation = annotation;
return annotationView;
}
/** 当点击annotationView弹出的泡泡时,回调此方法. */
- (void)mapView:(BMKMapView *)mapView annotationViewForBubble:(BMKAnnotationView *)view {
if ([view isKindOfClass:[BMKPinAnnotationView class]]) {
ClusterAnnotation *clusterAnnotation = (ClusterAnnotation*)view.annotation;
if (clusterAnnotation.size > 1) {
/**
设定地图中心点坐标
@param coordinate 要设定的地图中心点坐标,用经纬度表示
@param animated 是否采用动画效果
*/
[mapView setCenterCoordinate:view.annotation.coordinate];
/**
放大一级比例尺
@return 是否成功
*/
[mapView zoomIn];
}
}
}
/** 地图加载完成时会调用此方法. */
- (void)mapViewDidFinishLoading:(BMKMapView *)mapView {
[self updateClusters];
}
/** 地图渲染每一帧画面过程中,以及每次需要重新绘制地图时(例如添加覆盖物)都会调用此方法*/
- (void)mapView:(BMKMapView *)mapView onDrawMapFrame:(BMKMapStatus *)status {
if (_clusterZoom!= 0 && _clusterZoom!= (NSInteger)mapView.zoomLevel) {
[self updateClusters];
}
}
复制成功