# 地图组件如何添加多个Marker并自定义样式

#### 问题现象

如何在地图上实现多个Marker的效果，多个Marker的样式不同，需要自定义样式。

#### 背景知识

*   Map Kit提供的点标记功能（又称Marker）是地图开发的核心组件之一。它封装了大量的触发事件，例如点击事件、长按事件、拖拽事件。
*   Marker的主要作用是在地图上标记任何位置，例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。
*   系统为Marker提供了默认的显示风格，同时也支持开发者进行自定义，来实现自定义标记、自定义信息窗等功能。

#### 解决方案

*   添加多个Marker：可以通过调用map.MapComponentController类的addMarker方法，该方法会返回添加的Marker实例；再通过不同的MarkerOptions参数调用该方法创建不同的Marker实例，即可在地图上添加多个Marker标记。
*   自定义Marker样式的实现：Marker的icon属性可以自定义设置图片，可以尝试使用组件截图的方式去构建Builder组件来实现Marker的自定义设置。

实现步骤如下：

1.  构造Marker自定义样式。
2.  通过组件截图的方式获取需要样式的图片，并添加Marker至地图上显示。

完整示例参考如下：

```
import { map, mapCommon, MapComponent } from '@kit.MapKit';
import { AsyncCallback } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';

@Entry
@Component
struct CustomizationMarker {
  private mapOptions?: mapCommon.MapOptions;
  private mapController?: map.MapComponentController;
  private callback?: AsyncCallback<map.MapComponentController>;
  uiContext: UIContext = this.getUIContext();

  addMarker() {
    this.uiContext.getComponentSnapshot().createFromBuilder(() => {
      this.RandomBuilder();
    },
      async (error: Error, pixmap: image.PixelMap) => {
        if (error) {
          return;
        }
        // Marker初始化参数
        let markerOptions: mapCommon.MarkerOptions = {
          position: {
            latitude: 31.984410259206815,
            longitude: 118.76625379397866
          },
          rotation: 0,
          visible: true,
          zIndex: 0,
          alpha: 1,
          anchorU: 0.5,
          anchorV: 1,
          clickable: true,
          draggable: true,
          flat: false,
          icon: pixmap
        };
        this.mapController?.addMarker(markerOptions);
      });
  }

  aboutToAppear(): void {
    // 地图初始化参数
    this.mapOptions = {
      position: {
        target: {
          latitude: 31.984410259206815,
          longitude: 118.76625379397866
        },
        zoom: 15
      }
    };
    this.callback = async (err, mapController) => {
      if (!err) {
        this.mapController = mapController;
        this.addMarker();
      }
    };
  }

  @Builder
  RandomBuilder() {
    Row() {
      Image($r('app.media.startIcon')).width(18).height(24)
      Column() {
        Text('200米')
          .fontSize(12)
          .fontColor('#1f2642')
          .fontWeight(FontWeight.Bold)
        Text('35分钟')
          .fontSize(12)
          .fontColor('#1f2642')
          .fontWeight(FontWeight.Bold)
          .margin({ top: 1 })
      }.margin({ left: 6 }).alignItems(HorizontalAlign.Start)

      Divider()
        .vertical(true)
        .width(1)
        .height(18)
        .backgroundColor('#c1cadd')
        .margin({ left: 8, right: 8 })

      Image($r('app.media.startIcon')).width(18).height(18)

      Text('导航')
        .fontSize(12)
        .fontColor('#1f2642')
        .fontWeight(FontWeight.Bold)
        .margin({ left: 2 })
    }
    .margin({ bottom: 3 })
    .padding({
      left: 6,
      right: 6,
      top: 8,
      bottom: 8
    })
    .backgroundColor(Color.White)
    .borderRadius(12)
    .shadow({ radius: 12, color: '#33000000' })
  }

  build() {
    Stack() {
      Column() {
        MapComponent({ mapOptions: this.mapOptions, mapCallback: this.callback })
      }.width('100%')
    }.height('100%')
  }
}
```

#### 常见FAQ

Q：地图上如何实现自定义信息窗？

A：自定义信息窗可以参考：自定义信息窗。

Q：Marker中的图标（icon）可以使用远程地址吗？

A：不可以，icon参数目前只支持三种类型，分别为string、image.PixelMap和Resource。当类型为string时，可以传入资源相对路径格式或者toDataURL格式。所以如果需要传入远程图片地址，可以下载到本地以后使用本地相对路径或者转化成Base64格式以data:image/png;Base64,<图片的Base64字节编码值>加载。

Q：地图组件怎么删除Marker？

A：可以使用remove方法从地图移除覆盖物，实现删除单个Marker。或者可以使用clear方法删除地图上所有标记。