How to ignore the result of 3Dtiles only get Entites when i use LEFT_CLICK to click on 3Dtiles and entities?

I tried using
const pickedFeature = viewer.scene.pick(movement.position);
and realized it can return 3Dtile and Entites, I used

 if (Cesium.defined(pickedFeature)&& (pickedFeature.id._name === 'Video')) {
                viewer.selectedEntity = new Cesium.Entity({
                    name: pickedFeature.id._id,
                    description: pickedFeature.id._description,
                });
            }

to display the results of Entities but when I click on the 3Dtile I get an error as shown, how to read only the results of Entities ?

this is Entities result
image

this is 3Dtiles result
image
this is error
image

Never use properties with underlines, they are private (for the exact reason your application now throws an error). Also, Entities and 3DTilesets are very, very different kinds of objects, with different properties and different APIs, so you cannot expect them to behave in the same way. There are many different things that can be picked, all sorts of structures and properties within them. And that’s just a pick(), but there’s also a drillPick() which returns all objects found at the ray intersection point.

The first thing you do is check on the type that is returned, then adopt your behaviour to that type. You either check typeof (not safe), instanceof (safer; if (picked instanceof Cesium.Cesium3DTileset ) else if () … ), or infer (ie. picked.?tileset returns true for 3DTilesets, etc).

Next, a name or id is only set on objects where you have input control, but there’s plenty of stuff that’s automatically added to the map. Instead, whenever you ann anything to the viewer, inject your own custom properties to do specific manipulation (ie. viewer.entities.add({ …, myID:‘1234’, …) or add it manually after injecting the object (ie. myAddedTileset[‘myID’] = ‘1234’) and so on. I would think hard about a minimal set of properties, and use something that is a bit safe from future API changes in Cesium, so instead of “myID”, I’d go with “__ext_id” or somesuch.

Normally you’d have a controller (a cache machine or similar) that does all this for you. There’s no such controller (outside of the collections) in the Cesium API, so you need to make one (if you want that level of control). Also, you really shouldn’t base identification on names (of files or otherwise), but try to keep them to either numbers (integers) or strings as UUIDs, and have a lookup table to convert.

The shortest answer to your question is to wrap your pick in instanceof test or, for entities, test for primitives;

if ( pickedObject instanceof Cesium.Cesium3DTileset ) { ... // 3DTilesets }
else if ( pickedObject.primitive ) { ... // entities }

Cheers,

Alex

1 Like

thanks for reply, you help me to gain more knowledge, thanks a lot, let me try your way