viewer.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. <template>
  2. <div>
  3. <i class="cesiumbtn" :class="store.state.viewer_flag ? 'el-icon-aim' : 'el-icon-rank'" :title="isbig ? '缩小' : '放大'"
  4. @click="bigViewerChange"></i>
  5. <div v-show="store.state.viewer_flag" class="viewer">
  6. <div class="bg">
  7. <div class="bg_left"></div>
  8. <div class="bg_right"></div>
  9. <div class="bg_bottom"></div>
  10. </div>
  11. <datePicker @dateChange="dateChange"></datePicker>
  12. <!-- <ser-center></ser-center> -->
  13. <KJZB ref="gkzb_ref" />
  14. <JCBD />
  15. <TDSC ref="tdsc_ref" />
  16. <TDSY ref="tdgy_ref" />
  17. <GDBH ref="gdbh_ref" />
  18. <STXF ref="stxf_ref" />
  19. <WPJG ref="wpjg_ref" />
  20. <div class="bottom_model">
  21. <div class="bjxm_box">
  22. <BJXM ref="bjxm_ref" />
  23. </div>
  24. <div class="hysy_box">
  25. <ydjc ref="ydjc_ref" />
  26. </div>
  27. </div>
  28. </div>
  29. <Boxcommon v-show="!store.state.viewer_flag"></Boxcommon>
  30. <InfoVector v-show="!store.state.viewer_flag"></InfoVector>
  31. </div>
  32. </template>
  33. <script>
  34. //这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  35. import KJZB from './cockpit/kjgh';
  36. import TDSC from './cockpit/tdsc';
  37. import HYSY from './cockpit/hysy';
  38. import YDHC from './cockpit/ydjc';
  39. import TDSY from './cockpit/tdsy';
  40. import BJXM from './cockpit/bjxm';
  41. import GDBH from './cockpit/gdbh';
  42. import STXF from './cockpit/stxf';
  43. import WPJG from './cockpit/wpjg';
  44. import JCBD from './cockpit/jcbd';
  45. import Boxcommon from '@/views/cockpit/common/VectorSpace/BoxCommonVector.vue';
  46. import InfoVector from '@/views/cockpit/common/VectorSpace/InfoVector.vue';
  47. import datePicker from './cockpit/datePicker.vue';
  48. import xzqh from "../../static/data/460200_full.json";
  49. import hyqy from "../../static/data/460200_hyqy.json";
  50. import * as tdsy from "@/views/cockpit/js/tdsy";
  51. import { cockpitInfo } from '@/api/cockpit'
  52. import * as cockpit from "@/common/js/cockpit.js";
  53. import Ydjc from './cockpit/ydjc.vue';
  54. export default {
  55. name: 'viewer',
  56. components: { KJZB, BJXM, TDSC, HYSY, TDSY, GDBH, STXF, WPJG, datePicker, JCBD, Boxcommon, InfoVector, YDHC, Ydjc },
  57. data() {
  58. return {
  59. params: {
  60. beginTime: '',
  61. endTime: '',
  62. id: 4602,
  63. name: ""
  64. },
  65. flag: true,
  66. xzqh_color_click: "rgba(46, 177, 251, 0.6)",
  67. xzqh_color: "rgba(10, 95, 152, 0.5)",
  68. primitivesL: [],
  69. };
  70. },
  71. //监听属性 类似于data概念
  72. computed: {
  73. isViewer_flag() {
  74. return store.state.viewer_flag;  //需要监听的数据
  75. },
  76. isxzqh_flag() {
  77. return store.state.xzqh_flag;  //需要监听的数据
  78. },
  79. },
  80. //监控data中的数据变化
  81. watch: {
  82. isViewer_flag(newVal, oldVal) {
  83. cockpit.hidden_xzqh(newVal);
  84. cockpit.hidden_wall(newVal);
  85. if (newVal) {
  86. viewer.camera.flyTo({ //定位到范围中心点
  87. destination: {
  88. x: -2040463.7901390342,
  89. y: 5793227.819015942,
  90. z: 1894583.1762108966
  91. },
  92. orientation: {
  93. heading: 0.000005686606919574899,
  94. pitch: -0.41034310444770905,
  95. roll: 0.0
  96. },
  97. })
  98. }
  99. },
  100. isxzqh_flag(newVal, oldVal) {
  101. cockpit.hidden_xzqh(newVal);
  102. cockpit.hidden_wall(newVal);
  103. }
  104. },
  105. //方法集合
  106. methods: {
  107. bigViewerChange() {
  108. store.setViewerFlagb(!store.state.viewer_flag);
  109. store.setToolBarShow(!store.state.viewer_flag);
  110. tdsy.remove();
  111. store.state.vectorData = [];
  112. // store.setToolBarShow(true);
  113. // // 隐藏行政区划
  114. // cockpit.hidden_xzqh(store.state.viewer_flag);
  115. // // 隐藏墙体
  116. // cockpit.hidden_wall(store.state.viewer_flag);
  117. },
  118. switch() {
  119. this.flag = !this.flag;
  120. },
  121. setDatas() {
  122. // 耕地保护
  123. this.$refs.gdbh_ref.init_zbph(this.params);
  124. this.$refs.gdbh_ref.init_info(this.params);
  125. this.$refs.gdbh_ref.init_zbph_hz(this.params);
  126. this.$refs.gdbh_ref.init_jcpg_hz(this.params);
  127. this.$refs.gdbh_ref.init_jcph_table(this.params);
  128. // this.$refs.stxf_ref.setData({ id: this.params.id });
  129. // this.$refs.wpjg_ref.setData(this.params);
  130. // 卫片监管
  131. this.$refs.wpjg_ref.switch_xzqh(this.params);
  132. this.$refs.wpjg_ref.init_wpjg_title(this.params);
  133. // 土地收储
  134. this.$refs.tdsc_ref.init_tdsc_jg(this.params);
  135. this.$refs.tdsc_ref.init_scjd(this.params);
  136. // 土地供应
  137. this.$refs.tdgy_ref.init_tdgy_gy_jd(this.params);
  138. this.$refs.tdgy_ref.init_tdgy_gy_jg(this.params);
  139. this.$refs.tdgy_ref.init_tdgy_jt_jg(this.params);
  140. this.$refs.tdgy_ref.getInfo(this.params);
  141. this.$refs.tdgy_ref.init_tdgy_jt_jd(this.params);
  142. this.$refs.tdgy_ref.init_echart_data(this.params);
  143. this.$refs.tdgy_ref.init_info(this.params);
  144. // 海域使用
  145. // this.$refs.hysy_ref.init_info(this.params);
  146. // this.$refs.hysy_ref.init_echart_data(this.params);
  147. // 报建项目
  148. this.$refs.bjxm_ref.switch_xzqh(this.params);
  149. this.$refs.bjxm_ref.init_info(this.params);
  150. // this.$refs.bjxm_ref.init_bjxm_echart_info(this.params);
  151. // 生态修复
  152. this.$refs.stxf_ref.getInfo(this.params);
  153. this.$refs.stxf_ref.tdzz(this.params);
  154. // 用地监管
  155. this.$refs.ydjc_ref.switch_xzqh(this.params);
  156. },
  157. dateChange(date) {
  158. this.params.beginTime = date[0]
  159. this.params.endTime = date[1]
  160. store.setCockpitDate(date);
  161. this.setDatas()
  162. },
  163. async gkzb_xzqh(address) {
  164. let obj = {
  165. // beginTime: store.state.cockpit_date[0],
  166. // endTime: store.state.cockpit_date[1],
  167. jscType: 'jsc_gkzb_ztgu_stbh',
  168. id: address
  169. };
  170. let data = await cockpitInfo(obj);
  171. let obj_yjjbntmj = {
  172. jscType: 'jsc_gdbh_ztgh_nt',
  173. id: address
  174. };
  175. let obj_yjjbntmj_data = await cockpitInfo(obj_yjjbntmj);
  176. let obj_kfbjmj = {
  177. jscType: 'jsc_gkzb_ztgh_kfbj',
  178. id: address
  179. };
  180. let obj_kfbjmj_data = await cockpitInfo(obj_kfbjmj);
  181. let obj_gdbhmb = {
  182. jscType: 'jsc_gkzb_ztgu_gdbhmb',
  183. id: address
  184. };
  185. let obj_gdbhmb_data = await cockpitInfo(obj_gdbhmb);
  186. store.setCockpitGkzb({
  187. mj: data.data[0].mj,// 生态保护红线面积
  188. ly_mj: data.data[0].ly_mj,// 路域生态保护红线
  189. hy_mj: data.data[0].hy_mj,//近海岸面积
  190. yjjbntmj: obj_yjjbntmj_data.data[0].yjjbntmj,// 永久基本农田保护面积
  191. kfbjmj: obj_kfbjmj_data.data[0].kfbjmj,// 城市开发边界
  192. bfb: (obj_kfbjmj_data.data[0].bfb * 100).toFixed(2),// 覆盖城镇开发边界
  193. tbmj_ys: obj_gdbhmb_data.data[0].tbmj_ys,//耕地保护目标
  194. ghdkmj: obj_kfbjmj_data.data[0].ghdkmj//已入库管控范围
  195. });
  196. },
  197. async gkzb() {
  198. const that = this;
  199. that.$refs.gkzb_ref["initData"]();
  200. },
  201. async pick_xzqh() {
  202. const that = this;
  203. const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  204. handler.setInputAction(async event => {
  205. let pickObj = viewer.scene.pick(event.position);
  206. var position = viewer.scene.pickPosition(event.position);
  207. if (!position)//点击到地球之外
  208. return false;
  209. var cartographic = Cesium.Cartographic.fromCartesian(position);
  210. let longitude = Cesium.Math.toDegrees(cartographic.longitude);
  211. let latitude = Cesium.Math.toDegrees(cartographic.latitude);
  212. let height = cartographic.height;
  213. let heading = viewer.scene.camera.heading;
  214. let pitch = viewer.scene.camera.pitch;
  215. if (!position) {
  216. position = Cesium.Cartesian3.fromDegrees(0, 0, 0);
  217. return;
  218. }
  219. if (store.state.viewer_flag) {
  220. if (Cesium.defined(pickObj)) {
  221. if (pickObj.primitive instanceof Cesium.Primitive) {//点击primitive
  222. //primitive相关操作
  223. let obj = JSON.parse(pickObj.id);
  224. let pri_name = obj.name;
  225. let adcode = obj.adcode
  226. that.params.id = adcode
  227. that.params.name = pri_name
  228. store.setCockpitRegion(obj)
  229. that.setDatas()
  230. // 管控指标
  231. that.gkzb_xzqh(adcode);
  232. cockpit.pick_xzqh(pri_name);
  233. }
  234. } else {
  235. // 暂时点击周围数据显示三亚市
  236. // 清除所有xzqh状态
  237. cockpit.pick_xzqh();
  238. // 管控指标
  239. that.gkzb();
  240. that.params.id = '4602'
  241. that.setDatas()
  242. store.setCockpitRegion({ id: '4602', name: '三亚市' })
  243. }
  244. }
  245. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  246. },
  247. colorFun(color) {
  248. // * `czm_material czm_getMaterial(czm_materialInput materialInput) {...}`: 这是一个名为 `czm_getMaterial` 的函数,它接受一个 `czm_materialInput` 类型的参数并返回一个 `czm_material` 类型的对象。这是 Cesium 中的一个约定,允许你通过编写自定义的 GLSL 代码来定义材质。
  249. // * `czm_material material = czm_getDefaultMaterial(materialInput);`: 获取默认的材质设置。
  250. // * `vec2 st = materialInput.st;`: 从输入中获取纹理坐标(texture coordinates)。
  251. // * `float dis = distance(st, vec2(0.5));`: 计算纹理坐标与中心 `(0.5, 0.5)` 的距离。
  252. // * `material.diffuse = color.rgb;`: 设置材质的漫反射颜色为你提供的 `color` 的 RGB 部分。
  253. // * `material.alpha = clamp(dis * 2.0, 0.1, 0.7);`: 根据与中心的距离设置材质的透明度(alpha)。使用 `clamp` 函数确保透明度值在 0.1 和 0.7 之间。
  254. const fs = `czm_material czm_getMaterial(czm_materialInput materialInput)
  255. {
  256. czm_material material = czm_getDefaultMaterial(materialInput);
  257. vec2 st = materialInput.st;
  258. float dis = distance(st,vec2(0.5));
  259. material.diffuse = color.rgb;
  260. material.alpha = clamp( dis * 2.0, 0.1, 0.3);
  261. return material;
  262. }
  263. `
  264. const material = new Cesium.Material({
  265. fabric: {
  266. uniforms: {
  267. color: color
  268. },
  269. source: fs,
  270. }
  271. })
  272. const aper = new Cesium.MaterialAppearance({
  273. material,
  274. source: fs,
  275. })
  276. return aper;
  277. },
  278. init_xzqh() {
  279. const that = this;
  280. xzqh.features.forEach((res) => {
  281. let obj = {
  282. 'type': "cockpit",
  283. 'name': res.properties.name,
  284. 'centroid': res.properties.centroid,
  285. 'adcode': res.properties.adcode,
  286. }
  287. res.geometry.coordinates.forEach((item) => {
  288. const twoDArray = item[0];
  289. const oneDArray = twoDArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
  290. that.primitivesL.push(JSON.stringify(obj));
  291. // 行政区划
  292. let polygon = new Cesium.GeometryInstance({
  293. id: JSON.stringify(obj),
  294. geometry: new Cesium.PolygonGeometry({
  295. minimum: new Cesium.Cartesian3(0, 0, 0),
  296. maximum: new Cesium.Cartesian3(100000, 100000, 100000),
  297. polygonHierarchy: new Cesium.PolygonHierarchy(
  298. Cesium.Cartesian3.fromDegreesArray(oneDArray)
  299. ),
  300. height: 100,
  301. extrudedHeight: res.properties.extrudedHeight,
  302. })
  303. })
  304. let addPolygonGeometry = new Cesium.Primitive({
  305. geometryInstances: polygon,
  306. appearance: that.colorFun(Cesium.Color.fromCssColorString('#139FF0')),
  307. show: true,
  308. })
  309. // manager.add(addPolygonGeometry)
  310. cockpit.addPrimitive(addPolygonGeometry);
  311. viewer.scene.primitives.add(addPolygonGeometry)
  312. // 墙体流动效果
  313. var positions = Cesium.Cartesian3.fromDegreesArray(oneDArray);
  314. cockpit.add_wall(obj, positions, res);
  315. })
  316. })
  317. },
  318. init_hyqy() {
  319. const that = this;
  320. hyqy.features.forEach((res) => {
  321. let obj = {
  322. 'type': "cockpit",
  323. 'name': res.properties.name,
  324. 'centroid': res.properties.centroid,
  325. 'adcode': res.properties.adcode,
  326. }
  327. const twoDArray = res.geometry.coordinates[0];
  328. const oneDArray = twoDArray.reduce((accumulator, currentValue) => accumulator.concat(currentValue), []);
  329. cockpit.add_hy(obj, res, oneDArray, that.xzqh_color);
  330. })
  331. },
  332. addSceneFun() {
  333. var pitch = viewer.camera.pitch;
  334. //获取当前视角的heading
  335. var heading = viewer.camera.heading;
  336. //获取当前视角的postion(位置)
  337. var position = viewer.camera.position;
  338. var x = position.x;
  339. var y = position.y;
  340. var z = position.z;
  341. var testPitch = pitch;
  342. var testHeading = heading;
  343. // console.log("获取当前视角x,y,z", position.x, position.y, position.z, "pitch", pitch, "heading", heading);
  344. var obj = {
  345. "x": x,
  346. "y": y,
  347. "z": z,
  348. "pitch": pitch,
  349. "heading": heading,
  350. }
  351. console.log(obj, "asd");
  352. },
  353. flatten3DArray(arr) {
  354. let stack = [...arr]; // 初始化栈,并将数组元素压入栈中
  355. let result = []; // 用于存储结果的一维数组
  356. while (stack.length > 0) {
  357. let current = stack.pop(); // 弹出栈顶元素
  358. if (Array.isArray(current)) {
  359. // 如果当前元素是数组,则将其元素压入栈中(逆序)
  360. for (let i = current.length - 1; i >= 0; i--) {
  361. stack.push(current[i]);
  362. }
  363. } else {
  364. // 如果当前元素不是数组,则将其添加到结果数组中
  365. result.push(current);
  366. }
  367. }
  368. // 注意:因为我们是逆序压入栈中的,所以结果数组的顺序与原始三维数组中的顺序相反
  369. // 如果需要保持原始顺序,可以在压入栈时使用unshift代替push,但这样会降低性能
  370. return result;
  371. },
  372. },
  373. beforeCreate() { }, //生命周期 - 创建之前
  374. created() { }, //生命周期 - 创建完成(可以访问当前this实例)
  375. beforeMount() { }, //生命周期 - 挂载之前
  376. async mounted() {
  377. this.$nextTick((res) => {
  378. cockpit.init(viewer);
  379. this.pick_xzqh();
  380. this.init_xzqh();
  381. this.init_hyqy();
  382. // viewer.scene.debugShowFramesPerSecond = true;
  383. });
  384. }, //生命周期 - 挂在完成
  385. beforeUpdate() { }, //生命周期 - 更新之前
  386. updated() { }, //生命周期 - 更新之后
  387. beforeDestroy() { }, //生命周期 - 销毁之前
  388. destroy() { },//生命周期 - 销毁完成
  389. activated() {
  390. cockpit.hidden_xzqh(true);
  391. cockpit.hidden_wall(true);
  392. }, //若组件实例是 <KeepAlive> 缓存树的一部分,当组件被插入到 DOM 中时调用。
  393. deactivated() {
  394. cockpit.hidden_xzqh(false);
  395. cockpit.hidden_wall(false);
  396. } //若组件实例是 <KeepAlive> 缓存树的一部分,当组件从 DOM 中被移除时调用。
  397. };
  398. </script>
  399. <style scoped lang="scss" >
  400. .viewer {
  401. width: 100%;
  402. height: 100%;
  403. }
  404. .bg {
  405. width: 100%;
  406. height: 100%;
  407. .bg_left {
  408. width: 21.6%;
  409. height: calc(100% + 60px);
  410. position: absolute;
  411. top: -60px;
  412. left: 0;
  413. z-index: 100;
  414. background: linear-gradient(to right, rgba(6, 37, 66, 1), rgba(26, 28, 53, 0));
  415. }
  416. .bg_right {
  417. width: 21.6%;
  418. height: calc(100% + 60px);
  419. position: absolute;
  420. top: -60px;
  421. right: 0;
  422. z-index: 100;
  423. background: linear-gradient(to left, rgba(6, 37, 66, 1), rgba(26, 28, 53, 0));
  424. }
  425. .bg_bottom {
  426. width: 100%; // 56.8%;
  427. height: 30%;
  428. position: absolute;
  429. // left: 21.6%;
  430. bottom: 0;
  431. z-index: 100;
  432. background: linear-gradient(to top, rgba(6, 37, 66, 0.5), rgba(26, 28, 53, 0));
  433. }
  434. }
  435. .bottom_model {
  436. // border: 1px solid red;
  437. position: absolute;
  438. left: 28.5vw;
  439. width: 44vw;
  440. height: 29vh;
  441. z-index: 100;
  442. top: 63vh;
  443. .bjxm_box {
  444. // border: 1px solid red;
  445. width: 48%;
  446. height: 100%;
  447. display: inline-block;
  448. }
  449. .hysy_box {
  450. // border: 1px solid red;
  451. width: 48%;
  452. height: 100%;
  453. display: inline-block;
  454. float: right;
  455. }
  456. }
  457. </style>