高德3D地图-标点数字显示&点击&更新中心点

480 阅读4分钟

功能描述

  1. 地图初始化:系统加载时,默认显示南京市地图,确保地图清晰、完整。
  2. 区块着色:南京市的每个区块使用不同的颜色进行区分,颜色应鲜明、易于识别。
  3. 数字标注:在每个区块上方显示对应的数字标识,数字应清晰、准确,与区块一一对应。
  4. 告警信息响应:当用户点击告警信息时,地图中心点自动定位至告警信息所在位置,并进行人员定位。
  5. 定时返回:人员定位后,地图中心点在10秒后自动返回南京市地图中心位置,以便用户继续查看其他信息。

image.png image.png

<!--地图-->
<div id="container"></div>
window._AMapSecurityConfig = {
  securityJsCode: "",
};
import AMapLoader from "@amap/amap-jsapi-loader";
import iconNumURL from "../assets/images/iconNum.png";
import red1 from "../assets/images/red-1.png";
import red2 from "../assets/images/red-2.png";
import blue1 from "../assets/images/blue-1.png";
import blue2 from "../assets/images/blue-2.png";

let bEquipmentWarningRecordsInfo = ref({}); //信息

let map = ref(null);
let markers = ref(null);
let timeoutId = ref(null);
const center = ref([118.8, 31.7]); // 初始中心点
const propsArr = ref([]);


