Vue使用高德地图快速加载覆盖物

业务场景:需要在高德地图上加载地块数据并灵活切换。

效果图:8000多地块加载使用了2.几秒且无卡顿现象

 最开始使用的是将边界信息用AMap.Polygon绘制到地图上,发现界面会卡顿,通过Promise去异步加载并递归调用渲染,情况好了些但是加载速度久了很多,用户体验不是很好,最后使用了他的2.0版本Loca,话不多说直接上代码:

首先咱们得初始化地图:

import AMapLoader from "@amap/amap-jsapi-loader";  //引用高德

let mapLand; //声明地图对象
var loca = ""; //声明loca
let fillColor = "blue"; //默认
let strokeColor = "red"; //默认
let fillOpacity = 0.1; //默认
const riskType = ["类型A", "类型B", "类型C", "类型D"];

onMounted(() => {
  //初始化地图
  LoadMap();
  //我这里是暴露出来的,不暴露可以不写
  window.mapStore = mapStore;
});


//初始化地图
function LoadMap() {
  AMapLoader.load({
    key: "", // 申请好的Web端开发者Key,首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: ["Amap.Geocoder"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
    AMapUI: {
      version: "1.1", // AMapUI 缺省 1.1
      plugins: ["overlay/SimpleMarker"], // 需要加载的 AMapUI ui插件
    },
    Loca: {
      version: "2.0.0", //版本 此处需要填写!
    },
  }).then((AMap) => {
    mapLand = new AMap.Map("map", {
      mapStyle: "",  //地图样式 自行修改
      pitch: 40,
      center: [121.538319, 31.153452],
      zoom: 13,
      fitView: true,
      viewMode: "2D",
      zIndex: 100,
    });
   
    loca = new Loca.Container({
      map: mapLand,
    });
    //地块数据
    LoadLandDataXYs();
  });
}

接下来就是读取渲染数据:

//查询数据集合
async function LoadLandDataXYs() {
  await proxy.$request.get("你的接口url").then((res) => {
    if (res.data.code == 200) {
      changeXyToGeoJSON(res.data.result);
    }
  });
}

//地理坐标数据分类处理
var LandType = {};
function changeXyToGeoJSON(data) {
  data.forEach((gg) => {
    if (AreaNiCheng.landColor.hasOwnProperty(gg.landType)) {
      if (!LandType.hasOwnProperty(gg.landType)) {
        LandType[gg.landType] = [];
      }
      LandType[gg.landType].push(gg);

      if (!LandType.hasOwnProperty(gg.riskLevel)) {
        LandType[gg.riskLevel] = [];
      }
      LandType[gg.riskLevel].push(gg);
    }
  });
  for (let key in LandType) {
    setTimeout(() => {
      if (riskType.find((ff) => ff == key) == null) {
        ForDataChange(
          LandType[key],
          riskType.find((ff) => ff == key) != null ? "类型1" : "类型2",
          key
        );
      }
    }, 500);
  }
}

//将数据处理成GeoJSON
function ForDataChange(loadD, riskType, key) {
  let GeoJSON = [];
  loadD.forEach((e) => {
    let totalArea = [];
    e.areaPoints.forEach((ff) => {
      totalArea.push([ff.longitude, ff.latitude]);
    });

    GeoJSON.push({
      type: "Feature",
      //这里你需要什么属性都可以在此写入
      properties: {
        name: e.idNum,
        risk: e.riskLevel,
        landType: e.landType,
        landId: e.id,
        //……
      },
      geometry: {
        type: "Polygon",
        coordinates: [totalArea],
      },
    });
  });
  ShowMapData(GeoJSON, riskType, key);
}


