Position of Billboard on a building/3D Tile or Extrusion/Lollipopping

Hi,

I have a billboard, which I would like display over/at a building.

myDataSource.entities.add({
position: Cesium.Cartesian3.fromRadians(latlon.longitude,latlon.latitude),
billboard: {
image: “./whiteShapes.png”,
imageSubRegion: new Cesium.BoundingRectangle(67, 80, 14, 14),
color: new Cesium.Color(0.5, 0.9, 1.0, 1.0),
scale: 2.0,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
});

This marker now changes the position, if I navigate around the building, because of the heightReference → it sits on the “walls” and on the other side because I disabled the DepthTest it is seen from everywhere.

Is there a possibility to get/pick the height of the buildings (3D-Tiles) and set the billboard on top ? Do I need a position callback (? I’m using typescript, error is known) ?

Or has anyone experience with extrusion and lollipopping ?

“In many cases, billboarded or cubed symbols are raised above the ground surface using a marker post, a technique sometimes called “lollipopping”. The user can set an arbitrary height above ground surface and drop down lines connect the symbol to its ground location.”

Rüdiger

Hi Rüdiger,

I’m stuck with the same problem and I was wondering if you were able to find a solution for the problem?

Or maybe there is someone reading this and can help out with some information.

EDIT:

I actually found the solution. The method clampToHeight() of Cesium.Scene is what I was looking for:

https://cesium.com/learn/cesiumjs/ref-doc/Scene.html#clampToHeight

EDIT 2:
with clampToHeight I experienced some problem, when there is no Tileset at this position. It seems sampleHeight() works better since it returns either a height or undefined if there is no Tileset.
With this information you can easily set the billboards heightReference to either CLAMP_TO_GROUND or NONE.

      const height = this.viewer.scene.sampleHeight(Cesium.Cartographic.fromDegrees(lon, lat))
      marker = this.viewer.entities.add({
        id: markerId,
        position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
        billboard: {
          image: "img/marker.png",
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          color: Cesium.Color.fromCssColorString(highlightColor),
          heightReference: height ? HeightReference.NONE : HeightReference.CLAMP_TO_GROUND
        },
        })

thanks,

Steffen