mirror of
				https://github.com/jiawanlong/Cesium-Examples.git
				synced 2025-11-04 01:04:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			292 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			292 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
 | 
						||
class excavateTerrain {
 | 
						||
    constructor(viewer, config) {
 | 
						||
        this.viewer = viewer;
 | 
						||
        this.config = config;
 | 
						||
        this.analysis();
 | 
						||
    }
 | 
						||
 | 
						||
    analysis() {
 | 
						||
 | 
						||
        var viewer = this.viewer;
 | 
						||
        var config = this.config;
 | 
						||
        var ellipsoid = viewer.scene.globe.ellipsoid;
 | 
						||
        var arr = config.positions;
 | 
						||
        var nArr = [];
 | 
						||
        var nArr2 = [];
 | 
						||
 | 
						||
        arr.forEach((element) => {
 | 
						||
            var catographic = Cesium.Cartographic.fromCartesian(element);
 | 
						||
            var height = Number(catographic.height.toFixed(2));
 | 
						||
            var cartographic = ellipsoid.cartesianToCartographic({
 | 
						||
                x: element.x,
 | 
						||
                y: element.y,
 | 
						||
                z: element.z,
 | 
						||
            });
 | 
						||
            var lat = Cesium.Math.toDegrees(cartographic.latitude);
 | 
						||
            var lng = Cesium.Math.toDegrees(cartographic.longitude);
 | 
						||
            nArr.push({
 | 
						||
                x: lng,
 | 
						||
                y: lat,
 | 
						||
                z: height,
 | 
						||
            });
 | 
						||
            nArr2.push({
 | 
						||
                x: lng,
 | 
						||
                y: lat,
 | 
						||
                z: height,
 | 
						||
            });
 | 
						||
        });
 | 
						||
 | 
						||
        var cartographic = ellipsoid.cartesianToCartographic({
 | 
						||
            x: arr[0].x,
 | 
						||
            y: arr[0].y,
 | 
						||
            z: arr[0].z,
 | 
						||
        });
 | 
						||
        var catographic1 = Cesium.Cartographic.fromCartesian(arr[0]);
 | 
						||
        var height1 = Number(catographic1.height.toFixed(2));
 | 
						||
        var lat = Cesium.Math.toDegrees(cartographic.latitude);
 | 
						||
        var lng = Cesium.Math.toDegrees(cartographic.longitude);
 | 
						||
        nArr2.push({
 | 
						||
            x: lng,
 | 
						||
            y: lat,
 | 
						||
            z: height1,
 | 
						||
        });
 | 
						||
        this.excavate(nArr, nArr2)
 | 
						||
        try {
 | 
						||
            drawControl.deleteAll();
 | 
						||
          } catch (error) {
 | 
						||
            
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    excavate(arr, nArr2) {
 | 
						||
        var viewer = this.viewer;
 | 
						||
        var config = this.config;
 | 
						||
        var _this = this;
 | 
						||
        var ellipsoid = viewer.scene.globe.ellipsoid;
 | 
						||
        var nar = [];
 | 
						||
        var hhh = [];
 | 
						||
        var flag = _this.isClockWise(arr);
 | 
						||
        if (flag === true) {
 | 
						||
            arr.reverse();
 | 
						||
            nArr2.reverse();
 | 
						||
        }
 | 
						||
        arr.forEach((element) => {
 | 
						||
            nar.push(element.x);
 | 
						||
            nar.push(element.y);
 | 
						||
            hhh.push(element.z);
 | 
						||
        });
 | 
						||
        var points = [];
 | 
						||
        arr.forEach((element) => {
 | 
						||
            points.push(Cesium.Cartesian3.fromDegrees(element.x, element.y));
 | 
						||
        });
 | 
						||
        var pointsLength = points.length;
 | 
						||
        var clippingPlanes = [];
 | 
						||
 | 
						||
        for (var i = 0; i < pointsLength; ++i) {
 | 
						||
            var nextIndex = (i + 1) % pointsLength;
 | 
						||
            var midpoint = Cesium.Cartesian3.add(
 | 
						||
                points[i],
 | 
						||
                points[nextIndex],
 | 
						||
                new Cesium.Cartesian3()
 | 
						||
            );
 | 
						||
            midpoint = Cesium.Cartesian3.multiplyByScalar(midpoint, 0.5, midpoint);
 | 
						||
 | 
						||
            var up = Cesium.Cartesian3.normalize(midpoint, new Cesium.Cartesian3());
 | 
						||
            var right = Cesium.Cartesian3.subtract(
 | 
						||
                points[nextIndex],
 | 
						||
                midpoint,
 | 
						||
                new Cesium.Cartesian3()
 | 
						||
            );
 | 
						||
            right = Cesium.Cartesian3.normalize(right, right);
 | 
						||
 | 
						||
            var normal = Cesium.Cartesian3.cross(
 | 
						||
                right,
 | 
						||
                up,
 | 
						||
                new Cesium.Cartesian3()
 | 
						||
            );
 | 
						||
            normal = Cesium.Cartesian3.normalize(normal, normal);
 | 
						||
 | 
						||
            var originCenteredPlane = new Cesium.Plane(normal, 0.0);
 | 
						||
            var distance = Cesium.Plane.getPointDistance(
 | 
						||
                originCenteredPlane,
 | 
						||
                midpoint
 | 
						||
            );
 | 
						||
            clippingPlanes.push(new Cesium.ClippingPlane(normal, distance));
 | 
						||
        }
 | 
						||
        viewer.scene.globe.clippingPlanes = new Cesium.ClippingPlaneCollection({
 | 
						||
            planes: clippingPlanes,
 | 
						||
            edgeWidth: 1.0,
 | 
						||
            edgeColor: Cesium.Color.OLIVE,
 | 
						||
        });
 | 
						||
        try {
 | 
						||
            viewer.entities.removeById("entityDM");
 | 
						||
            viewer.entities.removeById("entityDMBJ");
 | 
						||
        } catch (error) { }
 | 
						||
 | 
						||
        var min;
 | 
						||
        for (var i = 0; i < hhh.length; i++) {
 | 
						||
            for (var j = i; j < hhh.length; j++) {
 | 
						||
                if (hhh[i] > hhh[j]) {
 | 
						||
                    min = hhh[j];
 | 
						||
                    hhh[j] = hhh[i];
 | 
						||
                    hhh[i] = min;
 | 
						||
                }
 | 
						||
            }
 | 
						||
        }
 | 
						||
        viewer.entities.add({
 | 
						||
            id: "entityDM",
 | 
						||
            polygon: {
 | 
						||
                hierarchy: Cesium.Cartesian3.fromDegreesArray(nar),
 | 
						||
                material: new Cesium.ImageMaterialProperty({
 | 
						||
                    image: config.bottom,
 | 
						||
                    color: new Cesium.Color.fromCssColorString("#cbc6c2"),
 | 
						||
                    repeat: new Cesium.Cartesian2(30, 30),
 | 
						||
                }),
 | 
						||
                height: hhh[0] - config.height,
 | 
						||
            },
 | 
						||
        });
 | 
						||
 | 
						||
        var maximumHeightsARR = [];
 | 
						||
        var minimumHeights = [];
 | 
						||
        var terrainSamplePositions = [];
 | 
						||
        var length = 2048;
 | 
						||
        var nar22 = [];
 | 
						||
 | 
						||
        nArr2.forEach((element, index) => {
 | 
						||
            if (index < nArr2.length - 1) {
 | 
						||
                var startLon = Cesium.Math.toRadians(element.x);
 | 
						||
                var endLon = Cesium.Math.toRadians(nArr2[index + 1].x);
 | 
						||
                var starty = Cesium.Math.toRadians(element.y);
 | 
						||
                var endy = Cesium.Math.toRadians(nArr2[index + 1].y);
 | 
						||
 | 
						||
                for (var i = 0; i < length; ++i) {
 | 
						||
                    var x = Cesium.Math.lerp(element.x, nArr2[index + 1].x, i / (length - 1));
 | 
						||
                    var y = Cesium.Math.lerp(element.y, nArr2[index + 1].y, i / (length - 1));
 | 
						||
 | 
						||
                    var lon = Cesium.Math.lerp(startLon, endLon, i / (length - 1));
 | 
						||
                    var lat = Cesium.Math.lerp(starty, endy, i / (length - 1));
 | 
						||
                    var position = new Cesium.Cartographic(lon, lat);
 | 
						||
                    terrainSamplePositions.push(position);
 | 
						||
                    nar22.push(x)
 | 
						||
                    nar22.push(y)
 | 
						||
                }
 | 
						||
            } else {
 | 
						||
                var startLon = Cesium.Math.toRadians(element.x);
 | 
						||
                var endLon = Cesium.Math.toRadians(nArr2[0].x);
 | 
						||
                var starty = Cesium.Math.toRadians(element.y);
 | 
						||
                var endy = Cesium.Math.toRadians(nArr2[0].y);
 | 
						||
 | 
						||
                for (var i = 0; i < length; ++i) {
 | 
						||
                    var x = Cesium.Math.lerp(element.x, nArr2[0].x, i / (length - 1));
 | 
						||
                    var y = Cesium.Math.lerp(element.y, nArr2[0].y, i / (length - 1));
 | 
						||
 | 
						||
                    var lon = Cesium.Math.lerp(startLon, endLon, i / (length - 1));
 | 
						||
                    var lat = Cesium.Math.lerp(starty, endy, i / (length - 1));
 | 
						||
                    var position = new Cesium.Cartographic(lon, lat);
 | 
						||
                    terrainSamplePositions.push(position);
 | 
						||
                    nar22.push(x)
 | 
						||
                    nar22.push(y)
 | 
						||
                }
 | 
						||
            }
 | 
						||
        });
 | 
						||
        if ( viewer.terrainProvider._layers ) {
 | 
						||
            // Cesium.when(Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, terrainSamplePositions), function (samples) {
 | 
						||
                // for (let index = 0; index < samples.length; index++) {
 | 
						||
                //     maximumHeightsARR.push(samples[index].height);
 | 
						||
                //     minimumHeights.push(hhh[0] - config.height);
 | 
						||
                // }
 | 
						||
                // viewer.entities.add({
 | 
						||
                //     id: "entityDMBJ",
 | 
						||
                //     wall: {
 | 
						||
                //         positions: Cesium.Cartesian3.fromDegreesArray(nar22),
 | 
						||
                //         maximumHeights: maximumHeightsARR,
 | 
						||
                //         minimumHeights: minimumHeights,
 | 
						||
                //         material: new Cesium.ImageMaterialProperty({
 | 
						||
                //             image: config.side,
 | 
						||
                //             repeat: new Cesium.Cartesian2(30, 30),
 | 
						||
                //         }),
 | 
						||
                //     },
 | 
						||
                // });
 | 
						||
            //     config.drawControl.deleteAll();
 | 
						||
            // })
 | 
						||
            var p1 = Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, terrainSamplePositions)
 | 
						||
            Promise.all([p1]).then((samples) => {
 | 
						||
                console.log(samples[0])
 | 
						||
                samples = samples[0]
 | 
						||
                for (let index = 0; index < samples.length; index++) {
 | 
						||
                    maximumHeightsARR.push(samples[index].height);
 | 
						||
                    minimumHeights.push(hhh[0] - config.height);
 | 
						||
                }
 | 
						||
                viewer.entities.add({
 | 
						||
                    id: "entityDMBJ",
 | 
						||
                    wall: {
 | 
						||
                        positions: Cesium.Cartesian3.fromDegreesArray(nar22),
 | 
						||
                        maximumHeights: maximumHeightsARR,
 | 
						||
                        minimumHeights: minimumHeights,
 | 
						||
                        material: new Cesium.ImageMaterialProperty({
 | 
						||
                            image: config.side,
 | 
						||
                            repeat: new Cesium.Cartesian2(30, 30),
 | 
						||
                        }),
 | 
						||
                    },
 | 
						||
                });
 | 
						||
            })
 | 
						||
 | 
						||
        } else {
 | 
						||
            for (let index = 0; index < terrainSamplePositions.length; index++) {
 | 
						||
                maximumHeightsARR.push( 0 );
 | 
						||
                minimumHeights.push(hhh[0] - config.height);
 | 
						||
            }
 | 
						||
            viewer.entities.add({
 | 
						||
                id: "entityDMBJ",
 | 
						||
                wall: {
 | 
						||
                    positions: Cesium.Cartesian3.fromDegreesArray(nar22),
 | 
						||
                    maximumHeights: maximumHeightsARR,
 | 
						||
                    minimumHeights: minimumHeights,
 | 
						||
                    material: new Cesium.ImageMaterialProperty({
 | 
						||
                        image: config.side,
 | 
						||
                        repeat: new Cesium.Cartesian2(30, 30),
 | 
						||
                    }),
 | 
						||
                },
 | 
						||
            });
 | 
						||
            // config.drawControl.deleteAll();
 | 
						||
        }
 | 
						||
       
 | 
						||
    }
 | 
						||
 | 
						||
    isClockWise(latLngArr) {
 | 
						||
        if (latLngArr.length < 3) {
 | 
						||
            return null
 | 
						||
        }
 | 
						||
        if (latLngArr[0] === latLngArr[latLngArr.length - 1]) {
 | 
						||
            latLngArr = latLngArr.slice(0, latLngArr.length - 1)
 | 
						||
        }
 | 
						||
        let latMin = {
 | 
						||
            i: -1,
 | 
						||
            val: 100000000
 | 
						||
        }
 | 
						||
        for (let i = 0; i < latLngArr.length; i++) {
 | 
						||
            let y = latLngArr[i].y
 | 
						||
            if (y < latMin.val) {
 | 
						||
                latMin.val = y
 | 
						||
                latMin.i = i
 | 
						||
            }
 | 
						||
        }
 | 
						||
        let i1 = (latMin.i + latLngArr.length - 1) % latLngArr.length
 | 
						||
        let i2 = latMin.i
 | 
						||
        let i3 = (latMin.i + 1) % latLngArr.length
 | 
						||
 | 
						||
        let v2_1 = {
 | 
						||
            y: latLngArr[i2].y - latLngArr[i1].y,
 | 
						||
            x: latLngArr[i2].x - latLngArr[i1].x
 | 
						||
        }
 | 
						||
        let v3_2 = {
 | 
						||
            y: latLngArr[i3].y - latLngArr[i2].y,
 | 
						||
            x: latLngArr[i3].x - latLngArr[i2].x
 | 
						||
        }
 | 
						||
        let result = v3_2.x * v2_1.y - v2_1.x * v3_2.y
 | 
						||
        // result>0 3-2在2-1的顺时针方向 result<0 3-2在2-1的逆时针方向 result==0 3-2和2-1共线,可能同向也可能反向
 | 
						||
        return result === 0 ? (latLngArr[i3].x < latLngArr[i1].x) : (result > 0)
 | 
						||
    }
 | 
						||
}
 |