当前位置:   article > 正文

Vue3+cesium添加自定义弹窗并设置随地图移动位置移动_cesium overlay

cesium overlay

        需求:点击三维地图上的标注展示弹窗,随着地图移动弹窗也需要移动,缩小地图比例要隐藏,反之显示。

        效果图如下:

 话不多说,直接上代码:

父组件:

  1. <template>
  2. <div id="cesiumContainer" />
  3. <div id="popup">
  4. <OverlayChart
  5. v-if="cesiumGather.popVisible"
  6. :overlay-chart-obj="cesiumGather.overlayChartObj"
  7. />
  8. </div>
  9. </template>
  10. <script setup>
  11. import * as Cesium from "cesium";
  12. import { reactive, onMounted } from "vue";
  13. import OverlayChart from "../../components/overlayChart.vue";
  14. const cesiumGather = reactive({
  15. popVisible: false,
  16. overlayChartObj: {},
  17. cesiumViewer: null,
  18. });
  19. onMounted(() => {
  20. cesiumGather.cesiumViewer = mapCreate();
  21. mapCesiumData();
  22. });
  23. // 初始化地图
  24. const mapCreate = () => {
  25. // 添加图层
  26. const viewer = new Cesium.Viewer("cesiumContainer", {
  27. geocoder: false, //搜索框
  28. homeButton: false, //home键
  29. animation: false, //动画控件
  30. fullscreenButton: false, //全屏按钮
  31. sceneModePicker: false, //场景模式选择器
  32. timeline: false, //时间轴
  33. navigationHelpButton: false, //导航提示
  34. baseLayerPicker: false, //地图选择器
  35. infoBox: false, //是否显示信息框
  36. scene3DOnly: false, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
  37. selectionIndicator: false, //是否显示选取指示器组件
  38. baselLayerPicker: false, // 将图层选择的控件关掉,才能添加其他影像数据
  39. });
  40. viewer._cesiumWidget._creditContainer.style.display = "none";
  41. return viewer;
  42. };
  43. // 获取聚合数据
  44. const mapCesiumData = () => {
  45. let queryData = [
  46. { lng: 104.023442, lat: 23.44321, name: "标点一" },
  47. { lng: 134.023442, lat: 27.44321, name: "标点二" },
  48. { lng: 105.023442, lat: 32.44321, name: "标点三" },
  49. { lng: 104.023442, lat: 23.44221, name: "标点四" },
  50. { lng: 105.023442, lat: 13.44321, name: "标点五" },
  51. { lng: 114.023442, lat: 33.44321, name: "标点六" },
  52. { lng: 124.023442, lat: 43.42321, name: "标点七" },
  53. { lng: 134.023442, lat: 33.42321, name: "标点八" },
  54. { lng: 144.023442, lat: 53.14321, name: "标点九" },
  55. { lng: 101.023442, lat: 23.44321, name: "标点十" },
  56. ];
  57. // 加载点位
  58. renderCesiumPoint(cesiumGather.cesiumViewer, queryData);
  59. // 添加点击事件
  60. handlePinClick();
  61. };
  62. // 加载点位
  63. const renderCesiumPoint = (cesiumViewer, projectList) => {
  64. cesiumViewer.entities.removeAll();
  65. for (let i = 0; i < projectList.length; i++) {
  66. const pro = projectList[i];
  67. cesiumViewer.entities.add({
  68. position: Cesium.Cartesian3.fromDegrees(pro.lng, pro.lat, 1000),
  69. name: pro.name,
  70. property: pro, //自己加的相关属性,弹窗里需要用到
  71. billboard: {
  72. //图标
  73. image: "./static/images/markers/4.png",
  74. scale: 1, //图标比例
  75. width: 36,
  76. height: 36,
  77. // 垂直方向
  78. verticalOrigin: Cesium.VerticalOrigin.BASELINE,
  79. //水平方向
  80. heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  81. },
  82. label: {
  83. // 文字标签
  84. text: pro.name,
  85. scale: 1,
  86. font: "16px monospace",
  87. fillColor: Cesium.Color.WHITE,
  88. showBackground: true, //设置背景颜色
  89. pixelOffset: new Cesium.Cartesian2(0, -44), //设置左右、上下移动
  90. // 垂直方向
  91. verticalOrigin: Cesium.VerticalOrigin.BASELINE,
  92. //水平方向
  93. heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  94. },
  95. });
  96. }
  97. };
  98. // 点击地图上的点
  99. const handlePinClick = () => {
  100. const cesiumViewer = cesiumGather.cesiumViewer;
  101. const handle3D = new Cesium.ScreenSpaceEventHandler(
  102. cesiumViewer.scene.canvas
  103. );
  104. handle3D.setInputAction((movement) => {
  105. const pick = cesiumViewer.scene.pick(movement.position);
  106. console.log(pick);
  107. if (!pick) {
  108. cesiumGather.popVisible = false;
  109. // 清除监听事件
  110. cesiumViewer.scene.postRender.removeEventListener(infoWindowPostRender);
  111. return;
  112. }
  113. const obj = pick.id.property;
  114. const coordinate = movement.position;
  115. // 解决点击不同点数据不更换问题
  116. if (cesiumGather.overlayChartObj != {}) {
  117. cesiumGather.popVisible = false;
  118. cesiumGather.overlayChartObj = {};
  119. }
  120. /*overlayChartObj是传给子组件(弹窗)的数据*/
  121. cesiumGather.overlayChartObj = obj;
  122. showOverlayChart(coordinate);
  123. // 添加地图移动监听:使地图移动弹窗跟着移动
  124. cesiumViewer.scene.postRender.addEventListener(infoWindowPostRender);
  125. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  126. };
  127. //显示图表
  128. const showOverlayChart = (position) => {
  129. const pop = document.getElementById("popup");
  130. pop.style.position = "absolute";
  131. pop.style.top = position.y - 100 + "px";
  132. pop.style.left = position.x - 120 + "px";
  133. pop.style.zIndex = 99;
  134. cesiumGather.popVisible = true;
  135. };
  136. // 地图移动时弹窗跟随
  137. const infoWindowPostRender = () => {
  138. const cesiumViewer = cesiumGather.cesiumViewer;
  139. //经纬度转为世界坐标
  140. const gisPosition = Cesium.Cartesian3.fromDegrees(
  141. Number(cesiumGather.overlayChartObj.lng),
  142. Number(cesiumGather.overlayChartObj.lat),
  143. 2500
  144. );
  145. //转化为屏幕坐标
  146. var windowPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
  147. cesiumViewer.scene,
  148. gisPosition
  149. );
  150. //解决滚动不隐藏问题
  151. const camerPosition = cesiumViewer.camera.position;
  152. let height =
  153. cesiumViewer.scene.globe.ellipsoid.cartesianToCartographic(
  154. camerPosition
  155. ).height;
  156. height += cesiumViewer.scene.globe.ellipsoid.maximumRadius;
  157. if (
  158. !(Cesium.Cartesian3.distance(camerPosition, gisPosition) > height) &&
  159. cesiumViewer.camera.positionCartographic.height < 50000000
  160. ) {
  161. cesiumGather.popVisible = true;
  162. } else {
  163. cesiumGather.popVisible = false;
  164. }
  165. if (Cesium.defined(windowPosition)) {
  166. setPopPosition(windowPosition);
  167. }
  168. };
  169. const setPopPosition = (position) => {
  170. const pop = document.getElementById("popup");
  171. pop.style.top = position.y - 100 + "px";
  172. pop.style.left = position.x - 120 + "px";
  173. };
  174. </script>
  175. <style scoped></style>

子组件:

  1. <template>
  2. <div class="cesium-popup">
  3. <span>姓名:{{ overlayChartObj.name }}</span><br/>
  4. <span>坐标:X:{{ overlayChartObj.lat }},Y:{{ overlayChartObj.lng }}</span>
  5. </div>
  6. </template>
  7. <script setup>
  8. // props父传子
  9. const props = defineProps({
  10. overlayChartObj: {
  11. type: Object,
  12. default: function () {
  13. return {};
  14. },
  15. },
  16. });
  17. </script>
  18. <style lang="scss" scoped>
  19. .cesium-popup{
  20. width: 240px;
  21. height: 50px;
  22. background-color: #3df;
  23. span{
  24. font-size: 14px;
  25. }
  26. }
  27. </style>

 这里的弹窗样式笔者随便弄了一下,你们可以自行发挥,有哪块不懂的随时联系笔者。

借鉴文章:cesium自定义弹窗

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/109668
推荐阅读
相关标签
  

闽ICP备14008679号