高德地图Vue3使用

933 阅读2分钟

高德地图API自用记录

功能需求:

需求:高德地图,加载点位信息,点击marker弹出信息窗口,右上角模糊搜索选择,自动切换marker以及信息窗口。 添加行政区边界,边界外添加透明灰背景。

image.png

  1. 首先,初始化地图,引入高德的web api js
<script src="https://webapi.amap.com/maps?v=2.0&key=你的Key"></script>
<script src="//webapi.amap.com/ui/1.1/main.js?v=1.1.1"></script>

2. 初始化地图,获取行政区域坐标和所需拿到的标记点的坐标

<template>
  <div class="search-box">
      <el-select v-model="searchValue" style="width: 200px" @change="onSearch" filterable clearable placeholder="请输入桥梁名称">
        <el-option
          v-for="item in mapData"
          :key="item.id"
          :label="item.bridgeName"
          :value="item.id" />
      </el-select>
    </div>
    <div>
      <div id="map" ref="mapContainer" style="width: 100%; height: 800px;"></div>
    </div>
</template>
<style>
.search-box {
  position: absolute;
  top: 16px;
  right: 20px;
  display: flex;
  gap: 10px;
}
</style>
const mapData = ref<any>([]);
const mapContainer = ref(null); // 新增DOM容器引用
const map = ref<AMap.Map>(); // 保持地图实例专用
const searchValue = ref('');
const markersMap = ref<Record<string, AMap.Marker>>({});
const infoWindowsMap = ref<Record<string, any>>({}); // 新增infoWindow存储
const isSelectInfoMap = ref<any>();
  const getMapInfo = () => {
    DashboardApi.getMapInfo().then((res: any) => {
      mapData.value = res;
      initMap();
    })
  }
  const initMap = () => {
    map.value = markRaw(new AMap.Map('map', {
      center: [121.5879052,29.83087043], // 宁波市鄞州区的经纬度
      zoom: 14, // 缩放级别
    }));
    fetchDistrictBoundary();
  };
  const fetchDistrictBoundary = () => {
    const url = `https://restapi.amap.com/v3/config/district?key=你的Key&keywords=鄞州区&subdistrict=3&extensions=all`;

    fetch(url)
      .then(response => response.json())
      .then(data => {
        if (data.status === '1') {
          const district = data.districts[0];
          const boundary = parseBoundary(district.polyline);

          drawPolygon(boundary);
          addMarkers();
        }
      })
      .catch(error => {
        console.error('Error fetching district boundary:', error);
      });
  };
  // 解析坐标数据
  const parseBoundary = (polyline: string) => {
    return polyline.split(';').map(point => {
      const [lng, lat] = point.split(',').map(Number);
      return [lng, lat];
    });
  };

3.为行政区域画出边界线和外部区域的阴影

const drawPolygon = (boundary) => {
    const worldBounds = [
    [0, 90],    // 左上角坐标
    [180, 90],  // 右上角
    [180, -90], // 右下角
    [0, -90],   // 左下角
    [0, 90]     // 闭合路径
  ];
  // 1. 绘制外部灰色背景
  const outerBoundary = new AMap.Polygon({
    path: [worldBounds, boundary],
    strokeColor: '#D3D3D3',  // 灰色边界
    strokeOpacity: 0,        // 透明的边界
    strokeWeight: 0,         // 无边界宽度
    fillColor: '#D3D3D3',    // 灰色填充
    fillOpacity: 0.7,        // 灰色背景透明度
    fillRule: 'evenodd'
  });
  outerBoundary.setMap(map.value);

  // 2. 绘制鄞州区的蓝色边界
  const innerBoundary = new AMap.Polygon({
    path: boundary,
    strokeColor: '#318ec9',  // 蓝色边界
    strokeOpacity: 0.8,      // 边界透明度
    strokeWeight: 4,         // 边界宽度
    fillColor: 'transparent', // 内部不填充颜色
    fillOpacity: 0,          // 不填充
  });
  innerBoundary.setMap(map.value);
};

4.对地图添加标记的点位,自定义marker点击后的样式并添加点击监听

const addMarkers = () => {
  const data = mapData.value;
  
  // 加载 AMapUI 的 SimpleInfoWindow 组件
    data.forEach((item: any) => {
      const marker = new AMap.Marker({
        position: [item.longitude, item.latitude],
        title: item.bridgeName,
      });

      // 为每个标记创建独立的信息窗体
      const infoWindow = new AMap.InfoWindow({
        content: `
        <div class="my-desc">
          <strong>${item.bridgeName}</strong>
          <p>道路名称:${item.roadName || '--'}</p>
          <p>桥梁类型:${item.bridgeType || '--'}</p>
          <p>桥长:${item.totalLength || '--'}</p>
          <p>桥宽:${item.totalWidth || '--'}</p>
          <p>级别:${item.technicalConditionGrade || '--'}</p>
          <p>管养单位:${item.maintenanceCompany || '--'}</p>
          <p>荷载等级:${item.designLoad || '--'}</p>
        </div>
      `,
        offset: new AMap.Pixel(0, -31) // 调整信息窗体的偏移量
      });

       // 存储marker和infoWindow
      markersMap.value[item.id] = marker;
      infoWindowsMap.value[item.id] = infoWindow;
      // 点击标记时打开信息窗体
      marker.on('click', () => {
        infoWindow.open(map.value!, marker.getPosition());
      });

      marker.setMap(map.value!);
  });
};

5.地图组件外部card添加一个搜索组件,可以模糊搜索筛选已拿到的marker点位,并且打开正确的信息窗体

const onSearch = (item) => {
  console.log(map.value)
  const marker = markersMap.value[item];
  const data = mapData.value.find((e: any) => e.id === item);
  
  // 关闭之前的信息窗
  if (isSelectInfoMap.value) {
    isSelectInfoMap.value.close();
  }
  isSelectInfoMap.value = infoWindowsMap.value[item];
  
  // 打开信息窗并记录当前窗口
  infoWindowsMap.value[item].open(map.value!, marker.getPosition());
};
···