通视分析
原理
将起点和终点连成一条线,判断这条线与场景之间是否有交点,如果有交点,就返回第一个交点,起点——交点创建,交点——终点创建红色实体线,起点到障碍点为可视区
代码实现
let viewer=null
let tempEntities = []
const sightline = (startWorldPoint, endWorldPoint) => {
let positions = [startWorldPoint, endWorldPoint]
// 计算射线的方向
let direction = Cesium.Cartesian3.normalize(
Cesium.Cartesian3.subtract(
positions[1],
positions[0],
new Cesium.Cartesian3()
),
new Cesium.Cartesian3()
);
// 建立射线
let ray = new Cesium.Ray(positions[0], direction);
// 计算交互点,返回第一个
let result = viewer.scene.pickFromRay(ray);
let barrierPoint = null
if (Cesium.defined(result.position)) {
barrierPoint = result.position
drawPoint(result.position, 3)
}
return barrierPoint;
}
export const ViewLine = (_viewer) => {
viewer=_viewer
clearDrawEntities();
let position = [];
let tempPoints = [];
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (click) {
let ray = viewer.camera.getPickRay(click.position);
position = viewer.scene.globe.pick(ray, viewer.scene);
tempPoints.push(position);
let tempLength = tempPoints.length;
let point = drawPoint(position, tempPoints.length);
tempEntities.push(point);
if (tempLength == 2) {
let pointline = drawPolyline(tempPoints);
tempEntities.push(pointline);
let breakpoint = sightline(tempPoints[0], tempPoints[1])
let startwgs84 = DC.T.transformCartesianToWGS84(tempPoints[0])
let endwgs84 = DC.T.transformCartesianToWGS84(tempPoints[1])
let t = "观察点:" + startwgs84.toString().substr(0, startwgs84.toString().length - 6) + "\n目标点:" + endwgs84.toString().substr(0, endwgs84.toString().length - 6) + "\n"
let breakwgs84 = null
if (breakpoint) {
breakwgs84 = DC.T.transformCartesianToWGS84(breakpoint)
t += "障碍点:" + breakwgs84.toString().substr(0, breakwgs84.toString().length - 6) + "\n是否通视:否"
} else {
t += "是否通视:是"
}
drawLabel(breakpoint ? breakpoint : tempPoints[1], t)
handler.destroy();//关闭事件句柄
handler = null;
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
const drawPoint = (position, type) => {
let text = "观察点"
switch (type) {
case 1:
text = "观察点"
break;
case 2:
text = "目标点"
break;
case 3:
text = "障碍点"
break;
default:
break;
}
return viewer.entities.add({
name: "点几何对象",
position: position,
point: {
color: Cesium.Color.RED,
pixelSize: 5,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 1,
// heightReference: Cesium.HeightReference.NONE
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
label: {
text: text,
fillColor: Cesium.Color.YELLOW,
font: 'normal 16px MicroSoft YaHei',
pixelOffset: {
x: 20,
y: 0
},
scale: 1
}
});
}
const drawLabel = (position, text) => {
return viewer.entities.add({
name: "点几何对象",
position: position,
label: {
text: text,
color: Cesium.Color.fromCssColorString('#fff'),
font: 'normal 16px MicroSoft YaHei',
showBackground: true,
scale: 1,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: 10000.
}
});
}
const drawPolyline = (positions) => {
if (positions.length < 1) return;
return viewer.entities.add({
name: "线几何对象",
polyline: {
positions: positions,
width: 2.0,
material: Cesium.Color.RED,
// depthFailMaterial:Cesium.Color.BLUE,
// clampToGround: true,
}
});
}
const clearDrawEntities = () => {
tempEntities = [];
// 清除之前的实体
const entitys = viewer.entities._entities._array;
let length = entitys.length
// 倒叙遍历防止实体减少之后entitys[f]不存在
for (let f = length - 1; f >= 0; f--) {
if (entitys[f]._name && (entitys[f]._name === '点几何对象' || entitys[f]._name === '线几何对象' || entitys[f]._name === '面几何对象')) {
viewer.entities.remove(entitys[f]);
}
}
}
export const clearAll = () => {
clearDrawEntities();
}