viewer.vue 19 KB

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