Ideal method for creating a "Popup" to follow lng lat AND elevation of a Billboard

1. A concise explanation of the problem you’re experiencing.

An HTML popup gets initial billboard position, but does not get elevation position, so the popup does not match position of billboard as new elevation is downloaded with updated tiles.

Is there a way to update this HTML overlay with changes in elevation ?

or

Is there a better way to do this ?

Example site: https://dev.globaltimoto.com/

popup.png

Initially the popup appears to be in the correct position as above.

popup-2.png

After zooming in and dragging/rotating the scene the popup begins to drift from the billboard, presumably because the billboard has updated it’s elevation.

2. A minimal code example. If you’ve found a bug, this helps us reproduce and repair it.

This is the method used to get the position for the HTML overlay:

var canvasPosition = viewer.scene.cartesianToCanvasCoordinates( Cesium.Cartesian3.fromDegrees( position.lng, position.lat ) );

if ( Cesium.defined( canvasPosition ) ) {

    $overlay.css( 'top', canvasPosition.y + 'px' );
    $overlay.css( 'left', canvasPosition.x + 'px' );
}

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

I need this because an HTML popup can include the styling and scroll bars for vertical overflow where needed, and is best associated with the map content by being locked to the billboard.

4. The Cesium version you’re using, your operating system and browser.

Cesium 1.51, Windows, macOS, iOS, FF, Chrome, Safari

Also attempted the following with no change in behaviour:

position = marker.position.getValue();
var canvasPosition = viewer.scene.cartesianToCanvasCoordinates( position );

if ( Cesium.defined( canvasPosition ) ) {

    $overlay.css( 'top', canvasPosition.y + 'px' );
    $overlay.css( 'left', canvasPosition.x + 'px' );
}

Presumably viewer.scene.cartesianToCanvasCoordinates( position ) does not include calculation for elevation.

Can you show how you’re creating the billboard? I’m guessing it’s clamped to ground or has a height reference relative to ground?

If so, the problem is that the returned position is not the “actual” position. There is literally a private “actual” position that’s not exposed, see the discussion here:

https://github.com/AnalyticalGraphicsInc/cesium/issues/6995

Looks like the canonical way to do this in CesiumJS is to pass a height of scene.getHeight() as described in the last comment in the above issue. Let me know if that works!

Hello Omar

Thank you for your response.

The Billboard was being created like this:

var marker = markers.entities.add( {
                    position: Cesium.Cartesian3.fromDegrees( 23.908321, -9.872312 ),
                    billboard: {
                        image: '/images/UI/marker-game-star.png',
                        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                        width: 40,
                        height: 58
                    }
                } );

Following your advice the issue has been fixed.

Thank you very much for your suggestion.

Tim

for me HTML donot popup