Hello,
I loaded a billboard in Cesium using czmldataSource, and its displayed on the map.
When I try to pick it and get its Id using pickObject.primitive.getId() I get "undefined". The same happens for pickObject.getId().
The only way I was able to get the Id, is to do: pickObject.primitive.dynamicObject.id
When I tried pickObject.primitive.dynamicObject.getId() I received an error that getId is not defined on Object etc...
When loading a billboard from the cesium js api, and setting its id, pickObject.primitive.getId() worked, and gave the id I set in code.
Is this correct behavior ? I would expect it to work the same, no matter how I added the billboard to Cesium, either using the API or loading with CZML.
Thanks
Of course I forgot to state that I added and id property to the czml object in czml. I expected to get this id when using getId() on the picked billboard as I stated.
I'm experiencing the same issue with the GeoJsonDataSource on Cesium b26.
The DynamicObject(s) loaded from the geoJson files have the correct _id values (whether it's provided in the geoJson file or generated as a GUID).
When I pick an object in the scene using the picker, the returned object has an undefined id.
Example:
var pickedObject = cesiumWidget.scene.pick(position);
// if pickedObject is defined
console.log(pickedObject.id); // 'undefined'
console.log(pickedObject.primitive.id.id); // the correct id
Is this the expected behaviour? Is the id getting lost along the way when picking?
I believe this is all expected behavior. Since b21, Scene.pick returns an object containing a primitive
property instead of the primitive itself. Primitives now have a standardized id
property which is intended to associate arbitrary external data with graphical primitives. Since b26, the DynamicScene layer stores the DynamicObject that corresponds to each primitive in that id
property. Then, if you want the string id, it’s a property on the DynamicObject. I agree it’s a little confusing that id
is used for two purposes in two different layers in Cesium.
So:
var pickResult = scene.pick(position); // the result of the pick, or undefined if nothing was picked
var primitive = pickResult.primitive; // the picked primitive
var dynamicObject = primitive.id; // the primitive’s dynamic object
var id = dynamicObject.id; // the dynamic object’s string id
Scott is mostly correct. It’s still not as standard as we want it to be. BillboardCollection is the primitive while each billboard is simply an object managed by BillboardCollection. So when you pick a billboard, the primitive that got picked is actually the billboard collection, while the id that gets returned is the id of the billboard that was picked. The individual billboard ID is currently a property added by the BillboardVisualizer and not a standard property of Billboard itself (I believe). We still need to clean up this area of the code, since everything works but it’s far too confusing.
Long story short, here’s some code we use to pick an object loaded from CZML that checks for both cases. It returns the DynamicObject instance associated with a picked object.
function pickDynamicObject(e) {
var picked = viewer.scene.pick(e.position);
if (defined(picked)) {
var id = defaultValue(picked.id, picked.primitive.id);
if (id instanceof DynamicObject) {
return id;
}
}
}
Thanks for the suggestions.
As you mentioned, it would be ideal to have one API for all types of data (primitives and dynamic).