android高德点聚合头像,点聚合效果

使用场景

当地图上需要展示的marker过多,可能会导致界面上marker压盖、性能变差。使用点聚合功能,则可以解决该问题。效果示例请见右侧视频。

用到产品

核心类/接口

类接口说明版本

MAMapView(void) addAnnotations:    (NSArray *)   annotations向地图窗口添加一组标注,需要实现MAMapViewDelegate的-mapView:viewForAnnotation:函数来生成标注对应的ViewV4.3.0版本起

核心难点

1、调用ClusterAnnotation文件夹下的代码能够实现poi点聚合,使用步骤如下:

初始化coordinateQuadTree。

self.coordinateQuadTree = [[CoordinateQuadTree alloc] init];

var coordinateQuadTree = CoordinateQuadTree()

2、获得poi数组pois后,创建coordinateQuadTree。

·  项目Demo通过关键字搜索获得poi数组数据,具体见工程。此处从获得poi数组开始说明。

·  创建四叉树coordinateQuadTree来建立poi的四叉树索引。

·  创建过程较为费时,建议另开线程。创建四叉树完成后,计算当前mapView下需要显示的annotation。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

/* 建立四叉树. */

[self.coordinateQuadTree buildTreeWithPOIs:respons.pois];

dispatch_async(dispatch_get_main_queue(), ^{

/* 计算当前mapView区域内需要显示的annotation. */

NSLog(@"First time calculate annotations.");

[self addAnnotationsToMapView:self.mapView];

});

});

DispatchQueue.global(qos: .default).async(execute: { [weak self] in

self?.coordinateQuadTree.build(withPOIs: response.pois)

self?.shouldRegionChangeReCalculate = true

self?.addAnnotations(toMapView: (self?.mapView)!)

})

3、根据CoordinateQuadTree四叉树索引,计算当前zoomLevel下,mapView区域内的annotation。

- (void)addAnnotationsToMapView:(MAMapView *)mapView

{

/* 判断是否已建树. */

if (self.coordinateQuadTree.root == nil)

{

return;

}

/* 根据当前zoomLevel和zoomScale 进行annotation聚合. */

double zoomScale = self.mapView.bounds.size.width / self.mapView.visibleMapRect.size.width;

/* 基于先前建立的四叉树索引,计算当前需要显示的annotations. */

NSArray *annotations = [self.coordinateQuadTree clusteredAnnotationsWithinMapRect:mapView.visibleMapRect

withZoomScale:zoomScale

andZoomLevel:mapView.zoomLevel];

/* 更新annotations. */

[self updateMapViewAnnotationsWithAnnotations:annotations];

}

func addAnnotations(toMapView mapView: MAMapView) {

synchronized(lock: self) { [weak self] in

guard (self?.coordinateQuadTree.root != nil) || self?.shouldRegionChangeReCalculate != false else {

NSLog("tree is not ready.")

return

}

guard let aMapView = self?.mapView else {

return

}

let visibleRect = aMapView.visibleMapRect

let zoomScale = Double(aMapView.bounds.size.width) / visibleRect.size.width

let zoomLevel = Double(aMapView.zoomLevel)

DispatchQueue.global(qos: .default).async(execute: { [weak self] in

let annotations = self?.coordinateQuadTree.clusteredAnnotations(within: visibleRect, withZoomScale: zoomScale, andZoomLevel: zoomLevel)

self?.updateMapViewAnnotations(annotations: annotations as! Array)

})

}

}

4、更新annotations。对比mapView里已有的annotations,吐故纳新。

/* 更新annotation. */

- (void)updateMapViewAnnotationsWithAnnotations:(NSArray *)annotations

{

/* 用户滑动时,保留仍然可用的标注,去除屏幕外标注,添加新增区域的标注 */

NSMutableSet *before = [NSMutableSet setWithArray:self.mapView.annotations];

[before removeObject:[self.mapView userLocation]];

NSSet *after = [NSSet setWithArray:annotations];

/* 保留仍然位于屏幕内的annotation. */

NSMutableSet *toKeep = [NSMutableSet setWithSet:before];

[toKeep intersectSet:after];

/* 需要添加的annotation. */

NSMutableSet *toAdd = [NSMutableSet setWithSet:after];

[toAdd minusSet:toKeep];

/* 删除位于屏幕外的annotation. */

NSMutableSet *toRemove = [NSMutableSet setWithSet:before];

[toRemove minusSet:after];

/* 更新. */

dispatch_async(dispatch_get_main_queue(), ^{

[self.mapView addAnnotations:[toAdd allObjects]];

[self.mapView removeAnnotations:[toRemove allObjects]];

});

}

func updateMapViewAnnotations(annotations: Array) {

/* 用户滑动时,保留仍然可用的标注,去除屏幕外标注,添加新增区域的标注 */

let before = NSMutableSet(array: mapView.annotations)

before.remove(mapView.userLocation)

let after: Set = NSSet(array: annotations) as Set

/* 保留仍然位于屏幕内的annotation. */

var toKeep: Set = NSMutableSet(set: before) as Set

toKeep = toKeep.intersection(after)

/* 需要添加的annotation. */

let toAdd = NSMutableSet(set: after)

toAdd.minus(toKeep)

/* 删除位于屏幕外的annotation. */

let toRemove = NSMutableSet(set: before)

toRemove.minus(after)

DispatchQueue.main.async(execute: { [weak self] () -> Void in

self?.mapView.addAnnotations(toAdd.allObjects)

self?.mapView.removeAnnotations(toRemove.allObjects)

})

}

架构

Controllers  BaseMapViewController //地图基类 AnnotationClusterViewController //poi点聚合 PoiDetailViewController //显示poi详细信息列表

ViewMAAnnotationView

ClusterAnnotationView //自定义的聚合annotationView

ModelsConform to

ClusterAnnotation //记录annotation的信息,如其代表的poi数组、poi的个数、poi平均坐标,并提供两个annotation是否Equal的判断

CoordinateQuadTree //封装的四叉树类

QuadTree //四叉树基本算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值