let initMap = (item) => {
  let itemInfo = item;
  AMapLoader.load({
    key: "", // 申请好的Web端开发者Key,首次调用 load 时必填
    // version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: [ 
      "AMap.DistrictSearch",
      "AMap.Object3D",
      "AMap.DistrictLayer",
      "AMap.Object3DLayer",], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
  }).then((AMap) => {
    var SOC = "CHN";
    var colors = {};
    // 存各个区中心点
    markers = [];
    // 南京-区
    var GDPSpeed = {
      320101: 10,
      320102: 10,
      320104: 8.5,
      320105: 8.5,
      320111: 8.5,
      320113: 8.0,
      320114: 7.5,
      320115: 8.5,
      320116: 8.0,
      320117: 7.5,
      320118: 7.5,
    };
    var getColorByDGP = function (adcode) {
      if (!colors[adcode]) {
        var gdp = GDPSpeed[adcode];
        if (!gdp) {
          colors[adcode] = "rgb(78,134,244,1)";
        } else {
          var rg = 255 - Math.floor(((gdp - 5) / 5) * 255);
          // 假设GDP增长速度在5到10之间,我们需要将其映射到天蓝色的范围内
          let normalizedGDP = (gdp - 5) / 5; // 将GDP增长速度归一化到0到1之间
          let r = 65 + Math.floor(normalizedGDP * (255 - 65));
          let g = 122 + Math.floor(normalizedGDP * (255 - 122));
          let b = 239 + Math.floor(normalizedGDP * (255 - 239));
          // colors[adcode] = "rgb(" + r + "," + g + "," + b + ")";
          colors[adcode] = "rgb(" + rg + "," + rg + ",255)";
        }
      }
      return colors[adcode];
    };
    map = new AMap.Map("container", {
      zooms: [4, 30],
      mapStyle: "amap://styles/dark", //设置地图的显示样式 darkblue
      zoom: 9,
      pitch: 40, // 设置俯仰角度
      rotation: -15,
      viewMode: "3D",
      center: center.value,
    });
    var distProvince = new AMap.DistrictLayer.Province({
      zIndex: 10,
      // SOC: 'CHN',
      adcode: ["320100"],
      depth: 2,
      opacity: 0.4,
      hideFloorBar: true,
      styles: {
        // 'nation-stroke': '#f09',
        // 'coastline-stroke': [0.85, 0.63, 0.94, 1],
        // 'province-stroke': 'white',
        "province-stroke": "cornflowerblue",
        fill: function (props) {
          propsArr.value.push(props);
          console.log(props, i + 1);
          updateMarkers();
          return getColorByDGP(props.adcode);
        },
      },
    });

    map.add(distProvince);
    map.add(markers);
    if (itemInfo) {
      setTimeout(function () {
        map.setCenter([itemInfo.longitude, itemInfo.latitude]);
        map.setZoom(15);
      }, 500);
      setTimeout(function () {
        // 116.80,40.12
        map.setCenter(center.value);
        map.setZoom(9);
      }, 10000);
    }

    var object3Dlayer = new AMap.Object3DLayer({ zIndex: 1 });
    map.add(object3Dlayer);

    var opts = {
      extensions: "all",
      level: "city",
      subdistrict: 0 // 不返回下级行政区
    };
    //利用行政区查询获取边界
    var district = new AMap.DistrictSearch(opts);
    district.search("南京市", function (status, result) {
      console.log(result.districtList, "9999999999999");
      if (status === "complete" && result.info === "OK") {
        var bounds = result.districtList[0].boundaries;
        console.log(bounds,'boundsboundsboundsbounds',JSON.stringify(bounds));
        var height = 30000;
        var color = "#0088ffcc"; //rgba
        var wall = new AMap.Object3D.Wall({
          path: bounds,
          height: height,
          color: color,
        });
        wall.backOrFront = "both";
        wall.transparent = true;
        object3Dlayer.add(wall);
      } else {
        console.error("搜索失败", status, result);
      }
    });

    let mergedStaffList = [].concat(
      ...Object.values(regionCountArr.value)
        .filter((region) => region.staffList?.length > 0)
        .map((region) => region.staffList)
    );

    map.on("zoomchange", function () {
      var zoomLevel = map.getZoom();
      let markerss = [];
      console.log(zoomLevel, "zoomLevel");

      // 放大到12级以上时显示所有人员位置
      // 标记每个区域员工-点
      // earlyWarningState  0  1
      console.log(mergedStaffList, "mergedStaffList");
      mergedStaffList.forEach((staff) => {
        console.log(staff, "staff-------");
        // type 1 2
        // 绘制位置标记
        let marker = new AMap.Marker({
          // map: map,
          icon:
            staff.earlyWarningState == 1
              ? staff.type == 1
                ? blue1
                : blue2
              : staff.type == 1
              ? red1
              : red2,
          position: [staff.longitude, staff.latitude],
          offset: new AMap.Pixel(-13, -30),
        });
        marker.info = staff;
        // 为标点绑定点击事件
        marker.on("click", function (e) {
          clickItem(e.target.info);
        });
        markerss.push(marker);
      });
      if (zoomLevel >= 12) {
        // marker.setMap(map);
        markerss.map((item) => {
          // map.add(item);
          item.setMap(map);
        });
      } else {
        map.clearMap();
        map.add(markers);
      }
    });
  });

};
//更新标点
let updateMarkers = () => {
  console.log("update");
  propsArr.value.map((props) => {
    let objQ = Object.entries(regionCountArr.value).find(
      ([name, data]) => name == props.NAME_CHN
    );
    let countNow = 0; //每个区数字
    if (objQ) {
      const { count, staffList } = objQ[1];
      countNow = count;
    } else {
      console.log("数据未找到");
    }
    if (countNow > 0) {
      let marker = new AMap.Marker({
        position: [props.x, props.y], // 标记的位置
        map: map,
        // icon: icon, // 使用定义好的图标
        content: `<div class="center"><div class="${
          countNow && countNow != 0 ? "show" : "hide"
        }"
            style="background: url(${iconNumURL}) no-repeat center center;padding:3.6rem 3rem; background-size:cover;position: relative;"
            >
              <div class="white" style="font-size: 12px;position: absolute;top: 22%;left: 50%;
              transform: translate(-50%, -50%);display: flex;flex-direction: column;align-items: center;">
              <div style="">${props.NAME_CHN}</div>
              <div class="mt-4">${countNow}</div>
            </div>
            </div></div>`, // 显示的数字
      });
      markers.push(marker);
    }
  });
};
//点击标单
const clickItem = (item) => {
  // 清除上一个延迟操作
  if (timeoutId) {
    clearTimeout(timeoutId);
  }
  chooseId.value = item.id;
  bEquipmentWarningRecordsInfo.value = item;
  // 定义延迟更新的函数
  const updateMap = () => {
    map.setCenter([item.longitude, item.latitude]);
    map.setZoom(15);
  };
  // 定义延迟重置的函数
  const resetMap = () => {
    chooseId.value = bEquipmentWarningRecordsInfo.value.id;
    map.setCenter(center.value);
    map.setZoom(9);
  };
  // 延迟100毫秒更新地图
  timeoutId = setTimeout(updateMap, 100);
  // 10秒后重置地图并更新选择的项目
  timeoutId = setTimeout(() => {
    bEquipmentWarningRecordsInfo.value = bEquipmentWarningRecordsArr.value[0];
    chooseId.value = bEquipmentWarningRecordsInfo.value.id;
    resetMap();
  }, 10000);
};