So, I'm using cesium and I want to add a polygon or line to represent a property boundary on a terrain surface.
My polygon works fine on the flat/Ellipsoid surface, unfortunately however the polygon doesn't automagically drape over the surface when the terrain layer is shown.
Fair enough, I don't actually have the z/height values - so I'm using the sampleTerrain.js promise method to interpolate the height values based on the terrain. This part works fine, I get my height values. But then what?
I've tried creating a polygon entity with my height-laden positions, but to no avail - it just ignores the height values. When I read the docs, I can really see any reference to height values being ingested - all the "positions" array are two dimensional?
The only reference to height values being considered is in the PolygonOutlineGeometry, which has a promising looking property called perPositionHeight
.
This is essentially what I want - I don't want to set the height of the whole poly, I want every points height value to be used..
Here's one of my unsuccessful attempts:
Entity/Polygon:
var entity = viewer.entities.add({
polygon : {
hierarchy : cartesianPositions, //array of positions with z values
outline : true,
outlineColor : Cesium.Color.RED,
outlineWidth : 9,
material : Cesium.Color.BLUE.withAlpha(0.0),
}
});
Bottom line: I just want a polygon or polyline entity that sits nicely on the surface of the terrain.
EDIT:
Using the Orange Polygon example in the comments of the accepted answer combined with sampleTerrain.js, I've been able to simulate 'draping' a polygon onto terrain, with a list of positions that did not have z values, here's a crude example:
var positions = []; // xy position array
var cesiumTerrainProvider = new Cesium.CesiumTerrainProvider({
url : '//assets.agi.com/stk-terrain/world'
});
viewer.terrainProvider = cesiumTerrainProvider;
// go off and sample the terrain layer to get interpolated z values for each position..
var promise = Cesium.sampleTerrain(cesiumTerrainProvider, 11, positions);
Cesium.when(promise, function(updatedPositions) {
var cartesianPositions = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(updatedPositions);
var entity = viewer.entities.add({
polygon : {
hierarchy : cartesianPositions,
outline : true,
outlineColor : Cesium.Color.RED,
outlineWidth : 9,
perPositionHeight: true,
material : Cesium.Color.BLUE.withAlpha(0.0),
}
});
viewer.flyTo(entity);
});
As of version 1.13 cesium now supports GroundPrimitives. They will drape over terrain.
It looks like this: http://cesiumjs.org/images/2015/09-01/groundPrimitives.gif
This the example Cesium gives:
var rectangleInstance = new Cesium.GeometryInstance({
geometry : new Cesium.RectangleGeometry({
rectangle : Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0)
}),
id : 'rectangle',
attributes : {
color : new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5)
}
});
scene.primitives.add(new Cesium.GroundPrimitive({
geometryInstance : rectangleInstance
}));