最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cesium how to 'drape' a polygon or line onto terrain surface - Stack Overflow

programmeradmin2浏览0评论

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/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);   

});

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);   

});
Share Improve this question edited Apr 29, 2015 at 22:21 danwild asked Apr 28, 2015 at 6:16 danwilddanwild 2,0463 gold badges27 silver badges34 bronze badges 6
  • why do you have alpha(0.0) if you want to see the polygon? according to Cesium spec 0.0 is zero intensity – Kirill Slatin Commented Apr 28, 2015 at 13:15
  • I've intentionally hidden the surface of the polygon, as I am more interested in the border, which is visible. This is not really relevant to my question. – danwild Commented Apr 28, 2015 at 23:31
  • I'm using the same code, but some of the path segments still are under the ground. Does someone know the reason? – sabrina Commented Dec 16, 2015 at 9:01
  • Hey @sabrina, might be worthwhile putting up a jsfiddle to demonstrate the problem, or better still ditch this approach and use the great new GroundPrimitives as suggested in the accepted answer. Also consider asking a new question if need be (feel free to email me a link to the question and I'll take a look tomorrow). – danwild Commented Dec 16, 2015 at 10:03
  • Hi @Daniel. I've just understood my problem (but still didn't find a solution)... the positions (path's vertex) are perfectly on the ground; the problem is that the line connecting two points sometimes intersects the ground, going under it. – sabrina Commented Dec 16, 2015 at 10:12
 |  Show 1 more comment

2 Answers 2

Reset to default 8

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.

发布评论

评论列表(0)

  1. 暂无评论