效果

通视分析是指以某一点为观察点,研究某一区域通视情况的地形分析。

示例

通过cesium提供的碰撞检测api获取障碍点实现同时分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import PointDrawer from '../../BaseTool/Draw/DrawPoint';
import LineDrawer from '../../BaseTool/Draw/DrawLine';
import Coordinate from '../../BaseTool/Coordinate';
import Cesium from 'Cesium'
export default class InterAnalysis {
// viewer: any;
// interAnalysis_map: Map<Symbol, any>;
// lineEntities: any = [];
// pointEntities: any[] = [];

constructor(viewer) {
this.viewer = viewer;
this.interAnalysis_map = new Map();
this.pointEntities = [];
this.lineEntities = [];
}

create(sPoint, ePoint, objId) {
debugger
if (ePoint.x === sPoint.x && ePoint.y === sPoint.y && ePoint.z === sPoint.z) {
this.pointEntities.push(PointDrawer.draw(this.viewer, sPoint, 10, Cesium.Color.AQUAMARINE));
console.warn('通视起点与终点重叠');
return;
}

this.pointEntities.push(PointDrawer.draw(this.viewer, sPoint, 10, Cesium.Color.AQUAMARINE));
this.pointEntities.push(PointDrawer.draw(this.viewer, ePoint, 10, Cesium.Color.AQUAMARINE));

let obj = this.drawVisibility(sPoint, ePoint).then((obstaclePoint) => {
//获取视觉障碍点, 绘制线段
if (!obstaclePoint) {
obstaclePoint = ePoint;
debugger
return;
}
this.lineEntities.push(LineDrawer.draw(this.viewer, [sPoint, obstaclePoint], Cesium.Color.GREEN));
this.lineEntities.push(LineDrawer.draw(this.viewer, [obstaclePoint, ePoint], Cesium.Color.RED));
});

this.interAnalysis_map.set(objId, obj);
}

//绘制通视线
drawVisibility(sPoint, ePoint) {
var promise = Cesium.when.defer();
var removePreRenderListener = this.viewer.scene.postUpdate.addEventListener(() => {
//设置相机
var curCamera = this.setCameraPositoion(sPoint, ePoint);

var removePostRenderListener = this.viewer.scene.postRender.addEventListener(() => {
//取点
var obstaclePoint = this.getObstaclePoint(ePoint);
//重置相机
this.resetCamera(curCamera);

removePreRenderListener();

var removeOverlayListener = this.viewer.scene.postRender.addEventListener(function() {
removeOverlayListener();
});
promise.resolve(obstaclePoint);
removePostRenderListener();
});
});

return promise;
}

//设置相机位置
setCameraPositoion(sPoint, ePoint) {
let curCamera = {
positon: this.viewer.camera.position.clone(),
direction: this.viewer.camera.direction.clone(),
up: this.viewer.camera.up.clone()
};
let direction = this.calculateDirection(sPoint, ePoint);
let location = Coordinate.cartesian2lonlat(sPoint);
let position1 = Cesium.Cartesian3.fromDegrees(location.longitude, location.latitude, location.height + 0.1);
this.viewer.camera.setView({
destination: position1,
orientation: {
direction: direction,
up: this.viewer.camera.up.clone()
}
});
return curCamera;
}

//获取障碍点
getObstaclePoint(ePoint) {
let screenLocation = this.viewer.scene.cartesianToCanvasCoordinates(ePoint);

if (!screenLocation) {
console.warn('获取屏幕坐标失败');
return ePoint;
}
let obstaclePoint = this.viewer.scene.pickPosition(screenLocation);
return obstaclePoint;
}

//重置相机
resetCamera(camera) {
this.viewer.camera.setView({
destination: camera.positon,
orientation: {
direction: camera.direction,
up: camera.up
}
});
}

//计算方向
calculateDirection(p1, p2) {
return Cesium.Cartesian3.normalize(
Cesium.Cartesian3.subtract(p2, p1, new Cesium.Cartesian3()),
new Cesium.Cartesian3()
);
}

//清除绘制
clearDraw() {
if (this.pointEntities.length > 0) {
for (let i = 0; i < this.pointEntities.length ; i++) {
this.viewer.entities.removeById(this.pointEntities[i].id);
}
}
if (this.lineEntities.length > 0) {
for (let _i = 0; _i < this.lineEntities.length; _i++) {
this.viewer.entities.removeById(this.lineEntities[_i].id);
}
}
}
}

该示例只是将碰撞点的位置截取出来,渲染成两种颜色,还可以进一步添加分析结果和环视分析。

开源地址:github地址