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

绘制海量点图层 最后更新时间: 2026年06月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;
  }
}

返回顶部 示例中心 常见问题 智能客服 公众号
二维码