I have a working mouse click handler assigned to my Cesium scene's canvas. I am using the scene.pick() function to return the selected object. I'd like to see if the picked object is a billboard from my BillboardCollection via assigning a "pickedObject" to the object returned by scene.pick(). However, when I do so, I get a JavaScript error that complains that "pickedObject" does not have a property 'x'.
I don't have the code I'm using available at the moment but I am modeling my work from the Sandbox mouse move example. In that example, however, the function always knows which billboard to check for because there is only one added to the scene. This case is too simple for my situation.
Is there a better example to peruse? FYI, I am not using CZML.
Secondly, is it not possible at this point to add a Polyline *object* to a PolylineCollection? The examples never show it done this way and Cesium yells at me when I try. Going with the polylines.add({positions:... Option, is it possible to still use the "computeEllipseBoundary" method rather than specifying specific points?
Thank you for your assistance. Great product with amazing potential.
var pickedObject = scene.pick(movement.endPosition);
if (billboard && pickedObject === billboard) {
//etc
}
You’re right that this is built on the assumption that there’s only one billboard.
I would suggest trying to use BillboardCollection.contains to check whether pickedObject is in the collection or not, but the current implementation of contains is naively implemented and appears to error out if passed any object that’s not a billboard, which is a pretty glaring oversight.
I’ll fix this in our code, but in the meantime, a workaround is to add your own property to the billboards, and then you can check for that property on the picked object to see what kind of thing it is.
So, for example, when you add the billboards:
var billboard = billboards.add({
// etc
});
billboard.isBillboard = true;
Then later, you can do
var pickedObject = scene.pick(movement.endPosition);
if (pickedObject && pickedObject.isBillboard) {
// you know its one of your billboards
var position = pickedObject.getPosition();
}
We do a similar thing in CZML. Each primitive created by the DynamicObject system gets an extra dynamicObject property added to it, which contains the reference back to the corresponding DynamicObject.
Secondly, is it not possible at this point to add a Polyline object to a PolylineCollection? The examples never show it done this way and Cesium yells at me when I try. Going with the polylines.add({positions:… Option, is it possible to still use the “computeEllipseBoundary” method rather than specifying specific points?
Polylines now following the same pattern as Billboards, so a polyline is created with a call to PolylineCollection.add. This still works with computeEllipseBoundary. For example:
var polylines = new Cesium.PolylineCollection();
polylines.add({
positions : Cesium.Shapes.computeCircleBoundary(
ellipsoid, ellipsoid.cartographicToCartesian(
new Cesium.Cartographic.fromDegrees(-82.0, 37.0)), 300000.0)
Thanks, Patrick, and Scott, for your advise. I am still running into an issue picking the object from the scene, but in the meantime I’m going to work on the PoylineCollection usage you mentioned below.
Thank you for the suggestion/approach and for letting me know beforehand that BillboardCollection.pickedObject may not be successful.
I’m still encountering the same problem, and it appears as I call scene.pickObject(movement.endPosition). It almost seems like something is obstructing the mouse interaction with the canvas, it knows it’s been clicked but isn’t able to access the scene correctly? Would love to see if you guys have any ideas…(running Chrome v. 21 stable). Thank you!
Chrome debugger shows that it hops over to Scene.js (line 256) and runs the following snippet:
return this._pickFramebuffer.end({
x : windowPosition.x,
y : (this._canvas.clientHeight - windowPosition.y)
});
Uncaught TypeError: Cannot read property ‘x’ of undefined
The error is, “Uncaught TypeError: Cannot read property ‘x’ of undefined”.
I setup my mouse handler as follows:
In the instantiation of a “CesiumMap” object (our own), I called addMouseHandler(this._scene); (I’ve checked and this._scene is valid).
addMouseHandler:
var addMouseHandler = function(scene) {
var animation;
var handler = new EventHandler(scene.getCanvas());
var pickedObject;
handler.setMouseAction(
function(movement) {
console.log(“scene=” + scene); // exists
pickedObject = scene.pick(movement.endPosition); // fails here as this will in turn call Scene.prototype.pick()
I think I see the problem. Mouse click events (like LEFT_CLICK or RIGHT_CLICK, etc) give you an object that only has a position property, whereas mouse move events have both startPosition and endPosition.
Since you want to do a pick in response to a click event, change endPosition to position.
I see in the current examples that we use the parameter name “movement” in the handler for both click and move events, which is misleading. I’ll change this, and check to see if we have a picking example that uses clicks in addition to one based on move events (we should show both).
Also, if you update to the latest Cesium code in the master branch on Github, I’ve fixed the problem with BillboardCollection.contains. With that fix, you can use that to check if a picked object is one of the billboards in your collection if you prefer, or you can stick with the .isPlatform property check, which is also fine.
Awesome, works great! Thanks…I just didn’t find much about handling events in the documentation and (wrongly) figured the movement property would be the same.
Would the Cesium developers accept assistance on main baseline, perhaps in the area of documentation? I would be happy to help contribute.
Thanks for the kind offer. We certainty welcome and appreciate contributions to the reference documentation. There are a number of DOC_TBA placeholders that we’d appreciate help with. You can fork the repo, make changes, and send us a pull request. See the Contributor’s Guide. We also welcome other forms of documentation like tutorials, overviews, and sample apps. See the Roadmap.
For all contributions, we have a Contributor License Agreement (CLA) that ensures that you retain copyright to your contributions, and that we can use them. See the Contributing Code code section in the Contributor’s Guide (some bullets in that section like JSHint and unit tests are not relevant to doc contributions).
so i’m in the situation that i can either add the bendable line (per the sandbox) or have an updateable collection with no bendable and material lines (per the above code)
We recommend you use the entity API as seen in the Polyline sandcastle example unless you have a reason not to do so. If you explain what you are trying to accomplish, I would be glad to help.