MultiFieldAdaptWindow.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /* 引入Cesium */
  2. // import * as Cesium from 'Cesium';
  3. import {
  4. getGuid,
  5. } from "../common/common.js";
  6. import '../../Assets/styles/PopupWindow/MultiFieldAdaptWindow.css';
  7. /**
  8. * 多字段适配窗口
  9. */
  10. class MultiFieldAdaptWindow {
  11. /**
  12. * 初始化
  13. * @author joy/创睿
  14. * @param {Object} viewer 三维场景viewer对象
  15. * @param {Cesium.Cartesian3} position 坐标位置
  16. * @param {String} title 窗口标题
  17. * @param {Object} properties 属性
  18. * {
  19. * title: title,//标题
  20. * name: name,//名称
  21. * num: num, //编号
  22. * status: true,//在线状态
  23. * }
  24. */
  25. constructor(viewer, position, title, properties, offsetHeight) {
  26. if (!viewer) throw new Cesium.DeveloperError('no viewer object!');
  27. if (!position) throw new Cesium.DeveloperError('no position object!');
  28. this.viewer = viewer; //弹窗创建的viewer
  29. this.position = position; //弹窗挂载的位置
  30. this.offsetHeight = offsetHeight;
  31. //弹窗挂载的位置
  32. if (position instanceof Cesium.Cartesian3) {
  33. this.position = position;
  34. } else {
  35. this.position = Cesium.Cartesian3.fromDegrees(position[0], position[1], position[2] || 0);
  36. }
  37. //如果有div就移除
  38. if (document.getElementsByClassName("MultiField-popup").length > 0) {
  39. document.getElementsByClassName("MultiField-popup")[0].remove();
  40. viewer.entities.remove(viewer.entities.getById("MultiFieldPopupPoint"));
  41. }
  42. this.id = "popup_" + getGuid();
  43. this.popupDiv = document.createElement("div");
  44. this.popupDiv.classList.add("MultiField-popup");
  45. this.popupDiv.id = this.id;
  46. // 将字符串模板生成的内容添加到DOM上
  47. this.viewer.container.append(this.popupDiv);
  48. // this.viewer.cesiumWidget.container.appendChild(this.popupDiv);
  49. //创建Html
  50. this.popupDiv.innerHTML = this._createHtml(title, properties);
  51. //添加场景事件,实时更新窗口的位置
  52. this.viewer.scene.postRender.addEventListener(this.postRender, this);
  53. this.initPoint();
  54. //绑定关闭事件
  55. document.getElementsByClassName("leaflet-popup-close-button")[0].onclick = () => {
  56. this.close();
  57. };
  58. }
  59. /**
  60. * 场景渲染事件 实时更新窗口的位置 使其与笛卡尔坐标一致
  61. * @ignore
  62. */
  63. postRender() {
  64. const canvasHeight = this.viewer.scene.canvas.height;
  65. const windowPosition = new Cesium.Cartesian2();
  66. Cesium.SceneTransforms.wgs84ToWindowCoordinates(
  67. this.viewer.scene,
  68. this.position,
  69. windowPosition
  70. );
  71. let elWidth = this.popupDiv.offsetWidth;
  72. let elHeight = this.popupDiv.offsetHeight;
  73. //elHeight 值需要设置一个合适的,否则很容易导致场景拖动的时候,弹窗存在偏移
  74. if (!!this.offsetHeight) {
  75. elHeight += this.offsetHeight;
  76. }
  77. this.popupDiv.style.left = windowPosition.x - elWidth / 2 + "px";
  78. this.popupDiv.style.top = windowPosition.y - elHeight + "px";
  79. const camerPosition = this.viewer.camera.position;
  80. let height = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(camerPosition).height;
  81. height += this.viewer.scene.globe.ellipsoid.maximumRadius;
  82. if ((!(Cesium.Cartesian3.distance(camerPosition, this.position) > height)) && this.viewer.camera.positionCartographic.height < 50000000) {
  83. this.popupDiv.style.display = "block";
  84. } else {
  85. this.popupDiv.style.display = "none";
  86. }
  87. }
  88. /**
  89. * 生成Html
  90. * @ignore
  91. * @param {Object} header
  92. * @param {Object} content
  93. */
  94. _createHtml(header, content) {
  95. let html = `
  96. <div class="MultiField-popup-header">
  97. ` + header + `
  98. <span class="leaflet-popup-close-button">×</span>
  99. </div>
  100. <div class="MultiField-popup-content">
  101. ` + this._createTable(content) + `
  102. </div>
  103. <div class="MultiField-popup-tip">
  104. </div>
  105. `
  106. return html;
  107. }
  108. /**
  109. * 生成Table
  110. * @ignore
  111. * @param {Object} content
  112. */
  113. _createTable(content) {
  114. let html = '<table class="table-popup">';
  115. for (let key in content) {
  116. html += `<tr><td class="title-popup">${key}</td>
  117. <td class="value-popup">${content[key]}</td></tr>`;
  118. }
  119. html += "</table>";
  120. return html;
  121. }
  122. /**
  123. * 用于调试弹窗是否对得上位置,弹窗对上了该点,不然很容易出现弹窗偏移的问题
  124. * @ignore
  125. */
  126. initPoint() {
  127. this.billboard = new Cesium.Entity({
  128. id: "MultiFieldPopupPoint",
  129. name: "popupPoint",
  130. position: this.position, // 点的经纬度坐标
  131. billboard: {
  132. image: 'jt3dSDK/imgs/point/point.png',
  133. horizontalOrigin: Cesium.HorizontalOrigin.center,
  134. verticalOrigin: Cesium.VerticalOrigin.bottom,
  135. scale: 1,
  136. pixelOffset: new Cesium.Cartesian2(0, 0),
  137. disableDepthTestDistance: Number.POSITIVE_INFINITY,
  138. },
  139. });
  140. this.viewer.entities.add(this.billboard);
  141. }
  142. }
  143. /**
  144. * 通用对外公开函数
  145. */
  146. Object.assign(MultiFieldAdaptWindow.prototype, /** @lends MultiFieldAdaptWindow.prototype */ {
  147. /**
  148. * 关闭按钮
  149. */
  150. close() {
  151. this.popupDiv.remove();
  152. this.viewer.scene.postRender.removeEventListener(this.postRender, this);
  153. this.viewer.entities.remove(this.billboard);
  154. }
  155. });
  156. export default MultiFieldAdaptWindow;