如何在地形表面上“铺展”多边形或线条的Cesium实现方法

16

所以,我正在使用Cesium,并希望添加一个多边形或线条来代表地形表面上的属性边界。

我的多边形在平坦/椭球面上工作得很好,但不幸的是当地形图层显示时,多边形并不能自动覆盖在地形表面上。

很好,实际上我没有z/高度值——所以我正在使用sampleTerrain.js promise方法基于地形插值高度值。这部分工作得很好,我得到了我的高度值。但接下来怎么做呢?

我尝试用我的高度值创建多边形实体,但是毫无效果——它只会忽略高度值。当我阅读文档时,我真的看不出有任何涉及高度值摄入的参考——所有的“位置”数组都是二维的吗?

唯一涉及高度值被考虑的参考是PolygonOutlineGeometry,它有一个看起来很有前途的属性叫做perPositionHeight

这基本上就是我想要的——我不想设置整个多边形的高度,我希望每个点的高度值都被使用。

这是我其中一个失败的尝试:

实体/多边形:

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


底线: 我只需要一个多边形或折线实体,能够很好地贴在地形表面上。

编辑:

使用已接受答案评论中的橙色多边形示例,结合sampleTerrain.js,我已经能够模拟将多边形覆盖在地形上,用一个没有z值的位置列表来演示,这里是一个简单的例子:

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

});

如果你想看到多边形,为什么要使用 alpha(0.0)?根据Cesium规范,0.0代表的是“零强度”。 - Kirill Slatin
我故意隐藏了多边形的表面,因为我更关心边界,而边界是可见的。这与我的问题并不相关。 - danwild
我正在使用相同的代码,但是一些路径段仍然在地下。有人知道原因吗? - sabrina
嗨@sabrina,也许值得放一个jsfiddle来演示问题,或者更好的是放弃这种方法,并像被接受的回答建议的那样使用新的GroundPrimitives。如果需要的话,还可以考虑提出一个新问题(随时通过电子邮件发送问题链接给我,我会在明天查看)。 - danwild
嗨@Daniel。我刚刚明白了我的问题(但还没有找到解决办法)...位置(路径的顶点)完全在地面上;问题是连接两个点的线有时会与地面相交,进入地下。 - sabrina
@Daniel,这是我的新问题:https://dev59.com/fpLea4cB1Zd3GeqPyB6Z - sabrina
2个回答

8

自1.13版本起,Cesium现在支持地面基元。它们会覆盖在地形上。

它看起来像这样:http://cesiumjs.org/images/2015/09-01/groundPrimitives.gif

这是Cesium给出的示例:

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

1
能否将GroundPrimitives用于路径?这是我的代码: var target = viewer.entities.add({ position: sample, path: { resolution: 60, material:Cesium.Color.BLUE, width: 4, trailTime: 360, leadTime: 0 } }); 其中sample是Cesium.SampledPositionProperty,因此路径随时间延伸。 如何将路径覆盖在地形上? - sabrina
你需要使用一个原始类型并将其添加到scene.primitives集合中。看起来你正在创建一个实体。 - Zac
@emackey 有没有使用CZML实现这个的方法? - Slaiyer
@Slaiyer 我目前不这么认为。建议你去 Cesium 论坛上问一下。 - emackey

5
Cesium目前还不支持地形上的矢量数据。正在积极开发中,大多数功能应该会出现在6月1日发布的Cesium 1.10版本中。任何未能在该版本中实现的功能将在7月1日的1.11版本中实现。
对于多边形,您可以跟随GitHub拉取请求:https://github.com/AnalyticalGraphicsInc/cesium/pull/2618 对于广告牌和标签,请查看:https://github.com/AnalyticalGraphicsInc/cesium/pull/2653 折线尚未开始,但一旦以上两个功能完成,就会开始实现。

好的,目前还没有官方支持 - 但是 sampleTerrain.js 的存在告诉我一定有办法解决这个问题,不是吗?如果 Cesium 无法处理三维空间中的点,那么为什么会有人选择使用它而不是 OpenLayers呢?</rant> - danwild
非常抱歉,我误读了你的问题。要使用位置设置中的高度值,请将perPositionHeight属性设置为true。此示例中的橙色多边形可以实现您想要的效果:http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polygon.html&label=Geometries - Matthew Amato
我要补充的是,我们正在添加的是直接将矢量数据覆盖在地形上的能力,就像它躺在地面上一样。设置perPositionHeight不会使多边形与地形相适应,它只会将高度提升到指定的高度,以便您可以在空中拥有多边形。 - Matthew Amato
好的,明白了 - 感谢你的见解,马修。那么,你能确认当与 sampleTerrain.js 插值“地面”高度相结合时,perPositionHeight 可以成为一种有效的方法吗?(有效地将多边形渲染“悬浮在空中”,但与地形高度相同)。 - danwild
抱歉,我错过了你的第一条评论,我会检查一下,谢谢。 - danwild
嘿,马修 - 抱歉。我更改了接受的答案,因为API显然已经改变了。尽管我注意到你在互联网上散布了一些有用的技巧 - 所以再次感谢你的帮助! - danwild

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接