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
}));
Cesium does not support vector data on terrain yet. It is being actively worked on and most features should start to appear in Cesium 1.10 which will be out on June 1st. Anything that doesn't make that release should be in 1.11 on July 1st.
For Polygons specifically, you can follow along with the GitHub pull request: https://github.com/AnalyticalGraphicsInc/cesium/pull/2618
For Billboards and Labels, check out: https://github.com/AnalyticalGraphicsInc/cesium/pull/2653
Polylines haven't been started yet but will be as soon as the above two are finished.
来源:https://stackoverflow.com/questions/29911691/cesium-how-to-drape-a-polygon-or-line-onto-terrain-surface