index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <template>
  2. <div class="sm-function-module-content ZTGlobal">
  3. <el-row
  4. :gutter="5"
  5. style="border-top: 1px dashed #02a7f0; padding: 0.5rem; color: #ffffff"
  6. >
  7. {{ viewshed }}
  8. <el-col style="padding: 0.5rem">
  9. 观察者高度(米):
  10. <el-input-number
  11. size="small"
  12. label="观察者高度:"
  13. min="0"
  14. max="50"
  15. :step="0.5"
  16. precision="1"
  17. v-model="personH"
  18. ></el-input-number>
  19. </el-col>
  20. <el-col :span="8">
  21. <el-button size="mini" type="default" @click="addGCD">
  22. 添加观察点
  23. </el-button>
  24. </el-col>
  25. <el-col :span="8">
  26. <el-button size="mini" type="default" @click="addTagget">
  27. 添加目标点
  28. </el-button>
  29. </el-col>
  30. <el-col :span="7">
  31. <el-button size="mini" type="default" @click="clearViewshed">
  32. 清除
  33. </el-button>
  34. </el-col>
  35. <!-- <el-col :span="7">
  36. <el-button size="mini" type="default" @click="changeView"
  37. >切换视角</el-button
  38. >
  39. </el-col> -->
  40. </el-row>
  41. <!-- </el-row> -->
  42. <!-- 绿线为可见区域,红线为不可见区域 -->
  43. <div class="boxchild">
  44. <el-button type="primary" size="mini" @click="ExportResult">
  45. 导出结果
  46. </el-button>
  47. <!-- <el-button type="primary" size="mini" @click="clear">清除</el-button> -->
  48. </div>
  49. </div>
  50. </template>
  51. <script>
  52. import { init } from "@/utils/MapHelper/sightCorridor.js";
  53. // import RSAnalysis from "@/utils/MapHelper/RSAnalysis.js";
  54. // 观察点,目标点
  55. import { Cartesian2toDegrees } from "@/utils/MapHelper/help.js";
  56. let sightline, handlerPoint, points;
  57. import { download } from "@/utils/MapHelper/help.js";
  58. export default {
  59. // mixins: [RSAnalysis],
  60. data() {
  61. return {
  62. addViewFlag: false,
  63. addTargetFlag: false,
  64. isFrom2To: true,
  65. personH: 1.8,
  66. proform: {
  67. horizontal: 2,
  68. vertical: 1,
  69. distance: 200,
  70. visibleLine: true,
  71. },
  72. viewshed: null,
  73. points: [],
  74. };
  75. },
  76. mounted() {
  77. // if (this.analysisShow && this.skylineComb) {
  78. // }
  79. this.$nextTick(() => {
  80. this.initPoint();
  81. // init();
  82. });
  83. },
  84. methods: {
  85. initViewshed3D(point1, point2) {
  86. this.clearViewshed();
  87. // 创建可视域分析对象
  88. var viewshed3D = new Cesium.ViewShed3D(scene);
  89. viewshed3D.visibleAreaColor =
  90. Cesium.Color.fromCssColorString("rgba(255,0,0,0.5)");
  91. viewshed3D.hiddenAreaColor =
  92. Cesium.Color.fromCssColorString("rgba(0,255,0,0)");
  93. viewshed3D.viewPosition = point1;
  94. viewshed3D.build();
  95. viewshed3D.setDistDirByPoint(point2);
  96. viewshed3D.horizontalFov = 40;
  97. viewshed3D.verticalFov = 20;
  98. this.viewshed = viewshed3D;
  99. },
  100. clearViewshed() {
  101. if (!this.viewshed) return;
  102. this.viewshed.removeAllClipRegion();
  103. this.viewshed.distance = 0.1;
  104. this.clearScope();
  105. },
  106. ExportResult() {
  107. var legends = [];
  108. legends.push({ name: "视廊分析", value: "", unit: "" });
  109. legends.push({ name: "观察者高度", value: this.personH, unit: "米" });
  110. legends.push({ name: "观察者坐标", value: this.points[0], unit: "" });
  111. legends.push({ name: "目标点坐标", value: this.points[1], unit: "" });
  112. var promise = scene.outputSceneToFile();
  113. Cesium.when(promise, (base64data) => {
  114. download(base64data, legends);
  115. });
  116. },
  117. /**
  118. * 添加观察点
  119. */
  120. addGCD() {
  121. let that = this;
  122. this.clearScope();
  123. sightline.removeAllTargetPoint();
  124. that.addViewFlag = true;
  125. that.addTargetFlag = false;
  126. // that.isFrom2To = true;
  127. if (handlerPoint) handlerPoint.clear();
  128. this.setInput();
  129. },
  130. /**
  131. * 添加目标点
  132. */
  133. addTagget() {
  134. let that = this;
  135. that.addViewFlag = false;
  136. that.addTargetFlag = true;
  137. this.setInput();
  138. },
  139. initPoint() {
  140. sightline = new Cesium.Sightline(viewer.scene);
  141. sightline.build();
  142. handlerPoint = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Point);
  143. viewer.scene.undergroundMode = false;
  144. },
  145. /**
  146. * 输入点
  147. */
  148. setInput() {
  149. var that = this;
  150. // that.changCount = 0;
  151. handlerPoint = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Point);
  152. handlerPoint.activate();
  153. handlerPoint.drawEvt.addEventListener(function (result) {
  154. var point = result.object;
  155. // point.show = false;
  156. var position = result.object.position;
  157. //将获取的点的位置转化成经纬度
  158. var cartographic = Cartesian2toDegrees(position);
  159. // if (cartographic[2] < 0) cartographic[2] = 0;
  160. cartographic[2] += that.personH;
  161. //添加观察点
  162. if (that.addViewFlag) {
  163. //设置观察点
  164. sightline.viewPosition = cartographic;
  165. that.addViewFlag = false;
  166. viewer.entities.removeById("gcPoint");
  167. var labelentity = new Cesium.Entity({
  168. id: "gcPoint",
  169. position: Cesium.Cartesian3.fromDegrees(
  170. cartographic[0],
  171. cartographic[1],
  172. cartographic[2]
  173. ),
  174. point: {
  175. // 点的大小(像素)
  176. pixelSize: 10,
  177. // 点位颜色,fromCssColorString 可以直接使用CSS颜色
  178. color: Cesium.Color.RED,
  179. // 边框颜色
  180. outlineColor: Cesium.Color.fromCssColorString("#fff"),
  181. // 边框宽度(像素)
  182. outlineWidth: 2,
  183. // 显示在距相机的距离处的属性,多少区间内是可以显示的
  184. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
  185. 0,
  186. 1500
  187. ),
  188. // 是否显示
  189. show: true,
  190. },
  191. label: {
  192. show: true,
  193. text: "观察点",
  194. font: "15px sans-serif",
  195. pixelOffset: new Cesium.Cartesian2(0, -20), //文字偏移
  196. fillColor: Cesium.Color.RED,
  197. // backgroundColor:new Cesium.Color(0, 0, 0, 1),
  198. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
  199. 0,
  200. 1500
  201. ), //达到一定高度隐藏
  202. disableDepthTestDistance: Number.POSITIVE_INFINITY,
  203. },
  204. });
  205. // that.points.push(entity)
  206. // viewer.entities.add(entity);
  207. that.gcPoint = cartographic;
  208. points.push(labelentity);
  209. viewer.entities.add(labelentity);
  210. } else if (that.addTargetFlag) {
  211. //添加目标点
  212. //设置目标点
  213. sightline.addTargetPoint({
  214. position: cartographic,
  215. name: "目标点",
  216. });
  217. viewer.entities.removeById("targetPoint");
  218. var labelentity = new Cesium.Entity({
  219. id: "targetPoint",
  220. position: Cesium.Cartesian3.fromDegrees(
  221. cartographic[0],
  222. cartographic[1],
  223. cartographic[2]
  224. ),
  225. point: {
  226. // 点的大小(像素)
  227. pixelSize: 10,
  228. // 点位颜色,fromCssColorString 可以直接使用CSS颜色
  229. color: Cesium.Color.RED,
  230. // 边框颜色
  231. outlineColor: Cesium.Color.fromCssColorString("#fff"),
  232. // 边框宽度(像素)
  233. outlineWidth: 2,
  234. // 显示在距相机的距离处的属性,多少区间内是可以显示的
  235. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
  236. 0,
  237. 1500
  238. ),
  239. // 是否显示
  240. show: true,
  241. },
  242. label: {
  243. show: true,
  244. text: "目标点",
  245. font: "15px sans-serif",
  246. pixelOffset: new Cesium.Cartesian2(0, -20), //文字偏移
  247. fillColor: Cesium.Color.RED,
  248. // backgroundColor:new Cesium.Color(0, 0, 0, 1),
  249. distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
  250. 0,
  251. 1500
  252. ), //达到一定高度隐藏
  253. disableDepthTestDistance: Number.POSITIVE_INFINITY,
  254. },
  255. });
  256. points.push(labelentity);
  257. viewer.entities.add(labelentity);
  258. that.addTargetFlag = false;
  259. that.targetPoint = cartographic;
  260. sightline.build();
  261. that.ComputationalPerspective();
  262. }
  263. handlerPoint.deactivate();
  264. handlerPoint.clear();
  265. });
  266. },
  267. /**
  268. * 计算方位角
  269. * @param {} points
  270. */
  271. ComputationalPerspective() {
  272. // this.changCount++;
  273. var point1;
  274. var point2;
  275. if (
  276. sightline.viewPosition[0] == 0 ||
  277. sightline.viewPosition[1] == 0 ||
  278. sightline._currentTargetPoint[0] == 0 ||
  279. sightline._currentTargetPoint[1] == 0
  280. ) {
  281. this.$message.warning("请添加观察点或目标点");
  282. return;
  283. }
  284. if (this.isFrom2To) {
  285. point1 = [
  286. sightline.viewPosition[0],
  287. sightline.viewPosition[1],
  288. sightline.viewPosition[2],
  289. ];
  290. point2 = [
  291. sightline._currentTargetPoint[0],
  292. sightline._currentTargetPoint[1],
  293. sightline._currentTargetPoint[2],
  294. ];
  295. } else {
  296. point1 = [
  297. sightline._currentTargetPoint[0],
  298. sightline._currentTargetPoint[1],
  299. sightline._currentTargetPoint[2],
  300. ];
  301. point2 = [
  302. sightline.viewPosition[0],
  303. sightline.viewPosition[1],
  304. sightline.viewPosition[2],
  305. ];
  306. }
  307. var positionA = Cesium.Cartesian3.fromDegrees(
  308. point1[0],
  309. point1[1],
  310. point1[2]
  311. );
  312. var positionB = Cesium.Cartesian3.fromDegrees(
  313. point2[0],
  314. point2[1],
  315. point2[2]
  316. );
  317. this.points = [point1, point2];
  318. let finalPosition = new Cesium.Cartesian3();
  319. let matrix4 = Cesium.Transforms.eastNorthUpToFixedFrame(positionA);
  320. Cesium.Matrix4.inverse(matrix4, matrix4);
  321. Cesium.Matrix4.multiplyByPoint(matrix4, positionB, finalPosition);
  322. Cesium.Cartesian3.normalize(finalPosition, finalPosition);
  323. // const resultHead = Cesium.Math.toDegrees(
  324. // Math.atan2(finalPosition.x, finalPosition.y)
  325. // );
  326. // const resultPitch = Cesium.Math.toDegrees(Math.asin(finalPosition.z));
  327. // viewer.camera.setView({
  328. // destination: positionA,
  329. // orientation: {
  330. // heading: Cesium.Math.toRadians(resultHead), // east, default value is 0.0 (north)
  331. // pitch: Cesium.Math.toRadians(resultPitch), // default value (looking down)
  332. // roll: 0.0, // default value
  333. // },
  334. // });
  335. this.initViewshed3D(point1, point2);
  336. },
  337. /**
  338. * 停止飞行、漫游、清除图元
  339. */
  340. clearScope() {
  341. viewer.entities.removeAll();
  342. points = [];
  343. sightline.removeAllTargetPoint();
  344. if (handlerPoint) {
  345. handlerPoint.clear();
  346. handlerPoint.deactivate();
  347. }
  348. // this.tooltip.setVisible(false);
  349. // viewer.scene.camera.stopFlyCircle();
  350. // this.changCount = 0;
  351. // viewer.scene.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
  352. },
  353. },
  354. };
  355. </script>
  356. <style>
  357. /* @import "@/views/ConstructionApplication3D/zt.scss"; */
  358. </style>