1. 程式人生 > 其它 >CESIUM例子學習(十三)——Clamp To 3DModel

CESIUM例子學習(十三)——Clamp To 3DModel

前面從例子中學習了繪製要素緊貼地表的操作。但是在專案中,緊貼地表可能是不夠的,比如需要在模型頂上繪製一個label,難道要在模型頂上加上一個寫死的高度的,否則label就會被模型覆蓋。要解決這樣的問題,學習Clamp To 3DModel應該可以幫上忙。

原碼中繪製的是動態變化的點,繪製的原理方法就是利用屬性回撥函式,實時更新pint點的位置。程式碼如下:

function addPoint () {
    point = viewer.entities.add({
        position: new Cesium.CallbackProperty(updatePosition, false),
        point: {
            pixelSize: 10,
            color: Cesium.Color.YELLOW,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
        label: {
            show: false,
            showBackground: true,
            font: "14px monospace",
            horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            pixelOffset: new Cesium.Cartesian2(5, 5),
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
    });
    objectsToExclude = [point]
}
var objectsToExclude
var cartographic = new Cesium.Cartographic();
var point
function updatePosition (time, result) {
    let scene = viewer.scene
    var offset = (time.secondsOfDay % duration) / duration;
    var carto = Cesium.Cartographic.fromDegrees(longitude, latitude, 0);
    cartographic.longitude = carto.longitude - range + offset * range * 2.0;
    cartographic.latitude = carto.latitude;
    var height;
    if (scene.sampleHeightSupported) {
        height = scene.sampleHeight(cartographic, objectsToExclude);
    }
    if (Cesium.defined(height)) {
        cartographic.height = height;
        point.label.text = Math.abs(height).toFixed(2).toString() + " m";
        point.label.show = true;
    } else {
        cartographic.height = 0.0;
        point.label.show = false;
    }
    var reCartesian = Cesium.Cartographic.toCartesian(
        cartographic,
        Cesium.Ellipsoid.WGS84,
        result
    );
    return reCartesian;
}

繪製結果如圖:

程式碼中主要用到的函式是:

 height = scene.sampleHeight(cartographic, objectsToExclude);

對sampleHeight函式,API解釋是:Returns the height of scene geometry at the given cartographic position or undefined if there was no scene geometry to sample height from. The height of the input position is ignored. May be used to clamp objects to the globe, 3D Tiles, or primitives in the scene.返回給定地理點位置處,場景的幾何體的高度。如果沒有獲取到場景的幾何體,則返回undefined

。忽略輸入位置的高度。可用於將物件帖到到場景中的球體、3dtiles或primitives。

按照上面的解釋:sampleHeight函式也應該能獲取到地表的高度。可能是資料非同步載入問題,當需要獲取高度的點不在視野內時,返回的height可能是undefined

程式碼如下:

function addPoint () {
    var position = getPosition()
    point = viewer.entities.add({
        position: position,// new Cesium.CallbackProperty(updatePosition, false),// getPosition(),// 
        point: {
            pixelSize: 10,
            color: Cesium.Color.YELLOW,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
        label: {
            show: true,
            showBackground: true,
            font: "14px monospace",
            text: "test",
            horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            pixelOffset: new Cesium.Cartesian2(5, 5),
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
    });
    objectsToExclude = [point]
}
var objectsToExclude
var cartographic = new Cesium.Cartographic();
var point
function getPosition () {
    let scene = viewer.scene
    var carto = Cesium.Cartographic.fromDegrees(longitude, latitude, 0);
    console.log('carto=', carto)
    cartographic.longitude = carto.longitude;
    cartographic.latitude = carto.latitude;
    var height;
    if (scene.sampleHeightSupported) {
        height = scene.sampleHeight(cartographic);
    }
    console.log('height=', height)
    if (Cesium.defined(height)) {
        cartographic.height = height;
    } else {
        cartographic.height = 77;
    }
    var reCartesian = Cesium.Cartographic.toCartesian(
        cartographic,
        Cesium.Ellipsoid.WGS84,
        new Cesium.Cartesian3()
    );
    console.log('reCartesian=', reCartesian)
    return reCartesian;
}

返回結果如下圖:

在屬性回撥函式中呼叫卻可以返回正常資料的!如下圖:

所以在使用時最好是放在屬性回撥函式中。

至此,就學習完了繪製要素帖地形使用 :heightReference: Cesium.HeightReference.CLAMP_TO_GROUND屬性;

帖3dtiles使用: classificationType: Cesium.ClassificationType.CESIUM_3D_TILE屬性;

帖模型使用:屬性回撥函式呼叫sampleHeight方法。

本文轉自 https://blog.csdn.net/luoyun620/article/details/107609874?spm=1001.2014.3001.5502,如有侵權,請聯絡刪除。