更新时间:2021-09-20
绘制海量点简介
since6.4.0起iOS地图SDK支持海量点图层(BMKMultiPointOverlay)绘制,用于批量展现坐标点数据,并支持点击事件。
绘制海量点
1添加海量点覆盖物数据
Objective-C
Swift
NSMutableArray *items = [NSMutableArray array]; //读取数据 NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"multPoints" ofType:@"json"]]; if (jsonData) { NSArray *array = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]; for (NSDictionary *dic in array) { @autoreleasepool { BMKMultiPointItem *item = [[BMKMultiPointItem alloc] init]; item.coordinate = CLLocationCoordinate2DMake([dic[@"lat"] floatValue], [dic[@"lng"] floatValue]); [items addObject:item]; } } } _multiPointOverlay = [BMKMultiPointOverlay multiPointOverlayWithMultiPointItems:items]; /** 向地图View添加Overlay,需要实现BMKMapViewDelegate的-mapView:viewForOverlay:方法 来生成标注对应的View @param overlay 要添加的overlay */ [_mapView addOverlay:self.multiPointOverlay];
let path = Bundle.main.path(forResource: "multPoints", ofType: "json") let url = URL(fileURLWithPath: path!) let items = NSMutableArray.init() do { let data = try Data(contentsOf: url) let jsonData: Any = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) let jsonArr = jsonData as! NSArray for dict in jsonArr { let dictTemp: Dictionary = dict as! Dictionary<String, NSNumber> let item = BMKMultiPointItem.init() let lat = dictTemp["lat"]! as NSNumber let lng = dictTemp["lng"]! as NSNumber item.coordinate = CLLocationCoordinate2D(latitude: CLLocationDegrees(lat.floatValue), longitude: CLLocationDegrees(lng.floatValue)) items.add(item) } } catch let error as Error? { print("读取本地数据出现错误!") } /** 根据指定区域生成一个图层 @param bounds 指定的经纬度区域 @param icon 绘制使用的图片 @return 新生成的BMKGroundOverlay实例 */ let multiPointOverlay: BMKMultiPointOverlay = BMKMultiPointOverlay(multiPointItems: items as! [BMKMultiPointItem]) mapView.add(multiPointOverlay)
2实现代理方法生成对应的view(BMKMultiPointOverlayView)
Objective-C
Swift
#pragma mark - BMKMapViewDelegate /** 根据overlay生成对应的BMKOverlayView @param mapView 地图View @param overlay 指定的overlay @return 生成的覆盖物View */ - (BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id<BMKOverlay>)overlay { if ([overlay isKindOfClass:[BMKMultiPointOverlay class]]) { //初始化一个overlay并返回相应的BMKMultiPointOverlayView的实例 BMKMultiPointOverlayView *multiPointOverlayView = [[BMKMultiPointOverlayView alloc] initWithMultiPointOverlay:overlay]; multiPointOverlayView.icon = [UIImage imageNamed:@"multPoints"]; multiPointOverlayView.anchor = CGPointMake(0.5, 1.0); multiPointOverlayView.pointSize = CGSizeMake(32, 32); MultipointOverlayView.delegate = self; return multiPointOverlayView; } return nil; }
//MARK:BMKMapViewDelegate /** 根据overlay生成对应的BMKOverlayView @param mapView 地图View @param overlay 指定的overlay @return 生成的覆盖物View */ func mapView(_ mapView: BMKMapView!, viewFor overlay: BMKOverlay!) -> BMKOverlayView! { if overlay.isKind(of: BMKMultiPointOverlay.self) { let multiPointOverlayView = BMKMultiPointOverlayView(multiPointOverlay: overlay as? BMKMultiPointOverlay) multiPointOverlayView?.icon = UIImage.init(named: "multPoints") multiPointOverlayView?.anchor = CGPoint.init(x: 0.5, y: 0.5) multiPointOverlayView?.pointSize = CGSize.init(width: 32, height: 32) multiPointOverlayView?.delegate = self return multiPointOverlayView } return nil }
3海量点点击回调
Objective-C
Swift
//MARK:BMKMapViewDelegate /** 根据overlay生成对应的BMKOverlayView @param mapView 地图View @param overlay 指定的overlay @return 生成的覆盖物View */ - (void)multiPointOverlayView:(BMKMultiPointOverlayView *)overlayView didItemTapped:(BMKMultiPointItem *)item { [self.mapView removeAnnotations:self.mapView.annotations]; [self.mapView addAnnotation:item]; }
/** *点中覆盖物的item后会回调此接口 *@param multiPointOverlayView 覆盖物view信息 *@param item 覆盖物view被点击的item */ func multiPointOverlayView(_ multiPointOverlayView: BMKMultiPointOverlayView, didItemTapped item: BMKMultiPointItem) { self.mapView.removeAnnotations(self.mapView.annotations) self.mapView.addAnnotation(item) }
4运行程序
效果如下: