cesium 3dtile单击选中

发布时间 2023-10-24 14:02:15作者: 1156740846

监听瓦片加载完成事件,将所有3dtile对象按id归纳到map中

    tileset.readyPromise.then(() => {
        console.log('tileset.readyPromise');
        tileset.setObjsColor()
    })

    // allTilesLoaded 会被调用多次  旋转、放大缩小模型时会触发这个事件,不适合用来做一次性的操作
    // tileset.allTilesLoaded.addEventListener(function() {
    //     console.log('All tiles are loaded');
    //     tileset.setObjsColor()
    // });

 将所有3dtile对象按id归纳到map中的方法

    // 初始化一个map
    Cesium.Cesium3DTileset.MyBuildMap = new Map()
    // 虽然定义的是个体方法,调用也是用个体对象调用,但是evaluateColor方法会执行所有Cesium3DTileset对象
    Cesium.Cesium3DTileset.prototype.setObjsColor = function () {
        let currentStyle = this.style && this.style.style || {};
        this.style = new Cesium.Cesium3DTileStyle({
            ...currentStyle,
            color: {
                evaluateColor: function (feature) {
                    if (!Cesium.Cesium3DTileset.MyBuildMap.has(feature.getProperty('id'))) {
                        Cesium.Cesium3DTileset.MyBuildMap.set(feature.getProperty('id'), [])
                    }
                    if (['gdgdfgdfgf', 'vcxvfg', 'dsfdf1'].includes(feature.getProperty('name'))) {
                        // gdgdfgdfgf a1d0c6e83f027327d8461063f4ac58a6 、vcxvfg 地面
                    } else {
                        Cesium.Cesium3DTileset.MyBuildMap.get(feature.getProperty('id')).push(feature)
                    }
                }
            }
        })
    };

 

点击事件

function myClickEvent(viewer, event) {
    // 500 毫秒内直接返回  防止双击触发2次单击事件
    if (window.selTime && window.selTime > new Date().getTime() - 500) { 
        console.log('500 毫秒内直接返回');
        return
    }
    window.selTime = new Date().getTime()

    // 屏幕坐标转为空间坐标
    let cartesian = getCatesian3FromPX(event.position, viewer);
    // 判断是否定义(是否可以获取到空间坐标)
    if (!Cesium.defined(cartesian)) {
        return
    }
    if (!viewer.selectedEntity) {
        return
    }

    viewer.trackedEntity = undefined
    
    let sel = viewer.selectedEntity
    window.sel = sel

    // pick有id字段时,id存放的是模型对象,也就是viewer.selectedEntity
    // pick有_batchId字段时,pick是Cesium3DTileFeature对象,选中的是3dtile对象,primitive字段存放Cesium3DTileset对象,
    //    此时的viewer.selectedEntity拥有_feature字段,存放的是Cesium3DTileFeature
    //    feature.getProperty('id'), feature.getProperty('name') 也就是 viewer.selectedEntity 的 id name 字段
    const pick = viewer.scene.pick(event.position)
    window.pick = pick

    // 射线选中的一堆对象
    var picks = viewer.scene.drillPick(event.position)
    window.picks = picks

    // 上一个对象 取消选中状态
    if (viewer.oldSel && viewer.oldSel.lcxUnActiveFun) {
        viewer.oldSel.lcxUnActiveFun()
    }

    // 模型对象
    if (sel.lcxActiveFun) {
        console.log('model click');
        sel.lcxActiveFun()
        viewer.oldSel = sel
    } 
    
    // 瓦片模型对象   sel是临时的,增加属性并不会被保存  这里使用pick对象
    else if (pick._batchId != undefined) { // pick._batchId 包含 0 值,会被认为是false,用undefined判断
        console.log('3dtile click', pick.getProperty('id'), pick.getProperty('name'), arr);
        let arr = Cesium.Cesium3DTileset.MyBuildMap.get(pick.getProperty('id'))
        arr.forEach(feature => {
            feature.color = Cesium.Color.YELLOWGREEN
        });
        pick.lcxUnActiveFun = function() {
            arr.forEach(feature => {
                feature.color = Cesium.Color.WHITE
            });
        }
        viewer.oldSel = pick
    }
}

 

这里的瓦片点击事件也可以使用瓦片对象调用setObjsColor方法,这样就不用创建MyBuildMap对象,但是每次都要过滤一遍所有瓦片对象,效率不高,而且有时候会出现setObjsColor方法无限循环的情况,导致页面卡住

    // 瓦片模型对象  这个代码 放在else里执行,只会被执行一次   因为第二次判断sel.lcxActiveFun会为true  sel是临时的,增加属性并不会被保存
    else if (pick._batchId != undefined) { // pick._batchId 包含 0 值,会被认为是false,用undefined判断
        console.log('3dtile click', pick.getProperty('id'), pick.getProperty('name'), arr);
        pick.primitive.setObjsColor([pick.getProperty('id')])
        viewer.oldSel = pick
    }
Cesium.Cesium3DTileset.prototype.setObjsColor = function (ids) {
    let currentStyle = this.style && this.style.style || {};
    this.style = new Cesium.Cesium3DTileStyle({
      ...currentStyle,
      color: {
        evaluateColor: function (feature) {
          console.log(feature.myId, feature._batchId, ids.includes(feature._batchId));
          if (ids.includes(feature._batchId)) {
            return Cesium.Color.RED;
          }
        }
      }
    })
  };