Bootstrap

Cesium 点击获取场景 Entity

Cesium 点击获取场景 Entity

需求描述:(1)使用 Cesium 构建地形图并且放置了三维模型后,需要实现点击三维模型变换颜色。(2)点击另外一个模型,前一个通过点击变换颜色的模型须将颜色换回来。
解决方案:对于第一个需求,我们使用 Cesium 中 viewer.scene.pick() 获取 entity 后直接更改entity 的 model 属性;对于第二个需求,我们需要利用设置监听函数,获取鼠标左击的地图位置,再通过 viewer.scene.pick() 抓取在该位置的 entity 并对其更改属性。

关键函数介绍

new Cesium.ScreenSpaceEventHandler(canvas)

这没什么好说的,设置监听事件首先需要对画布设置事件监听

ScreenSpaceEventHandler.setInputAction(action, type, modifier)

setInputAction 函数注册事件监听器,函数三个参数(第二个没用过)。第一个参数为回调函数,第三个为事件触发的动作。

viewer.scene.pick(windowPosition)

pick 函数接受一个 Cartesian2 的对象表示鼠标所在的屏幕位置,函数用于拾取将鼠标位置所代表的地理坐标的对象,主要有:Entity(实体)、Primitive(基元)、Tileset(瓦片集)等等。如果点击空白或者地形图等,则会返回 undefine

viewer.entities.getById(id)/EntityCollection.getById(id)

getById 函数接受一个参数 id,该函数用来实现通过 entity 的 id 属性寻找对应的实体。

代码展示

//点击模型获取信息并且更换模型
    let colored_entity_id = 0; //记录换颜色的模型id
    var handler_1 = new Cesium.ScreenSpaceEventHandler(canvas);
    handler_1.setInputAction(function(movement){
      var pick = viewer.scene.pick(movement.position);//拾取鼠标所在的entity
      if (Cesium.defined(pick)) {
        var colored_entity =  viewer.entities.getById(colored_entity_id);//查看是否已有换颜色的模型
        if(Cesium.defined(colored_entity))//如果有,先将换颜色的模型换回来,在把当前模型换色
        {
          colored_entity.model.uri = "/1.glb";
          pick.id.model.uri = "/2.glb";
          colored_entity_id = pick.id.id;
        }else{//如果没有,直接把当前模型换色
          pick.id.model.uri = "/2.glb";
          //this.former_id = pick.id;
          colored_entity_id = pick.id.id;
        }
      }
    },Cesium.ScreenSpaceEventType.LEFT_CLICK)

在这里插入图片描述
在这里插入图片描述

问题

吐槽一句,viewer.scene.pick() 你是珍妮嘛坑啊!!!!!
原本以为 viewer.scene.pick() 和 viewer.entities.getById() 都会返回 entity 对象,于是我的原先的代码是这么写的。

if(Cesium.defined(colored_entity))
        {
          colored_entity.model.uri = "/1.glb";
          pick.model.uri = "/2.glb";
          colored_entity_id = pick.id;
        }else{
          pick.model.uri = "/2.glb";
          colored_entity_id = pick.id;
        }

一直失败,后来我去查了一下文档发现两个函数是这么定义的:
在这里插入图片描述在这里插入图片描述
我发现,viewer.entities.getById() 返回的是 entity,但是 viewer.scene.pick() 返回的是一个 object 的东西,文档解释这个 object 包含了 primitives 的特征,那既然如此我就不能像直接访问 entity.id 的形式去访问这个 object 的 id 了。通过调试我发现,果然!entity.model.uri 不可以,entity.id.model.uri 才可以;pick.id 不可以,pick.id.id 才可以😭😭😭😭

请添加图片描述

;