Entity with Ellipsoid Graphic Position Appears to Change When Tilting Globe

I’ve been adding ellipsoid entities to represent noise monitor locations. However, most of the locations have been near an ocean or in areas with elevation near sea level. I recently looked at data around Denver, CO and noticed that the position of the ellipsoids appears to move/glide across the surface of the globe when I tilt the globe.

It’s hard to show very well in a picture, but I’ve added a couple of screenshots to try to better illustrate the issue. The first picture is looking straight down, and the ellipsoids are positioned where they should be. However as I start to tilt the globe away the ellipsoids appear to move across the surface of the globe toward the camera as seen in the second picture (all of the ellipsoids appear to move… I added a few arrows near ones that have easy visual references in the tiles around them).

I have not been able to replicate the issue in Sandcastle. I put the following example together, but as I stated it does not exhibit the problem. This makes me wonder if my globe/elevation settings are somehow coming into play. I could have just added one ellipsoid entity (and I did initially), but in order to eliminate as many variables as possible I tried replicating my code in the Sandcastle example as closely as I could. The ellipsoid radii and material along with the label text are updated via callback properties in my code. But when I eliminate the callback properties and simply set a value as in this example I still am getting the same position moving issue.

Any ideas as to why these ellipsoids would appear to move when I tilt the globe?

Thanks,

Rob

Sandcastle example:

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var lstNMS = ;
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.71386, 39.91342, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.71449, 39.94071, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.69054, 39.97209, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.52659, 39.88391, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.52661, 39.86758, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.62164, 39.79782, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.66348, 39.75366, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.75777, 39.84132, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.75127, 39.93749, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.79585, 39.95961, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.83249, 39.97904, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.94630, 39.94179, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.93377, 39.92068, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.96673, 39.91066, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.93136, 39.90431, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.94985, 39.88058, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.94443, 39.86318, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.95437, 39.83997, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.91327, 39.83498, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.91656, 39.80739, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.83585, 39.75997, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.83780, 39.71838, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.80171, 39.71663, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.75819, 39.74609, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.63775, 39.92862, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.74136, 39.91173, 0));
lstNMS.push(Cesium.Cartesian3.fromDegrees(-104.80629, 39.99073, 0));

var lstEllipsoids = ;

for (var i=0; i<lstNMS.length; i++) {

var pos = lstNMS[i];

var newEllipsoid = viewer.entities.add({
    id: 'id'+i,
    name : 'e'+i,
    position: pos,
    show: false,
    ellipsoid : {
        radii : new Cesium.Cartesian3(500.0, 500.0, 1),
        material : Cesium.Color.YELLOW
    },
    label: {
        text: '67',
        font: '100 72px sans-serif',
        fillColor: Cesium.Color.BLACK,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 1.0,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        scale: 0.2,
        eyeOffset: new Cesium.Cartesian3(0.0, 0.0, -200.0)
    }
});

lstEllipsoids.push(newEllipsoid);

}

for (var j=0; j<lstEllipsoids.length; j++) {
lstEllipsoids[j].show = true;
}

viewer.zoomTo(viewer.entities);

``

By the way I am experiencing a similar issue with wall entities. When I make the walls visible in the scene and tilt the globe the walls appear to move across the globe toward the camera.

I am creating the walls with the following code…
var newCurtainSeg = cesiumViewer.entities.add({
id: this.TrackId,
wall: {
positions: new Cesium.CallbackProperty(this.updateCurtainPositions(this), false),
material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(this.updateCurtainColor(this), false))
}
});

``

Again, I am updating the positions and materials with callback properties. But even if I remove the callback properties and set fixed positions I get the same issue.

I’m wondering if I have something with my globe or elevation data that is possibly an issue. I’m using a CesiumTerrainProvider when I initialize the viewer with the stk-terrain elevation data as follows…

terrainProvider: new Cesium.CesiumTerrainProvider({
url: ‘https://assets.agi.com/stk-terrain/world’,
requestVertexNormals : true
}),

``

Or maybe I’m missing something when adding the entities?

Any help would be greatly appreciated!

Rob

This sort of parallax effect is nearly always because the entities are not actually positioned on the surface of the terrain. A height of 0 is usually relative to the ellipsoid, meaning that in most places on Earth the graphics are actually being drawn far below the terrain surface.

Hi Scott,

Thanks for the response! I was under the impression that setting a height of 0 for an entity had the effect of “clamping to ground”. Is this not correct?

Should I be determining the elevation at the surface and setting the height accordingly?

Thanks,

Rob

Hi Rob,

Actually, setting the height to 0 disables clamping. Geometry is automatically clamped to ground if no height is specified, or you can do it explicitly with heightReference : CLAMP_TO_GROUND. See some code examples here: http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Ground%20Clamping.html&label=Showcases

Hope that helps,

  • Rachel

Ok. I modified the code that draws the ellipsoids so that I first retrieve the elevation of the globe at the ellipsoid location using Cesium.sampleTerrainMostDetailed. I use the returned height to set the height of the individual ellipsoids, and the “parallax effect” is eliminated. Thank you for the help with this!

For the benefit of anyone interested… I’m experiencing what seems to be the same issue with the wall entity objects. I am using the wall entity to create “curtains” (trails that extend behind the aircraft for a certain distance and extend to the surface). Here’s an screen capture…

I can also just display trails that don’t extend to the ground. The trails are created using polylines. When I only display the trails (polylines) tilting the globe results in everything looking as it should. However, if I display the curtains (walls) then tilting the globe results in that same “parallax effect” as if the curtain is shifting toward the camera as the globe is being tilted away.

