监听瓦片加载完成事件,将所有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; } } } }) };
效果
标签:getProperty,单击,3dtile,viewer,feature,Cesium,pick,cesium,id From: https://www.cnblogs.com/LcxSummer/p/17784657.html