viewer.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import { addScene, addS3mLayers } from "../../js/common/layerManagement.js"
  2. import { actions, storeDate } from '../../js/store/store.js' //局部状态管理
  3. import EventManager from '../../js/common/eventManager/EventManager.js' //事件管理
  4. import { onBeforeUnmount } from 'vue'
  5. import createTooltip from '../../js/tool/tooltip2.js'
  6. import resource from '../../js/local/lang.js' //语言资源
  7. // Cesium 已经在 index.html 中通过 script 标签全局引入,无需再次导入
  8. //初始化地球
  9. function initViewer(props, callback) {
  10. //初始化viewer
  11. if (window.viewer) {
  12. // window.viewer.destroy();
  13. window.viewer = null;
  14. // return;
  15. }
  16. let viewer;
  17. let isPCBroswer = (window.isPCBroswer = Cesium.FeatureDetection.isPCBroswer());
  18. if (isPCBroswer) {
  19. viewer = new Cesium.Viewer("cesiumContainer", {
  20. selectionIndicator: false,
  21. timeline: true,
  22. baseLayerPicker: false,
  23. //shadows: true,
  24. infoBox: false,
  25. // geocoder: true, //查询
  26. // skyBox: false, // 关闭天空盒会一同关闭太阳,场景会变暗
  27. navigation: false,
  28. // contextOptions: {
  29. // requestWebgl2: true
  30. // },
  31. scale: true // 添加比例尺
  32. });
  33. // 太阳光默认打开
  34. // viewer.scene.globe.enableLighting = true;
  35. //隐藏时间线控件
  36. try {
  37. const timelineContainer = document.getElementsByClassName("cesium-viewer-timelineContainer")[0];
  38. if (timelineContainer) {
  39. timelineContainer.style.visibility = "hidden";
  40. }
  41. } catch (error) {
  42. console.error('隐藏时间线控件失败:', error);
  43. }
  44. } else {
  45. // 手机端
  46. viewer = new Cesium.Viewer("cesiumContainer", {
  47. selectionIndicator: false,
  48. infoBox: false,
  49. skyBox: false,
  50. navigation: false,
  51. contextOptions: {
  52. requestWebgl2: true
  53. }
  54. });
  55. let scene = viewer.scene;
  56. if (Cesium.defined(scene.sun)) {
  57. scene.globe.enableLighting = false;
  58. }
  59. if (Cesium.defined(scene.moon)) {
  60. scene.moon.show = false;
  61. }
  62. document.documentElement.style.height = window.innerHeight + "px";
  63. document.addEventListener(
  64. "touchmove",
  65. function (e) {
  66. e.preventDefault();
  67. },
  68. false
  69. );
  70. }
  71. viewer.scene.debugShowFramesPerSecond = true; //帧率
  72. viewer.scene.globe.baseColor = Cesium.Color.BLACK; // 没有影像图层时地球的底色
  73. // viewer.scene.globe.depthTestAgainstTerrain = false; //地形深度
  74. window.viewer = viewer;
  75. window.scene = viewer.scene;
  76. scene.moon.show = false;
  77. viewer.eventManager = new EventManager(viewer); //添加事件管理派发
  78. let widget = viewer.cesiumWidget;
  79. actions.setIsViewer(true); //初始化viewer标志
  80. if (viewer.geocoder) {
  81. // 请开发者自行到supermap online官网(http://www.supermapol.com/)申请key
  82. viewer.geocoder.viewModel.geoKey = "fvV2osxwuZWlY0wJb8FEb2i5";
  83. // document.querySelector(".cesium-geocoder-input").placeholder =
  84. // Resource.searchPlaceHolder; //语言配置,后面维护
  85. }
  86. if (!window.tooltip) {
  87. window.tooltip = createTooltip(viewer._element);
  88. }
  89. // 设置默认视角
  90. viewer.camera.setView({
  91. destination: Cesium.Cartesian3.fromDegrees(119.290381, 26.10377, 50000), // 指定位置,高度50公里
  92. orientation: {
  93. heading: Cesium.Math.toRadians(0), // 方向角
  94. pitch: Cesium.Math.toRadians(0), // 俯仰角
  95. roll: 0 // 翻滚角
  96. }
  97. });
  98. // 添加天地图影像底图和注记
  99. const tiandituKey = '3fb1e9fda20ee995dc815c8243553ce8';
  100. // 添加天地图影像底图(使用HTTPS)
  101. const imageryProvider = new Cesium.WebMapTileServiceImageryProvider({
  102. url: `https://t0.tianditu.gov.cn/img_c/wmts?service=WMTS&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=${tiandituKey}`,
  103. layer: 'img',
  104. style: 'default',
  105. format: 'image/jpeg',
  106. tileMatrixSetID: 'c',
  107. subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
  108. tilingScheme: new Cesium.GeographicTilingScheme(),
  109. tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'],
  110. maximumLevel: 15,
  111. show: true
  112. });
  113. // 添加天地图影像注记(使用HTTPS)
  114. const labelProvider = new Cesium.WebMapTileServiceImageryProvider({
  115. url: `https://t0.tianditu.gov.cn/cia_c/wmts?service=WMTS&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=${tiandituKey}`,
  116. layer: 'cia',
  117. style: 'default',
  118. format: 'image/png',
  119. tileMatrixSetID: 'c',
  120. subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
  121. tilingScheme: new Cesium.GeographicTilingScheme(),
  122. tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'],
  123. maximumLevel: 15,
  124. show: true
  125. });
  126. // 添加图层到viewer
  127. viewer.imageryLayers.addImageryProvider(imageryProvider);
  128. viewer.imageryLayers.addImageryProvider(labelProvider);
  129. function openingAnimation() {
  130. const lon = 118.247854;
  131. const lat = 26.107280;
  132. const height = 300000;
  133. const pitch = Cesium.Math.toRadians(-50);
  134. // 计算相机位置,使得在俯仰角为-50度时,指定位置在视图中心
  135. // 相机应该在指定位置的南方(假设heading为0)
  136. // 水平距离 = 高度 * tan(俯仰角)
  137. const horizontalDistance = height * Math.tan(-pitch);
  138. // 纬度偏移 = 水平距离 / 地球半径 * 180 / π
  139. const latOffset = horizontalDistance / 6371000 * 180 / Math.PI;
  140. const cameraLat = lat - latOffset;
  141. viewer.camera.flyTo({
  142. destination: Cesium.Cartesian3.fromDegrees(lon, cameraLat, height),
  143. orientation: {
  144. heading: 0.0,
  145. pitch: pitch,
  146. roll: 0.0
  147. },
  148. duration: 0 // 立即完成,不使用动画
  149. });
  150. }
  151. // 添加图层
  152. try {
  153. if (props && props.openingAnimation) {
  154. openingAnimation();
  155. }
  156. if (props && props.afterInitviewer) {
  157. props.afterInitviewer();
  158. }
  159. if (props && props.sceneUrl) {
  160. addScene(props.sceneUrl, {}, (layer) => {
  161. });
  162. }
  163. if (props && props.s3mScps) {
  164. addS3mLayers(props.s3mScps);
  165. }
  166. } catch (e) {
  167. if (widget && widget._showRenderLoopErrors) {
  168. let title = resource.showRenderLoopErrors;
  169. widget.showErrorPanel(title, undefined, e);
  170. }
  171. };
  172. // 销毁
  173. onBeforeUnmount(() => {
  174. if (viewer) {
  175. viewer.destroy();
  176. window.viewer = undefined;
  177. window.scene = undefined;
  178. }
  179. });
  180. // 返回viewer实例
  181. return viewer;
  182. };
  183. export default initViewer;