开发 HarmonyOS NEXT 地图SDK 开发指南 在地图上绘制 绘制海量点图层

绘制海量点图层 最后更新时间: 2026年01月06日

在地图上加载显示海量点,支持高达十万级点位的流畅显示。

第 1 步:初始化 MapView 并获取 AMap 实例

通过 MapViewComponent 创建地图视图,并在回调中获取底层 AMap 对象,用于后续操作。

@Builder
buildMapMultiPointOverlay() {
 Stack() {
 MapViewComponent({ mapViewName: Constants.MAP_MULTIPOINTOVERLAY_FUNC })
 }
 .width('100%')
 .height('100%')
}
private mapViewCreateCallback = (mapview?: MapView, mapViewName?: string) => {
 if (!mapview || mapViewName !== Constants.MAP_MULTIPOINTOVERLAY_FUNC) return;
 this.mapView = mapview;
 this.mapView.onCreate();
 this.mapView.getMapAsync(async (map: AMap) => {
 this.aMap = map;
 await this.setupMultiPointOverlay(); 
 });
};

第 2 步:准备点位数据源

支持两种方式加载点位数据:

方式一:从本地文件加载(推荐用于真实数据)

将经纬度数据以 CSV 格式保存在 resources/rawfile/point10w.txt 文件中,每行格式为:

经度,纬度 116.397026,39.90976 116.401,39.912 ...

private async loadPointItemsFromFile(): Promise<MultiPointItem[]>

方式二:动态生成测试数据(用于调试)

可生成指定数量的随机点,中心坐标为中国北京附近。

const testPoints = this.generateTestPoints(10000);

第 3 步:创建 MultiPointOverlay 图层

配置 MultiPointOverlayOptions,设置图标、锚点及初始点集。

const overlayOptions = new MultiPointOverlayOptions();
overlayOptions.icon(bitmapDescriptor); // 设置点图标
overlayOptions.anchor(0.5, 0.5); // 图标中心对齐
overlayOptions.setMultiPointItems([]); // 初始为空数组
this.multiPointOverlay = this.aMap.addMultiPointOverlay(overlayOptions);

其中:

参数

说明

icon(BitmapDescriptor)

点的显示图标,建议尺寸较小以提升性能

anchor(x, y)

图标锚点位置,(0.5, 0.5) 表示居中对齐

setMultiPointItems(items)

设置要渲染的点列表

第 4 步:加载并渲染点数据

调用 loadAndRenderPoints() 方法异步加载文件中的点数据,并更新到 MultiPointOverlay。

流程如下:

  1. 读取 rawfile/point10w.txt 文件内容;
  2. 解析每一行为 LatLng 坐标;
  3. 构造 MultiPointItem 并绑定自定义数据;
  4. 保存至 this.allPointItems(用于点击检测);
  5. 调用 multiPointOverlay.setItems(items) 更新视图;
  6. 启用图层 .setEnable(true)。

第 5 步:实现地图点击交互

监听地图点击事件,在所有点中查找距离最近的一个,并用红色 Marker 高亮显示。

this.aMap.setOnMapClickListener(async (latLng: LatLng) => {
 let closestItem: MultiPointItem | null = null;
 let minDistSq = 0.1; // 阈值
 for (const item of this.allPointItems) {
 const dLat = item.getLatLng().latitude - latLng.latitude;
 const dLon = item.getLatLng().longitude - latLng.longitude;
 const distSq = dLat * dLat + dLon * dLon;
 if (distSq < minDistSq) {
 minDistSq = distSq;
 closestItem = item;
 }
 }
 if (closestItem) {
 // 显示/移动红色 Marker
 if (!this.marker) {
 const redIcon = await BitmapDescriptorFactory.defaultMarkerASync(globalContext, BitmapDescriptorFactory.HUE_RED);
 const options = new MarkerOptions();
 options.setIcon(redIcon);
 this.marker = this.aMap?.addMarker(options);
 }
 this.marker.setPosition(closestItem.getLatLng());
 this.marker.setZIndex(1000); // 置顶显示
 }
});

其他:生命周期管理

在页面销毁时释放资源:

aboutToDisappear(): void {
 this.isDestroy = true;
 MapViewManager.getInstance().unregisterMapViewCreatedCallback(this.mapViewCreateCallback);
 if (this.mapView) {
 this.mapView.onDestroy();
 this.mapView = undefined;
 this.aMap = undefined;
 }
}

示例中心 常见问题

AltStyle によって変換されたページ (->オリジナル) /