高德地图jssdk 2.0搜索并标记

有一个用高德地图搜索地点的需求,本以为看看文档,很简单,结果……。先放个效果图。

引入地图

使用高德地图需要 key 和 jscode,有了这两个之后,直接按照官网实例代码写就可以。比如我这里的 vue 代码:

// 初始化地图
initAMap() {
  window._AMapSecurityConfig = {
    securityJsCode: amap.jscode,
  };
  AMapLoader.load({
    key: amap.key, // 申请好的Web端开发者Key,首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: ["AMap.Scale"], //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...']
  })
    .then((AMap) => {
      map.AMap = AMap;
      const center =
        this.detail?.orderWaybill?.lat && this.detail?.orderWaybill?.lng
          ? [
              this.detail.orderWaybill.lat >> 0,
              this.detail.orderWaybill.lng >> 0,
            ]
          : [116.397428, 39.90923];
      console.log(center);
      map.map = new AMap.Map("container", {
        // 设置地图容器id
        viewMode: "2d", // 是否为3D地图模式
        zoom: 11, // 初始化地图级别
        center: center, // 初始化地图中心点位置
      });
    })
    .catch((e) => {
      console.log(e);
    });
},

我是定义了一个 map 变量存放高德相关数据,比如 AMap 和 map 实例都放到 map 里,方便其他函数使用。

搜索地点

高德地图的很多功能是通过插件实现的,搜索地点也是,所以需要在插件的回调里搜索。

map.AMap.plugin(["AMap.PlaceSearch"], () => {
  const placeSearch = new map.AMap.PlaceSearch({
    pageSize: 50,
    pageIndex: 1,
    map: map.map,
    autoFitView: true,
  });
  map.placeSearch = placeSearch;
  placeSearch.search(this.searchText, (status, result) => {
    if (status === "complete") {
      this.addressList = (result.poiList.pois ?? []).map((item) => {
        item.checked = false;
        return item;
      });
      if (this.addressList.length === 0) {
        this.$message.info("未找到");
      }
    } else if (status === "no_data") {
      this.$message.info("没有结果");
    } else {
      this.$message.error("搜索出错");
    }
  });
  placeSearch.on("markerClick", (e) => {
    this.handleMarkerClick(e);
  });
});

代码的倒数几行我监听了 placeSearch 实例的 markerClick 事件,因为我需要在点击地图上 marker 的时候左侧列表里对应的数据也选中。为了找这个 markerClick 事件,我查了好几个网页,1.4 和 2.0 的写法也不一样。而高德地图的官方文档里,我一开始是在 map 上面找,但没找到,marker 上也没有,就是没想到要去 placeSearch 上找。

显示信息窗口

点击地图自带的 marker 是会显示信息窗口的,但点击左边列表的时候如果让地图上显示信息窗口呢?于是我就找有没有在地图上显示地图自带 poi 的信息窗口的方法,然后发现一个疑似 api——poiOnAMAP。这个 api 一开始是在 1.4 的文档里看到的,但 1.4 的写法是 map.poiOnAMAP,2.0 的这个方法则在 searchPlace 上。没错,还是 searchPlace,这个是我打印 searchPlace 的时候在原型上找到的。

但实际上这也不是我需要的,这个 api 会打开新标签跳转高德地图网站,然后定位到设置的地点。

map.placeSearch.poiOnAMAP(map.map, {
  name: data.name,
  location: data.location,
  id: data.id,
  address: data.address,
});

另外,这第一个参数 map.map 可以不需要,因为效果是一样的。api 文档也没有说明这个参数是干嘛的。

然后找到了 InfoWindow,但这就需要自己写窗口内容了,这实际上并不是我想要的,我要的只是调起地图自带的信息窗口,但没办法,没有找到相关方法。

const infowWindow = new map.AMap.InfoWindow({
  content: data.name,
  position: data.location,
  anchor: "bottom-center",
  offset: [0, -30],
});
infowWindow.open(map.map);

infoWindow 我这里内容很简单,只显示了地点的名称,和自带的有点出入。将就用吧。offset 是位置偏移,让 infoWindow 的箭头在 marker 上方,要不然会遮住 marker。

That’s all.