mirror of
https://github.com/jiawanlong/Cesium-Examples.git
synced 2025-07-04 15:17:36 +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)
|
||
}
|
||
}
|