is it possible to have a billboard as a link to an external site?

hi,
i want to achieve the following:

palce billboards and labels on the globe.
then when i click on them, go to any website.
how can i make this happen?

thanks:)

You’ll want to do a combination of Cesium event handling and normal web-type JS behavior.

Go look at the “Picking” example in the Cesium Sandcastle demo page. Check out the code for the “Erode Sensor on Click” section. The idea is that you set up a ScreenSpaceEventHandler that listens for a certain event type (like a LEFT_CLICK), then “pick” the globe and get a reference to whatever object was under the mouse at that time. This may be a label, billboard, etc. Labels and billboards are normal JS objects, and can have arbitrary fields attached to them.

So, in your case, you’d want to create a label, add a new field like “url” to the object, and set up the pick handler. In the pick handler, if the picked object is not null and it has a “url” field, go open up the new tab/window with that url.

thanks alot for the explanation.
unfortuantely i cant get the code right?

is there any way you could help me out here?

just the block youve described would be fine :slight_smile:

thanky again :):):slight_smile:

  1. Go here

  2. Paste the below code in the window on the left.

  3. Hit ‘Run’

  4. When the user clicks on the cesium logo billboard, they open a link to a new page.

var widget = new Cesium.CesiumWidget(‘cesiumContainer’);

var ellipsoid = widget.centralBody.getEllipsoid();

var scene = widget.scene;

var primitives = scene.getPrimitives();

var billboards = new Cesium.BillboardCollection();

primitives.add(billboards);

var image = new Image();

image.onload = function() {

"use strict";

var textureAtlas = scene.getContext().createTextureAtlas({image : image});

billboards.setTextureAtlas(textureAtlas);

var billboard = billboards.add({

    position : ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-75.59777, 40.03883)),

    imageIndex : 0

});

billboard.linkForPick = '[http://cesium.agi.com](http://cesium.agi.com)';

};

image.src = ‘…/images/Cesium_Logo_overlay.png’;

var handler = new Cesium.ScreenSpaceEventHandler(scene.getCanvas());

handler.setInputAction(function(movement) {

"use strict";

var pickedObject = scene.pick(movement.position);

if (typeof pickedObject !== 'undefined' && typeof pickedObject.linkForPick !== 'undefined') {

    window.open(pickedObject.linkForPick, '_blank');

}

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

thank you very much,
im going to try it right away.
i just have to port it to my local webserver :slight_smile:

i'll post on the success!

thank you :slight_smile:

so it finally worked out :slight_smile:
thanks all.

i create the billboard, say:

//Google
var billboard = billboards.add({
position : ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-105.270546, 40.014986)),
imageIndex : 0});
billboard.linkForPick = ‘http://www.google.com/intl/de/about’;

and the i do this

var handler = new Cesium.ScreenSpaceEventHandler(scene.getCanvas());
handler.setInputAction(function(movement) {
    "use strict";
    var pickedObject = scene.pick(movement.position);
    if (typeof pickedObject !== 'undefined' && typeof pickedObject.linkForPick !== 'undefined') {
        window.open(pickedObject.linkForPick, '_self');
    }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
            scene.getPrimitives().add(labels);}

it runs a bit jaggy, but okay :slight_smile:
what i then did was call this html site in another html site via iframe,
so i have an overlay logio, that remains on top even on external sites,
so ican always come back to my locally hosted globe.

exactly what i want.

thakns all :slight_smile:

I'm trying to create similiar element, but in this case it should be clickable plane. After clicking the plane there should open url address. Would you be so kind and update the code for plane too ?

It should be no different from the above code. Try it out, and if it doesn’t work, post a Sandcastle (https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/) of your attempt (click “Share” in the top and paste your link here) and I’d be happy to take a look.

Hi Omar,

Thanks for replay ! The problem is the code above does not work when pasted into sandcastle. I truly do not know the reason why. And does it work, when you try it in sandcastle?

I think there were just some syntax errors and the CesiumJS pick API might have changed slightly since. The examples on Sandcastle (https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/) are regularly updated and maintained, so that’d be where I’d look. You can find examples there of using Scene.pick as well as creating billboards which is all you need.

Here’s an updated Sandcastle link as of CesiumJS 1.53.

Hello Omar,

Thank you for your kind help in correcting the code. Now it works perfect with planes too :slight_smile: I do really appreciate your help.

One more thing I'm trying to invent, but due to lack of technical background, I can't obtain the effect by myself :frowning:

What I would like to achieve is to join 2 functions: "click plane and open url" and "slight change size of plane, when mouse is over" That would encourage potential user to click on plane.

Here's the code I tried to adapt from sandcastle. I paste it below in full version to avoid deleting the message by admin.

If you would be so kind, share your experience, have a look and correct the code below, you would make me fully happy, and let me finish the dream globe widget on my website :slight_smile: Thank you in advance !

var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;

var plane = viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(18.0, 53.0, 500000.0),
      plane : {
        plane : new Cesium.Plane(Cesium.Cartesian3.UNIT_Z, 0.0),
        dimensions : new Cesium.Cartesian2(1600000.0, 1200000.0),
        material : '../images/Cesium_Logo_overlay.png',
        outline : true,
        outlineColor : Cesium.Color.BLACK
      }
});

plane.linkForPick = ‘https://www.google.com/’;

viewer.screenSpaceEventHandler.setInputAction(function(mouse) {
    var pickedObject = viewer.scene.pick(mouse.position);

    if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id.linkForPick)) {
        window.open(pickedObject.id.linkForPick);
    }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
      
var handler;

  handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);

    handler.setInputAction(function(movement) {
        var pickedObject = viewer.scene.pick(movement.endPosition);
        if (Cesium.defined(pickedObject) && (pickedObject.id === plane)) {
            plane.scale = 2.0;
        } else {
            plane.scale = 1.0;

        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

There is no “scale” property on entities or planes. One way to do this is to alter the dimensions, but it seems pretty choppy.

Sandcastle link.

I think you might need to create a duplicate entity in the same location, that happens to be bigger, and toggle show/hide on mouse over to make it smooth.

Hi Omar, great idea :slight_smile: I'll try it out - and check it out, especially on mobile phones. Thanks for solution :wink:

Hi Omar,

Thank you for your kind help!

Finally I have what I planned to do :slight_smile:

http://www.michalstefaniak.com/swiat/