I was under the impression that the walls were drawn from the specified height (in the position) to the surface. The documentation describes the positions property as “A Property specifying the array of Cartesian3 positions which define the top of the wall.” and the minimumHeights property as “A Property specifying an array of heights to be used for the bottom of the wall instead of the globe surface.” I have been specifying the height in the position for the walls as meters above sea level. This seems to be correct as the height ends up matching the aircraft model height and the height of the other lines I display related to the aircraft.

However, I am working on providing a minimumHeights property, and it seems to be greatly improving the “parallax effect”. So I’m now trying to determine the best/most efficient way to provide sufficient minimum height values.

Hi Rachel,

Thank you for the response. I will try providing no height for the ellipsoid entities as that would be much better than me querying for elevation data.

Can you suggest the best method for me to address this issue with the wall entities I’m using to create the curtains I described? Or if there is another object that would be better suited for this application?

Thanks,

Rob

Rachel,

I tried passing no altitude/height value to the ellipsoid entity position, but that resulted in the same problem I’ve been experiencing. Maybe I’m doing this incorrectly? Here’s the code snippet…

var newObject = cesiumViewer.entities.add({
id: nm.id,
position: Cesium.Cartesian3.fromDegrees(nm.pos.LON, nm.pos.LAT),
// position: Cesium.Cartesian3.fromDegrees(nm.pos.LON, nm.pos.LAT, nm.pos.ALT),
show: false,
ellipsoid: {
radii: new Cesium.CallbackProperty(nm.updateMonitorSize_Ellipsoid(nm), false),
material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(nm.updateMonitorColor(nm), false))
},
label: {
text: new Cesium.CallbackProperty(nm.updateMonitorValue(nm), false),
font: ‘100 72px sans-serif’,
fillColor: Cesium.Color.BLACK,
// style: Cesium.LabelStyle.FILL,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1.0,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
scale: new Cesium.CallbackProperty(nm.updateLabelScale(nm), false),
eyeOffset: new Cesium.Cartesian3(0.0, 0.0, -200.0)
}
});

``

I’m creating a Cartesian3 with ONLY longitude and latitude values to set as the position property. Is this not the correct way to “not” specify the height?

I’ll take a look at the examples for using the heightReference.

I don’t see the ability to specify the heightReference property for entity ellipsoids or entity walls. And if I pass a position that does not contain a height value (by creating a Cartesian3 with only the longitude and latitude) then I get the problem with the ellipsoids and walls appearing to move toward the camera when I tilt the globe away from the camera (when I’m at a location significantly above sea level such as Denver, CO).

I’m not sure what to do? Are there alternative objects I should use that would appear like the objects in the screen shots I’ve provided?

Thanks,

Rob

Hi Rachel,

When you said “geometry is automatically clamped to ground if no height is specified, or you can do it explicitly with heightReference: CLAMP_TO_GROUND” it sounded like you were saying the ellipsoid entities and the wall entities support some method of clamping them to the ground. But providing only longitude/latitude for their position doesn’t seem to work, and I don’t see support for heightReference for either of these objects.

Is there a way to accomplish “clamp to ground” for the ellipsoid entities and the wall entities (for the lower edge/bound of the wall)?

Thanks,

Rob

In order to address this issue with the entity ellipsoids and walls appearing to move when tilting the globe I am querying the terrain elevation for the ellispoids and setting the height portion of their position to the terrain elevation. I’m also coming up with an elevation value (roughly based on the elevation at and around the airport) to set the minimumHeights for the walls.

Doing this makes the ellipsoids appear to remain in the correct position and greatly reduces (almost eliminates) the “movement” of the walls when tilting the globe.

I would much rather take advantage of some method of “clamp to ground” for both of these object types. But so far I have not found a method that works. The position of an entity requires a Cartesian3. If I create a Cartesian3 position with just Lon/Lat values I still get the problem with the movement. And as far as I can tell neither of these objects supports the heightReference property.

If anyone knows of a method to successfully accomplish clamping to ground of the entity ellipsoids and/or the lower boundary of entity walls I would love know how. Also, if there are objects that would be better to accomplish the visual representations shown in the screen captures in this thread then I’d gladly change to those objects.

Thanks for any help!

Rob

Hi Rob,

Sorry If I misled you – I overlooked that you were just working with ellipsoids and walls. You are correct in that unfortunately neither of these geometry types have ground clamping support currently, nor support for heightReference. We have examples for all the geometry types with ground clamping here: http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Ground%20Clamping.html&label=All

What you’ll need to do to clamp ellipsoids to the ground is use sampleTerrainMostDetailed to compute a height. Given a lat/lon/height, you’ll be able to compute the correct positions as Cartesian3 s. Here’s a quick code example (I’ve added it to the dropdown under ‘clamp ellipse’):

Hope that helps!

  • Rachel

Hi Rachel,

Thanks for the reply. That’s exactly what I’ve done to place the ellipsoid entities, and they are staying in place nicely.

The walls are being repositioned every frame as they are being used as “curtains/trails” behind aircraft that extend to the ground. I tried to use the sampleTerrain functions to get the elevation at the ground at the points that define the wall locations to use for the minimumHeights, but since the walls are moving every frame I think the response time to these calls is too slow and the walls still appear to move when you tilt the globe. So I’m providing a height value for the minimumHeights that is basically the elevation at the airport.

Thanks for you help. Maybe these objects will get clamp to ground capability in the future.

Rob