如何只展示当前地图可视区的定位mark

480 阅读2分钟

如何只展示当前地图可视区的定位mark

map.jpg

前言

之前在项目里面需要在地图上展示很多mark,因为数据量过大,同时生成大量的定位mark,导致地图加载以及拖动变卡顿。因此在展示定位mark的时候就需要进行懒加载(这里的懒加载是我自己认为的),也就是只加载当前地图视区内的定位mark,视区外的定位mark不加载,当定位mark的坐标进入当前视区后再加载。

获取地图四个边角点的坐标

通过openlayers的calculateExtent方法可以获取到地图四个边角点的坐标。

const mapInfo = this.map.getView().calculateExtent(this.map.getSize()); // getView是获取地图view的方法

获取到的mapInfo是由四个边角点的经纬度组成的一个数组,其中:

左上边角点:经度mapInfo[0],纬度mapInfo[3]

右上边角点:经度mapInfo[2],纬度mapInfo[3]

左下边角点:经度mapInfo[0],纬度mapInfo[1]

右下边角点:经度mapInfo[2],纬度mapInfo[1]

根据获取到的地图四个边角点坐标计算当前地图视区内的定位mark

// 生成地图定位mark
const overlayDom = document.querySelector(`#overlay-element-${factory.id}`);
const imgDom = document.querySelector(`#img-${factory.id}`);
const anchor = new window.ol.Overlay({
  element: imgDom,
  className: `customer-anchor customer-anchor-${index}`,
  positioning: "center-center",
  position: positions[index],
});
// 计算mark是否在地图视图内
let newAnchors = {};
for (const key in anchors) {
  const posi = anchors[key].getPosition(); // 获取定位mark的坐标,getPosition是获取地图view坐标的方法
  // 判断地图定位mark是否在当前地图视区内
  if (posi[0] > mapInfo[0] && posi[0] < mapInfo[2] && posi[1] < mapInfo[3] && posi[1] > mapInfo[1]) {
    newAnchors = { ...newAnchors, [`${key}`]: anchors[key] };
  }
}
// 将计算过后的新地图mark return
return {
  newAnchors,
};

将计算过后的新地图mark添加到地图view上

// 添加地图mark到地图view,addOverlay是地图添加mark方法
// 如果实际需求需要先移出地图mark可以使用removeOverlay方法,用法同addOverlay
that.map.addOverlay(newAnchors[item.id]);

结论

经过计算当前地图视区内的定位mark,再加载到地图view上,可以有效的优化地图加载大量mark而造成的卡顿问题

参考