MainMap.vue 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. <template>
  2. <div class="viewer_container">
  3. <div id="cesiumContainer">
  4. <!-- <div class="get_now_camera_view">
  5. <van-button @click="consoleCameraPosition"> 当前视角 </van-button>
  6. <van-button @click="setViewDefaultlocation"> 复位 </van-button>
  7. </div>
  8. <van-popup
  9. v-model:show="dialogVisible"
  10. :style="{ height: '50%', width: '80%' }"
  11. :closed="hideInfoDailog"
  12. >
  13. <div>
  14. <div style="font-size: 16px">{{ dialogInfoStr }}</div>
  15. <van-button @click="hideInfoDailog">关 闭</van-button>
  16. <van-button :class="'copy_info_dialog'" type="primary">
  17. 复 制
  18. </van-button>
  19. </div>
  20. </van-popup> -->
  21. </div>
  22. <canvas id="canvas-b" class="canvas" width="500" height="180"></canvas>
  23. <Tool></Tool>
  24. </div>
  25. </template>
  26. <script>
  27. // import Clipboard from "clipboard";
  28. import { defineAsyncComponent } from "vue";
  29. import Water from "@/utils/Water";
  30. import api from "@/api/content";
  31. export default {
  32. data() {
  33. return {
  34. JHEntityObj: {},
  35. dialogVisible: false,
  36. dialogInfoStr: "",
  37. clipboard: null,
  38. correctCamera: false,
  39. waterObj: null, // 水面实例
  40. flylineObj: [], // 飞线数组
  41. topK: [
  42. {
  43. lon: 121.12265818599361,
  44. lat: 31.153907327111906,
  45. h: 12.178229477117695,
  46. },
  47. {
  48. lon: 121.12264787421734,
  49. lat: 31.15395149031556,
  50. h: 12.178192986180326,
  51. },
  52. {
  53. lon: 121.12278546708409,
  54. lat: 31.153975342725264,
  55. h: 12.178415363887282,
  56. },
  57. {
  58. lon: 121.12281310059657,
  59. lat: 31.15385762853425,
  60. h: 12.178399877503464,
  61. },
  62. {
  63. lon: 121.1228576094918,
  64. lat: 31.15386519051712,
  65. h: 12.178394232107442,
  66. },
  67. {
  68. lon: 121.1228909000206,
  69. lat: 31.153723309251856,
  70. h: 12.17857353611858,
  71. },
  72. {
  73. lon: 121.12294578609598,
  74. lat: 31.153732796983615,
  75. h: 12.178675754028028,
  76. },
  77. {
  78. lon: 121.12298033312791,
  79. lat: 31.153585333373417,
  80. h: 12.17876227737616,
  81. },
  82. {
  83. lon: 121.1228480316718,
  84. lat: 31.15356239349922,
  85. h: 12.178326652099466,
  86. },
  87. {
  88. lon: 121.12283863696666,
  89. lat: 31.153602052352188,
  90. h: 12.178301731797035,
  91. },
  92. {
  93. lon: 121.12279132401528,
  94. lat: 31.153593731079162,
  95. h: 12.17821160134978,
  96. },
  97. {
  98. lon: 121.12280904366847,
  99. lat: 31.153517944755357,
  100. h: 12.178387628978598,
  101. },
  102. {
  103. lon: 121.12256003807408,
  104. lat: 31.15347475524662,
  105. h: 12.178108003497535,
  106. },
  107. {
  108. lon: 121.12255140331416,
  109. lat: 31.153510889388823,
  110. h: 12.178086221333002,
  111. },
  112. {
  113. lon: 121.12251427275822,
  114. lat: 31.153504509859477,
  115. h: 12.17756730102783,
  116. },
  117. { lon: 121.1224291079002, lat: 31.15386748647, h: 12.177529555001517 },
  118. ],
  119. };
  120. },
  121. components: {
  122. Tool: defineAsyncComponent(() => import("@/components2/Tool.vue")),
  123. },
  124. created() {},
  125. mounted() {
  126. let that = this;
  127. // this.clipboard = new Clipboard(".copy_info_dialog", {
  128. // // 点击copy按钮,直接通过text直接返回复印的内容
  129. // text: function () {
  130. // return that.dialogInfoStr;
  131. // },
  132. // });
  133. this.waterObj = new Water();
  134. window.controlCZ = this.controlCZ;
  135. this.$root.$.appContext.config.globalProperties.$flyTo = this.flyTo;
  136. this.initViewer().then(() => {
  137. this.mapConfig();
  138. // 默认视角
  139. this.setViewDefaultlocation().then(() => {
  140. that.mainFunc();
  141. });
  142. });
  143. window.getNowCameraPosition1 = this.getNowCameraPosition;
  144. window.getNowCameraPosition = function () {
  145. this.getNowCameraPosition().then((result) => {
  146. this.showInfoDailog(result.info);
  147. });
  148. };
  149. // window.addImage = this.addImage;
  150. // window.changeImage = this.changeImage;
  151. // addImage(globalVariable.viewer, {
  152. // arr: [
  153. // 121.12273519090121, 31.153827313511016, 3.280499471365055,
  154. // 121.12273815983032, 31.153814774429165, 3.281036567079009,
  155. // ],
  156. // minH: [2.807028457880749, 2.807028457880749],
  157. // });
  158. // window.tp =
  159. // this.addImage(globalVariable.viewer, {
  160. // arr: [
  161. // 121.12273519090121, 31.153826679130416, 3.280499471365055,
  162. // 121.12273833983032, 31.153813096263634, 3.281036567079009,
  163. // ],
  164. // minH: [2.807028457880749, 2.807028457880749]
  165. // }, '../static/images/ceshi.png');
  166. // changeImage(tp,'../static/images/jinru.png')
  167. // this.addImage(globalVariable.viewer, {
  168. // arr: [
  169. // 121.12273884192843, 31.153811497621240, 3.2435919391164383,
  170. // 121.12274206014264, 31.153797613000965, 3.2321212783392600,
  171. // ],
  172. // minH: [2.8569308025328994, 2.8529680784118310]
  173. // }, '../static/images/ceshi.png');
  174. this.initJH();
  175. return;
  176. },
  177. methods: {
  178. consoleCameraPosition() {
  179. this.getNowCameraPosition().then((result) => {
  180. this.showInfoDailog(
  181. JSON.stringify(result.result).replaceAll("{", "").replaceAll("}", "")
  182. );
  183. });
  184. },
  185. initViewer() {
  186. return new Promise((resolve, reject) => {
  187. globalVariable.viewer = new Cesium.Viewer("cesiumContainer", {
  188. animation: false, // 是否创建动画小器件,左下角仪表
  189. baseLayerPicker: false, // 是否显示图层选择器
  190. fullscreenButton: false, // 是否显示全屏按钮
  191. vrButton: false, // 是否创建VRButton小工具
  192. geocoder: false, // 是否显示geocoder小器件,右上角查询按钮
  193. homeButton: false, // 是否显示Home按钮
  194. infoBox: false, // 是否显示信息框
  195. sceneModePicker: false, // 是否显示3D/2D选择器
  196. selectionIndicator: false, // 是否显示选取指示器组件
  197. timeline: false, // 是否显示时间轴
  198. navigationHelpButton: false, // 是否显示右上角的帮助按钮
  199. navigationInstructionsInitiallyVisible: false, // 如果导航指示最初应可见,则为True;如果用户明确单击按钮后才显示,则为false。
  200. scene3DOnly: true, // 如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
  201. shouldAnimate: false, // 默认情况下,如果时钟应尝试提前模拟时间,则为true,否则为false。此选项优先于设置
  202. clock: new Cesium.Clock(), // 用于控制当前时间的时钟对象
  203. clockViewModel: new Cesium.ClockViewModel(
  204. new Cesium.Clock({
  205. startTime: Cesium.JulianDate.fromIso8601("2023-03-14T22:30:14Z"),
  206. currentTime: Cesium.JulianDate.fromIso8601(
  207. "2023-03-14T22:31:14Z"
  208. ),
  209. stopTime: Cesium.JulianDate.fromIso8601("2023-03-15T10:19:14Z"),
  210. clockRange: Cesium.ClockRange.LOOP_STOP,
  211. clockStep: Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER,
  212. })
  213. ), // 用于控制当前时间的时钟对象
  214. selectedImageryProviderViewModel: undefined, // 当前图像图层的显示模型,仅baseLayerPicker设为true有意义
  215. imageryProviderViewModels:
  216. Cesium.createDefaultImageryProviderViewModels(), // 可供BaseLayerPicker选择的图像图层ProviderViewModel数组
  217. selectedTerrainProviderViewModel: undefined, // 当前地形图层的显示模型,仅baseLayerPicker设为true有意义
  218. terrainProviderViewModels:
  219. Cesium.createDefaultTerrainProviderViewModels(), // 可供BaseLayerPicker选择的地形图层ProviderViewModel数组
  220. imageryProvider: new Cesium.SingleTileImageryProvider({
  221. url: (function createColorCanvas(color) {
  222. // 返回空白
  223. var width = 1,
  224. height = 1;
  225. var canvas = document.createElement("canvas");
  226. canvas.width = width;
  227. canvas.height = height;
  228. var ctx = canvas.getContext("2d");
  229. ctx.fillStyle = color;
  230. ctx.fillRect(0, 0, width, height);
  231. return canvas.toDataURL();
  232. })("#ffffff00"),
  233. rectangle: Cesium.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0),
  234. }), // 图像图层提供者,仅baseLayerPicker设为false有意义
  235. fullscreenElement: document.body, // 全屏时渲染的HTML元素,
  236. useDefaultRenderLoop: true, // 如果需要控制渲染循环,则设为true
  237. targetFrameRate: undefined, // 使用默认render loop时的帧率
  238. showRenderLoopErrors: false, // 如果设为true,将在一个HTML面板中显示错误信息
  239. automaticallyTrackDataSourceClocks: true, // 自动追踪最近添加的数据源的时钟设置
  240. sceneMode: Cesium.SceneMode.SCENE3D, // 初始场景模式
  241. mapProjection: new Cesium.WebMercatorProjection(), // 地图投影体系
  242. dataSources: new Cesium.DataSourceCollection(), // 需要进行可视化的数据源的集合
  243. });
  244. if (systemConfig.msaaSamples != 0) {
  245. globalVariable.viewer.scene.msaaSamples = systemConfig.msaaSamples;
  246. }
  247. //去除版权标记
  248. globalVariable.viewer._cesiumWidget._creditContainer.style.display =
  249. "none";
  250. resolve();
  251. });
  252. },
  253. mainFunc() {
  254. let that = this;
  255. // camera范围限制
  256. this.bindLimitCameraFunc();
  257. // 取消滑动事件
  258. this.controlCZ(systemConfig.mapControl);
  259. // 自定义滑动事件
  260. this.wetherScroll(this.changeCamera);
  261. window.bindLimitCameraFunc = this.bindLimitCameraFunc;
  262. window.unbindLimitCameraFunc = this.unbindLimitCameraFunc;
  263. // entity点击事件
  264. this.entityClickEvent();
  265. // // 键盘/地图点击事件
  266. // this.singleClick(viewer); // 地图点击
  267. this.singleClick2(); // 模型点击
  268. keyboardMapRoamingInit(globalVariable.viewer);
  269. let keyArr = Object.keys(systemConfig.tilesConfig);
  270. this.yanchiAdd3DTiles(0, keyArr);
  271. // for (let i = 0; i < keyArr.length; i++) {
  272. // const str = keyArr[i];
  273. // globalVariable.tilesArr[str] = this.add3DTilesData(
  274. // systemConfig.dataUrl + str + "/tileset.json", //
  275. // {
  276. // light: systemConfig.tilesConfig[str].light,
  277. // }
  278. // );
  279. // }
  280. // window.changeImage = this.changeImage;
  281. // 水面加载
  282. setTimeout(() => {
  283. that.addWaterPanel();
  284. }, 10000);
  285. },
  286. yanchiAdd3DTiles(index, keyArr) {
  287. let that = this;
  288. if (index >= keyArr.length) return;
  289. const str = keyArr[index];
  290. globalVariable.tilesArr[str] = this.add3DTilesData(
  291. systemConfig.tilesConfig[str].dataUrl + str + "/tileset.json" //
  292. // {
  293. // light: systemConfig.tilesConfig[str].light,
  294. // }
  295. );
  296. setTimeout(() => {
  297. that.yanchiAdd3DTiles(++index, keyArr);
  298. }, systemConfig.tilesConfig[str].yanchi);
  299. },
  300. // entity Click
  301. entityClickEvent() {
  302. let viewClickHandle = new Cesium.ScreenSpaceEventHandler(
  303. globalVariable.viewer.scene.canvas
  304. );
  305. viewClickHandle.setInputAction(function (evt) {
  306. var pickedObject = globalVariable.viewer.scene.pick(evt.position);
  307. if (pickedObject && pickedObject.id) {
  308. var clickMarkerId = pickedObject.id._id;
  309. if (globalVariable.point_positions[clickMarkerId]) {
  310. var data = globalVariable.point_positions[clickMarkerId];
  311. if (data.callback) {
  312. data.callback(data.infos);
  313. }
  314. }
  315. } else {
  316. return false;
  317. }
  318. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  319. },
  320. changeCamera(direction) {
  321. switch (direction) {
  322. case "left":
  323. globalVariable.viewer.camera.lookLeft((Math.PI / 180) * 2);
  324. break;
  325. case "right":
  326. globalVariable.viewer.camera.lookRight((Math.PI / 180) * 2);
  327. break;
  328. default:
  329. break;
  330. }
  331. },
  332. wetherScroll(func) {
  333. let startX = 0;
  334. let endX = 0;
  335. let distanceX = 0;
  336. let container = document.getElementById("cesiumContainer");
  337. var clientWidth = document.documentElement.clientWidth;
  338. container.addEventListener("pointerdown", mousedown, false);
  339. container.addEventListener("pointerup", mouseup, false);
  340. function mousedown(event) {
  341. var touch = event;
  342. //滑动起点的坐标
  343. startX = touch.pageX;
  344. container.addEventListener("pointermove", mousemove);
  345. }
  346. function mousemove(event) {
  347. var touch = event;
  348. //手势滑动时,手势坐标不断变化,取最后一点的坐标为最终的终点坐标
  349. endX = touch.pageX;
  350. distanceX = endX - startX;
  351. if (startX != Math.abs(distanceX)) {
  352. //在滑动的距离超过屏幕高度的20%时,做某种操作
  353. if (Math.abs(distanceX) > clientWidth * 0.005) {
  354. //向下滑实行函数someAction1,向上滑实行函数someAction2
  355. //向左滑实行函数someAction1,向右滑实行函数someAction2
  356. distanceX > 0 ? func("left") : func("right");
  357. startX = endX;
  358. }
  359. }
  360. }
  361. function mouseup(event) {
  362. startX = 0;
  363. endX = 0;
  364. distanceX = 0;
  365. container.removeEventListener("pointermove", mousemove);
  366. }
  367. },
  368. // 禁用/开启 操作
  369. controlCZ(bool) {
  370. let screenSpaceCameraController =
  371. globalVariable.viewer.scene.screenSpaceCameraController;
  372. screenSpaceCameraController.enableLook = bool;
  373. screenSpaceCameraController.enableRotate = bool; // 禁止旋转
  374. screenSpaceCameraController.enableTilt = bool; // 禁止倾斜相机
  375. screenSpaceCameraController.enableTranslate = bool; // 禁止移动
  376. screenSpaceCameraController.enableZoom = bool; // 禁止缩放
  377. },
  378. // 默认定位
  379. setViewDefaultlocation() {
  380. return new Promise((resolve, reject) => {
  381. this.$flyTo({
  382. lon: systemConfig.mapDefault.center.lon,
  383. lat: systemConfig.mapDefault.center.lat,
  384. h: systemConfig.mapDefault.height,
  385. heading: systemConfig.mapDefault.heading,
  386. pitch: systemConfig.mapDefault.pitch,
  387. roll: systemConfig.mapDefault.roll,
  388. time: 1,
  389. pitchAdjustHeight: 1000,
  390. callback: null,
  391. }).then(() => {
  392. resolve();
  393. });
  394. });
  395. },
  396. flyTo(item) {
  397. return new Promise((resolve, reject) => {
  398. globalVariable.viewer.camera.flyTo({
  399. destination: Cesium.Cartesian3.fromDegrees(
  400. item.lon,
  401. item.lat,
  402. item.h
  403. ),
  404. orientation: {
  405. heading: Cesium.Math.toRadians(item.heading), // 方向
  406. pitch: Cesium.Math.toRadians(item.pitch), // 倾斜角度
  407. roll: Cesium.Math.toRadians(item.roll),
  408. },
  409. duration: isNaN(item.time) ? 2 : item.time,
  410. pitchAdjustHeight: item.pitchAdjustHeight || 1000,
  411. complete: function () {
  412. if (item) {
  413. if (item.callback) item.callback(item);
  414. }
  415. resolve();
  416. },
  417. });
  418. });
  419. },
  420. // cesium 球体配置
  421. mapConfig() {
  422. // 大气效果(发光)
  423. globalVariable.viewer.scene.globe.showGroundAtmosphere = false;
  424. // 是否将地球渲染为半透明的球体
  425. globalVariable.viewer.scene.globe.translucency.enabled = true;
  426. // 基础球体颜色
  427. globalVariable.viewer.scene.globe.baseColor = Cesium.Color.TRANSPARENT;
  428. // 地底颜色
  429. globalVariable.viewer.scene.globe.undergroundColor = undefined;
  430. // 开启场景光照
  431. globalVariable.viewer.scene.globe.enableLighting = true;
  432. // 控制太阳光
  433. globalVariable.viewer.scene.sun.show = false; // systemConfig.sunShow;
  434. // 控制阴影
  435. globalVariable.viewer.shadows = false; // systemConfig.shadows;
  436. // 阴影强度
  437. globalVariable.viewer.shadowMap.darkness = systemConfig.shadowMapDarkness;
  438. // globalVariable.viewer.terrainShadows = Cesium.ShadowMode.RECEIVE_ONLY;
  439. // // globalVariable.viewer.shadowMap.softShadows = truee
  440. // globalVariable.viewer.shadowMap.darkness = 0.7; //阴影透明度--越大越透明
  441. if (systemConfig.DirectionalLightShow) {
  442. globalVariable.viewer.scene.light = new Cesium.DirectionalLight({
  443. color: new Cesium.Color(
  444. systemConfig.DirectionalLightColor.r,
  445. systemConfig.DirectionalLightColor.g,
  446. systemConfig.DirectionalLightColor.b,
  447. systemConfig.DirectionalLightColor.a
  448. ),
  449. // //去除时间原因影响模型颜色
  450. // direction: Cesium.Cartesian3.fromDegrees(
  451. // 121.1217914833498,
  452. // 31.154385387088624,
  453. // 2000
  454. // ),
  455. direction: new Cesium.Cartesian3(
  456. systemConfig.DirectionalLightDirection.x,
  457. systemConfig.DirectionalLightDirection.y,
  458. systemConfig.DirectionalLightDirection.z
  459. ),
  460. intensity: systemConfig.DirectionalLightIntensity,
  461. });
  462. }
  463. // globalVariable.viewer._cesiumWidget._supportsImageRenderingPixelated =
  464. // Cesium.FeatureDetection.supportsImageRenderingPixelated();
  465. // globalVariable.viewer._cesiumWidget._forceResize = true;
  466. // 解决抗锯齿问题
  467. // // 方法一
  468. // if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
  469. // //判断是否支持图像渲染像素化处理
  470. // var vtxf_dpr = window.devicePixelRatio;
  471. // // 适度降低分辨率
  472. // while (vtxf_dpr >= 2.0) {
  473. // vtxf_dpr /= 2.0;
  474. // }
  475. // //alert(dpr);
  476. // globalVariable.viewer.resolutionScale = vtxf_dpr;
  477. // }
  478. // 方法二
  479. if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
  480. //判断是否支持图像渲染像素化处理
  481. var vtxf_dpr = window.devicePixelRatio;
  482. globalVariable.viewer.resolutionScale = vtxf_dpr;
  483. }
  484. // //是否开启抗锯齿
  485. globalVariable.viewer.scene.fxaa = systemConfig.fxaa;
  486. globalVariable.viewer.scene.postProcessStages.fxaa.enabled =
  487. systemConfig.fxaaEnabled;
  488. // // 天空盒隐藏
  489. // globalVariable.viewer.scene.skyBox.show = false;
  490. // 配置天空盒子
  491. this.deploySkyBox();
  492. },
  493. // 限制camera的移动范围
  494. bindLimitCameraFunc() {
  495. globalVariable.viewer.camera.changed.addEventListener(
  496. this.limitCameraFunc
  497. );
  498. },
  499. unbindLimitCameraFunc() {
  500. globalVariable.viewer.camera.changed.removeEventListener(
  501. this.limitCameraFunc
  502. );
  503. },
  504. limitCameraFunc() {
  505. let that = this;
  506. if (!this.correctCamera) {
  507. this.getNowCameraPosition()
  508. .then((result) => {
  509. let cameraLon = result.result.lon;
  510. let cameraLat = result.result.lat;
  511. let cameraHeight = result.result.h;
  512. if (
  513. cameraLon > systemConfig.mapDefault.bbox.east ||
  514. cameraLon < systemConfig.mapDefault.bbox.west ||
  515. cameraLat > systemConfig.mapDefault.bbox.north ||
  516. cameraLat < systemConfig.mapDefault.bbox.south ||
  517. cameraHeight > systemConfig.mapDefault.defaultH
  518. ) {
  519. that.correctCamera = true;
  520. that.setViewDefaultlocation().then(() => {
  521. huifu();
  522. });
  523. }
  524. cameraLon = null;
  525. cameraLat = null;
  526. cameraHeight = null;
  527. })
  528. .catch((err) => {});
  529. }
  530. function huifu() {
  531. that.correctCamera = false;
  532. }
  533. },
  534. // 配置天空盒
  535. deploySkyBox() {
  536. // 自定义的近地天空盒
  537. let groundSkybox = new Cesium.GroundSkyBox({
  538. sources: {
  539. negativeX: "./static/images/skybox/Left.jpg",
  540. negativeY: "./static/images/skybox/Front.jpg",
  541. negativeZ: "./static/images/skybox/Down.jpg",
  542. positiveX: "./static/images/skybox/Right.jpg",
  543. positiveY: "./static/images/skybox/Back.jpg",
  544. positiveZ: "./static/images/skybox/Up.jpg",
  545. },
  546. });
  547. // // 自带的默认天空盒
  548. // let defaultSkybox = viewer.scene.skyBox;
  549. globalVariable.viewer.scene.skyBox = groundSkybox;
  550. globalVariable.viewer.scene.skyAtmosphere.show = false;
  551. },
  552. // 获取当前camera的详细位置
  553. getNowCameraPosition() {
  554. return new Promise((resolve, reject) => {
  555. var camera = globalVariable.viewer.camera;
  556. var heading = Cesium.Math.toDegrees(
  557. globalVariable.viewer.camera.heading
  558. );
  559. var pitch = Cesium.Math.toDegrees(globalVariable.viewer.camera.pitch); //Cesium.Math.toDegrees作用是把弧度转换成度数
  560. var roll = Cesium.Math.toDegrees(globalVariable.viewer.camera.roll);
  561. var h = globalVariable.viewer.camera.positionCartographic.height;
  562. var camera = globalVariable.viewer.camera.position;
  563. var position = Cesium.Cartographic.fromCartesian(camera);
  564. var lon = Cesium.Math.toDegrees(position.longitude);
  565. var lat = Cesium.Math.toDegrees(position.latitude);
  566. resolve({
  567. str: "",
  568. result: {
  569. lon: lon,
  570. lat: lat,
  571. h: h,
  572. heading: heading,
  573. pitch: pitch,
  574. roll: roll,
  575. },
  576. });
  577. });
  578. // that.showInfoDailog(str);
  579. },
  580. // 地图(地球表面,无地形)左击事件
  581. singleClick() {
  582. var handler = new Cesium.ScreenSpaceEventHandler(
  583. globalVariable.viewer.scene.canvas
  584. );
  585. handler.setInputAction(function (event) {
  586. var earthPosition = globalVariable.viewer.camera.pickEllipsoid(
  587. event.position,
  588. globalVariable.viewer.scene.globe.ellipsoid
  589. );
  590. var cartographic = Cesium.Cartographic.fromCartesian(
  591. earthPosition,
  592. globalVariable.viewer.scene.globe.ellipsoid,
  593. new Cesium.Cartographic()
  594. );
  595. var lat = Cesium.Math.toDegrees(cartographic.latitude);
  596. var lng = Cesium.Math.toDegrees(cartographic.longitude);
  597. var height = cartographic.height;
  598. console.log(lng + "," + lat);
  599. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  600. },
  601. // 地图(模型上)左击事件
  602. singleClick2() {
  603. let that = this;
  604. var handler = new Cesium.ScreenSpaceEventHandler(
  605. globalVariable.viewer.scene.canvas
  606. );
  607. handler.setInputAction(function (event) {
  608. var pick = globalVariable.viewer.scene.pickPosition(event.position);
  609. var pickModel = globalVariable.viewer.scene.pick(event.position);
  610. if (pickModel && pick && !pickModel.id) {
  611. var height = Cesium.Cartographic.fromCartesian(pick).height;
  612. var lat = Cesium.Math.toDegrees(
  613. Cesium.Cartographic.fromCartesian(pick).latitude
  614. );
  615. var lon = Cesium.Math.toDegrees(
  616. Cesium.Cartographic.fromCartesian(pick).longitude
  617. );
  618. // cartesian = Cesium.Cartesian3.fromDegrees(lng, lat, height);
  619. // console.log("模型高度点", cartesian);
  620. let str = `
  621. lon:${lon},
  622. lat:${lat},
  623. height:${height}
  624. `;
  625. console.log(str);
  626. that.showInfoDailog(
  627. JSON.stringify({
  628. lon: lon,
  629. lat: lat,
  630. h: height,
  631. })
  632. .replaceAll("{", "")
  633. .replaceAll("}", "")
  634. );
  635. }
  636. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  637. },
  638. initJH() {
  639. let that = this;
  640. window.getToken = function () {
  641. return that.$store.getters.getToken;
  642. };
  643. this.getToken().then(() => {
  644. serviceWindow.map(function (item, index) {
  645. let pointArr = item.topPoint
  646. .map(function (item_) {
  647. return [item_.lon, item_.lat, item_.height];
  648. })
  649. .join()
  650. .split(",")
  651. .map((num) => Number(num));
  652. that.getWindowInfo(item).then((info) => {
  653. let image = that.createJHImage(item, info);
  654. let entity = globalVariable.viewer.entities.add({
  655. wall: {
  656. positions: Cesium.Cartesian3.fromDegreesArrayHeights(pointArr),
  657. minimumHeights: item.endHeight,
  658. material: new Cesium.ImageMaterialProperty({
  659. image: image,
  660. transparent: true,
  661. }),
  662. },
  663. });
  664. that.JHEntityObj[item.id] = {
  665. item: item,
  666. entity: entity,
  667. };
  668. });
  669. });
  670. });
  671. // 开始循环访问
  672. setInterval(() => {
  673. that.loopJH();
  674. }, 5000); //3 * 60 * 1000
  675. },
  676. getToken() {
  677. let that = this;
  678. return new Promise((resolve, reject) => {
  679. api.getToken().then(function (result) {
  680. that.$store.commit("setToken", result.data);
  681. resolve();
  682. });
  683. });
  684. },
  685. getWindowInfo(params) {
  686. return new Promise((resolve, reject) => {
  687. api.getWindowInfo({ id: params.id }).then(function (result) {
  688. resolve(result.data);
  689. });
  690. });
  691. },
  692. createJHImage(item, info) {
  693. // win_code: "A02",
  694. // win_id: "102",
  695. // area_id: "310000310100310118001",
  696. // win_status: "STOP",
  697. // user_code: "742",
  698. // user_name: "谢晨 ",
  699. // ticket_uuid: "",
  700. // ticket_code: "",
  701. let width = 300,
  702. height = 100;
  703. var canvas = document.createElement("canvas");
  704. canvas.width = 300;
  705. canvas.height = 100;
  706. var ctx = canvas.getContext("2d");
  707. ctx.clearRect(0, 0, width, height);
  708. ctx.fillStyle = "#000000";
  709. ctx.fillRect(0, 0, width, height);
  710. ctx.fillStyle = "#FF0000";
  711. ctx.font = "30px Arial";
  712. // ctx.fillText(item.id, 15, 60);
  713. ctx.fillText(info.win_code, 15, 60);
  714. ctx.fillStyle = "#FF0000";
  715. ctx.beginPath();
  716. ctx.lineWidth = "2";
  717. ctx.strokeStyle = "#FF0000"; // Green path
  718. ctx.moveTo(83, 10);
  719. ctx.lineTo(83, 90);
  720. ctx.stroke(); // Draw it
  721. ctx.fillStyle = "#FF0000";
  722. ctx.font = "30px Arial";
  723. ctx.fillText(item.name, 100, 37);
  724. if (info.win_status == "STOP") {
  725. ctx.fillStyle = "#FF0000";
  726. ctx.font = "30px Arial";
  727. ctx.fillText("暂停服务", 116, 83);
  728. } else {
  729. if (info.ticket_code == "") {
  730. ctx.fillStyle = "#FF0000";
  731. ctx.font = "30px Arial";
  732. ctx.fillText("欢迎光临", 116, 83);
  733. } else {
  734. ctx.fillStyle = "#FF0000";
  735. ctx.font = "30px Arial";
  736. ctx.fillText("请" + info.ticket_code + "号", 116, 83);
  737. }
  738. }
  739. return canvas.toDataURL("image/png");
  740. },
  741. loopJH() {
  742. let that = this;
  743. this.getToken().then(() => {
  744. let arr = Object.getOwnPropertyNames(that.JHEntityObj);
  745. arr.map(function (index) {
  746. let obj = that.JHEntityObj[index];
  747. let item = obj.item;
  748. that.getWindowInfo(obj.item).then((info) => {
  749. let image = that.createJHImage(item, info);
  750. obj.entity.wall.material = new Cesium.ImageMaterialProperty({
  751. image: image,
  752. transparent: true,
  753. });
  754. });
  755. });
  756. });
  757. },
  758. // 地图添加图片
  759. addImage(viewer, pObj, imgUrl) {
  760. // // 顺时针
  761. // let pObj = {
  762. // arr: [
  763. // 121.12273519090121, 31.153826679130416, 3.280499471365055,
  764. // 121.12273833983032, 31.153813096263634, 3.281036567079009,
  765. // ],
  766. // minH: [2.807028457880749, 2.807028457880749],
  767. // };
  768. // let imgUrl = '../static/images/ceshi.png';
  769. // let material = Cesium.Material.fromType("Image");
  770. // material.uniforms.image = imgUrl;
  771. return new Promise((resolve, reject) => {
  772. let instance = new Cesium.GeometryInstance({
  773. geometry: new Cesium.WallGeometry({
  774. positions: Cesium.Cartesian3.fromDegreesArrayHeights(pObj.arr),
  775. minimumHeights: pObj.minH,
  776. }),
  777. });
  778. new Cesium.createDynamicImage({
  779. imageWidth: 500,
  780. imageHeight: 200,
  781. canvasWidth: 500,
  782. canvasHeight: 200,
  783. period: 10,
  784. text: "税务综合受理",
  785. textStyle: "normal bold 40pt 宋体",
  786. }).then((result) => {
  787. // let material = Cesium.Material.fromType("Image");
  788. // material.uniforms.image = result;
  789. // 使用抽象的Primitive而不是RectanglePrimitive
  790. // let wallPrimitive = new Cesium.Primitive({
  791. // geometryInstances: instance,
  792. // appearance: new Cesium.MaterialAppearance({
  793. // material: material,
  794. // faceForward: true,
  795. // }),
  796. // });
  797. // viewer.scene.primitives.add(wallPrimitive);
  798. viewer.entities.add({
  799. wall: {
  800. positions: Cesium.Cartesian3.fromDegreesArrayHeights(pObj.arr),
  801. minimumHeights: pObj.minH,
  802. material: result,
  803. },
  804. });
  805. });
  806. });
  807. // return item;
  808. },
  809. changeImage(primitiveObj, imgUrl) {
  810. let material = Cesium.Material.fromType("Image");
  811. material.uniforms.image = imgUrl;
  812. primitiveObj.appearance = new Cesium.MaterialAppearance({
  813. material: material,
  814. faceForward: true,
  815. });
  816. },
  817. showInfoDailog(str) {
  818. this.dialogVisible = true;
  819. this.dialogInfoStr = str;
  820. },
  821. hideInfoDailog() {
  822. this.dialogVisible = false;
  823. },
  824. // 添加水面
  825. addWaterPanel() {
  826. let d = [];
  827. for (let i = 0; i < systemConfig.water.length; i += 2) {
  828. let x = systemConfig.water[i];
  829. let y = systemConfig.water[i + 1];
  830. d.push(x);
  831. d.push(y);
  832. d.push(1);
  833. }
  834. let geometry = new Cesium.PolygonGeometry({
  835. polygonHierarchy: new Cesium.PolygonHierarchy(
  836. Cesium.Cartesian3.fromRadiansArrayHeights(d)
  837. ),
  838. height: -2,
  839. });
  840. let waterFace = this.waterObj.create(geometry, {
  841. // normalMap: "img/textures/waterNormals.jpg", // 水正常扰动的法线图
  842. frequency: 8000.0, // 控制波数的数字。
  843. animationSpeed: 0.02, // 控制水的动画速度的数字。
  844. amplitude: 5.0, // 控制水波振幅的数字。
  845. specularIntensity: 0.8, // 控制镜面反射强度的数字。
  846. baseWaterColor: "#006ab4", // rgba颜色对象基础颜色的水。#00ffff,#00baff,#006ab4
  847. blendColor: "#006ab4", // 从水中混合到非水域时使用的rgba颜色对象。
  848. // height: 100, //水面高度
  849. clampToGround: true, //是否贴地
  850. opacity: 0.7, //透明度
  851. });
  852. globalVariable.viewer.scene.primitives.add(waterFace);
  853. },
  854. // 加载3DTiles数据
  855. add3DTilesData(url, options) {
  856. if (!options) {
  857. options = {
  858. show: true,
  859. // light: 1,
  860. matrix: null,
  861. };
  862. } else {
  863. options.show = typeof options.show == "boolean" ? options.show : true;
  864. // options.light = isNaN(options.light) ? 1 : options.light;
  865. }
  866. let that = this;
  867. let tileset = new Cesium.Cesium3DTileset({
  868. url: url,
  869. show: options.show,
  870. });
  871. globalVariable.viewer.scene.primitives.add(tileset);
  872. tileset.readyPromise.then(function () {
  873. if (options.matrix)
  874. tileset.root.transform = that.createMatrix4(options.matrix);
  875. tileset.style = {
  876. color: {
  877. conditions: [["true", "rgba(0, 0, 0, 0.3)"]],
  878. },
  879. };
  880. });
  881. return tileset;
  882. },
  883. // 创建偏移矩阵
  884. createMatrix4(matrixParam, defaultModelMatrix) {
  885. let tileModelTool = matrixParam;
  886. var mx = Cesium.Matrix3.fromRotationX(
  887. Cesium.Math.toRadians(tileModelTool.rx)
  888. );
  889. var my = Cesium.Matrix3.fromRotationY(
  890. Cesium.Math.toRadians(tileModelTool.ry)
  891. );
  892. var mz = Cesium.Matrix3.fromRotationZ(
  893. Cesium.Math.toRadians(tileModelTool.rz)
  894. );
  895. var rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
  896. var rotationY = Cesium.Matrix4.fromRotationTranslation(my);
  897. var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
  898. var m;
  899. if (defaultModelMatrix) {
  900. m = defaultModelMatrix;
  901. } else {
  902. //平移 修改经纬度
  903. var position = Cesium.Cartesian3.fromDegrees(
  904. tileModelTool.longitude,
  905. tileModelTool.latitude,
  906. tileModelTool.height
  907. );
  908. m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
  909. }
  910. //旋转、平移矩阵相乘
  911. Cesium.Matrix4.multiply(m, rotationX, m);
  912. Cesium.Matrix4.multiply(m, rotationY, m);
  913. Cesium.Matrix4.multiply(m, rotationZ, m);
  914. //缩放 修改缩放比例
  915. var scale = Cesium.Matrix4.fromUniformScale(tileModelTool.scale);
  916. Cesium.Matrix4.multiply(m, scale, m);
  917. return m;
  918. },
  919. },
  920. };
  921. </script>
  922. <style lang="less" scoped>
  923. .viewer_container {
  924. width: 100%;
  925. height: 100%;
  926. #cesiumContainer {
  927. width: 100%;
  928. height: 100%;
  929. .get_now_camera_view {
  930. position: absolute;
  931. z-index: 1;
  932. }
  933. }
  934. #canvas-b {
  935. position: absolute;
  936. top: 0px;
  937. left: 0px;
  938. display: none;
  939. }
  940. }
  941. </style>