Cesium path onto terrain: line connecting 2 points

2019-08-08 21:53发布

问题:

I have a path moving over time. I use Cesium.sampleTerrain to get positions elevation and drape them on the terrain. The problem is that, even if all points are on the terrain, the line connecting 2 points sometimes goes under the terrain. How can I do to drape also connecting lines on the terrain?

Here is my code:

var promise = Cesium.sampleTerrain(terrainProvider, 14, positions);
Cesium.when(promise, function(updatedPositions) {
    var cartesianPositions = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(updatedPositions);
    var sample = new Cesium.SampledPositionProperty();
    sample.setInterpolationOptions({
        interpolationDegree : 3,
        interpolationAlgorithm : Cesium.HermitePolynomialApproximation
    });

    $(cartesianPositions).each(function(index, cartPosition) {
        var time = Cesium.JulianDate.addSeconds(start, index*10, new Cesium.JulianDate());
        sample.addSample(time, cartPosition);

    })

    var target = viewer.entities.add({
        position: sample,
          path: {
            resolution: 60,
            material:Cesium.Color.BLUE,
            width: 4,
            trailTime: 422*10,
            leadTime: 0
          }
    });

});

回答1:

So like Matthew says; Cesium doesn't currently support a 'polyline' type entity with draping over terrain.

If you find that the Entity API isn't giving you what you need, it might be worth digging into the lower-level Primitives API to gain finer control - more specifically the GroundPrimitive geometry.

Among others; GroundPrimitives currently support the CorridorGeometry.

I have no experience with temporal data plotting within Cesium, but I would suggest you consider this approach rather than the async promise approach, which (IMO) seems like more of a hack born from the absence of a GroundPrimitive-type solution at the time.

Here's a crude example of a GroundPrimitive in action (note we don't need any z values):

var viewer = new Cesium.Viewer('cesiumContainer');

var corridorInstance = new Cesium.GeometryInstance({
   geometry : new Cesium.CorridorGeometry({
      vertexFormat : Cesium.VertexFormat.POSITION_ONLY,
      positions : Cesium.Cartesian3.fromDegreesArray([
         -122.26, 46.15,  
         -122.12, 46.26, 
      ]),
      width : 100
   }),
   id : 'myCorridor',
   attributes : {
      color : new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 0.5)
   }
});

var corridorPrimitive = new Cesium.GroundPrimitive({
   geometryInstance : corridorInstance
});

viewer.scene.primitives.add(corridorPrimitive);
viewer.camera.setView({
   destination: Cesium.Cartesian3.fromDegrees(-122.19, 46.20, 10000.0)
});

Which will give you this:



回答2:

Cesium does not currently support draping lines on terrain, but it is on our road map and really important to us. This is actually an extremely complicated problem to handle correctly in all cases (and is even more complicated because of the limitations of WebGL). It will require a lot of research and experimentation and there's no hard timeline for when it will be finished. We should have a version of it for static lines by spring as part of our 3D Tiles work, but dynamic lines are probably further out.

If you're interested in following development of this feature, keep your eye on issue #2172 in our GitHub repository. We'll also make announcements on our blog/twitter/forum when this feature is part of an official release.