//渲染数据
function ShowMapData(geoFeatures, type = null, key = null) {
  var geo = new Loca.GeoJSONSource({
    data: {
      type: "FeatureCollection",
      features: geoFeatures,
    },
  });

  //这里主要是给图斑赋值颜色 
  if (type == "类型1" || type == "类型2") {
    if (AreaNiCheng.landColor.hasOwnProperty(key)) {
      fillColor = AreaNiCheng.landColor[key];
      strokeColor = AreaNiCheng.landColor[key];
    } else {
      fillColor = AreaNiCheng.landColor["另外"];
      strokeColor = AreaNiCheng.landColor["另外"];
    }
  } else if (type == "村") {
    fillColor = AreaNiCheng.landColor["村区域"];
    strokeColor = AreaNiCheng.landColor["村区域"];
  }

  var pl = new Loca.PolygonLayer({
    loca,
    strokeOpacity: fillOpacity,
    zIndex: type == "xxx" ? 5 : 500,
    visible: key == "xxx" ? false : true,  //默认隐藏、显示
  });
  pl.setSource(geo);

  pl.setStyle({
    topColor: (index, feature) => {
      return strokeColor;
    },
    sideTopColor: (index, feature) => {
      return strokeColor;
    },
  });
 
  //地图点击事件
  mapLand.on("click", function (e) {
    var feat = pl.queryFeature(e.pixel.toArray());
    if (feat != null) {
      // console.log(feat)
    }
  });

  loca.add(pl);
  // 设置样式
  pl.setStyle({
    radius: 30,
    fillOpacity: fillOpacity,
    borderWidth: 10,
    topColor: type == "xxx" ? [255, 255, 0, 0.01] : strokeColor,
  });

  pl.render();

  var thisKey = `${type}-${key}`;
  if (!mapStore.controlGroup.hasOwnProperty(thisKey)) {
    mapStore.controlGroup[thisKey] = [];
  }
 
  //这里主要是在给不同类型的地块分组,方便后面切换
  switch (key) {
    case "xx":
      overlayGroupCbyd = overlayGroupHelperNew(pl);
      mapStore.controlGroup[thisKey].push(overlayGroupCbyd);
      break;
    case "xx":
      overlayGroupDz = overlayGroupHelperNew(pl);
      mapStore.controlGroup[thisKey].push(overlayGroupDz);
      break;
    case "xx":
      overlayGroupDc = overlayGroupHelperNew(pl);
      mapStore.controlGroup[thisKey].push(overlayGroupDc);
      break;
    //……
  }
}

//封装地图切换展示方法
function overlayGroupHelperNew(data) {
  return {
    arr: data,
    show: function () {
      data.show();
    },
    hide: function () {
      data.hide();
    },
  };
}

最后是切换类型,基本上加载完成后秒切:


//切换show or hide
function ShowOrHideMapElementFunNew(type, classes = null) {
  for (let key in window.mapStore.controlGroup) {
    //展示全量
    if (classes == null) {
      if (type == "??") {
        if (key.indexOf("??") >= 0) {
          window.mapStore.controlGroup[key][0].show();
        } else {
          window.mapStore.controlGroup[key][0].hide();
        }
      } else {
       if (key.indexOf("风险") >= 0 && key.indexOf("??")<0) {
          window.mapStore.controlGroup[key][0].show();
        } else {
          window.mapStore.controlGroup[key][0].hide();
        }
      }
    }
    //展示选择的类型 其余全部隐藏
    else {
      if (type == "XX") {
        if (key.indexOf("XX") <= -1) {
          if (key.indexOf(classes) >= 0) {
            window.mapStore.controlGroup[key][0].show();
          } else {
            window.mapStore.controlGroup[key][0].hide();
          }
        }
      } else {
        if (key.indexOf("XX") <= -1) {
          if (key.indexOf(classes) >= 0) {
            mapStore.controlGroup[key][0].show();
          } else {
            mapStore.controlGroup[key][0].hide();
          }
        }
      }
    }
  }
}

详细参考高德地图示例:杭州功能区-面图层-示例详情-Loca API 2.0 | 高德地图API高德开放平台官网https://lbs.amap.com/demo/loca-v2/demos/cat-polygon/hz-gn

如有不好的地方,请大佬们多多指教!

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值