百度地图-大数据量点实时更新

本文介绍如何处理大数据量的地图点实时更新,避免闪烁和性能问题。通过监听数据变化,智能更新点的位置和数量,结合百度地图的点聚合功能优化显示。同时讨论了在点聚合下删除、添加和修改点的挑战,以及优化地图拖动和加载性能的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

闲话

上一篇文章本来打算记录一下自己做的东西,没想到第一次得到了大哥们的点赞特别开心(●'◡'●),接下来我也会多写写东西的

一.需求和思路

百度地图大多数前端开发者都使用过,或者是高德地图之类的第三插件。(要用好第三方插件,过程总是特别的痛苦┭┮﹏┭┮)很多人一定和我一样遇到过需要实时监控数据点的需求,通过WebSocket、SSe甚至http定时获取和后台建立连接,当数据点发生变化时,后台将数据推送过来,然后前端将地图上的点更新。

那么地图更新的时候会出现那些问题呢?

  1. 每次更新数据点,就算那个数据点经纬度和图标都没有变化,也会出现闪烁。
  2. 数据量过大会导致百度地图渲染很慢,出现浏览器卡顿甚至卡死的问题。
  3. 数据量过多在层级拉小的时候会因为点过于密集导致看不清楚。

思考一下。。。

  1. 如果可以做到每次只更新改变经纬度或者其它信息了的数据,这样就能避免大面积闪烁问题。
  2. 如果每次更新不用重新画点只改变经纬度和图标,应该能够提高一些性能。
  3. 百度地图有一个点聚合的功能,应该可以解决这个问题。

开始动手!

有了想法,那就可以开始动手去实现了!(●'◡'●),其实之前对于百度地图api不是特别的熟悉,只是会简单的使用,这次为了这个优化特地去补习了一下,可能有些地方还是考虑好,欢迎您能评论和我交流交流*^____^*。

二.思路实现

如何监听数据变化?

(为了方便 我这里用定时器动态生成数据点模拟数据更新)

首先我对于之前思考的第一点,应该存粹是一个js的问题,只要把新获取的数据与之前的数据进行比较筛选之后拿到我们需要的数据就行了。不过在这之前我们先解决另外一个问题,如果我想把它做成 一个组件我怎么才能知道点数据更新了呢,第一反应是用watch,不过用过的人应该都知道watch对于数组里面存储对象的这种数据无法监控到对象内部数据的改变,如果的确需要监控只能开启深度监听deep: true,考虑到点的数据很多,这种监控会对性能造成很大的影响我选择父容器拿到新的数据的时候主动告知组件更新数据,我们看一下代码。

//父级
<mapBaidu :mapChange="isChange" :mapDateOld="mapDataTableOld" :mapDateNew="mapDataTable"></mapBaidu>
data () {
    return {
      isChange:false,//数据是否改变
    }
  },
//组件mapBaidu
watch: {
    mapChange: {
      handler() {
       console.log("数据发现改变");
      }
    },
  }复制代码

我们通过修改isChange的值来进入watch,然后做逻辑处理。

下一步处理数据!

(数据是模拟数据 我们现看一下数据格式,方便看懂后面的话)

       {
          id:index,//唯一标识
          lng:120+Math.random(),//经度
          name:`点${index}`,//名称
          lat:30+Math.random(),//维度
          icon:Math.random()>0.5?"car-normal.png":"car-speeding.png"//图标
        }复制代码

知道了数据变化之后我们就应该开始对数据做处理了,首先我们再来看一下我们需要什么数据!

  1. 旧数据中应该删除的点
  2. 新数据中应该添加的点
  3. 旧数据中应该修改经纬度或者图标之类信息的点
那么大脑中的 fitter、reduce、foreach、 indexof、 some、map、find都开始蠢蠢欲动了,首先 第1点第2点其实比较简单,我们只需要分别获取新数据的id数组 newIDList,然后拿这个数组 newIDList和旧数据 oldPintList比较找到旧数据中的 id不在这个数组中的点那么这些点就是需要删除的点 delPointID,需要添加的点就是反过来找。那么 第3点呢其实也是一样的我们在处理第一点的时候可以保存一下旧数据 oldPintList中需要删除的点以为的点 otherPointList,然后循环这个数组 otherPointList和新数据 newPintList比较id相同的点的经纬度和图标是否相同,如果出现变化则保存新数据 newPintList中对应的点为需要修改的数组 changePonitList我们看看代码,其实可能还要其他思路我暂时只想到这个如果你有更好的想法可以和我分享一下。

    //比较新旧数组的不同
    filterMap(oldPintList, newPintList) {
      let delPointID = [], //相对于新获取的点需要取消的点的id数组
        otherPointList = [], //相对于新获取的点不需要取消的点
        addPointList = [], //相对于旧的数据点需要添加的点
        newIDList = new Set(), //定义一个数组用来存新数据的id的集合
        oldIDList = new Set(); //定义一个数组用来存旧数据的id的集合   
      newPintList.forEach(item => {
        newIDList.add(item.id);     
      });
      oldPintList.forEach(item => {
        oldIDList.add(item.id);     
      });
      oldPintList.forEach(item =>
        newIDList.has(item.id)? otherPointList.push(item):delPointID.push(item.id)
      );
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值