Vue3+cesium agrega una ventana emergente personalizada y la configura para moverse con el mapa

        Requisitos: haga clic en la etiqueta en el mapa 3D para mostrar la ventana emergente. La ventana emergente también debe moverse a medida que se mueve el mapa. Cuando se reduce la escala del mapa, debe ocultarse, y viceversa.

        Las representaciones son las siguientes:

 No hay mucho que decir, directamente en el código:

componente padre:

<template>
  <div id="cesiumContainer" />
  <div id="popup">
    <OverlayChart
      v-if="cesiumGather.popVisible"
      :overlay-chart-obj="cesiumGather.overlayChartObj"
    />
  </div>
</template>

<script setup>
import * as Cesium from "cesium";
import { reactive, onMounted } from "vue";
import OverlayChart from "../../components/overlayChart.vue";

const cesiumGather = reactive({
  popVisible: false,
  overlayChartObj: {},
  cesiumViewer: null,
});

onMounted(() => {
  cesiumGather.cesiumViewer = mapCreate();
  mapCesiumData();
});
// 初始化地图
const mapCreate = () => {
  // 添加图层
  const viewer = new Cesium.Viewer("cesiumContainer", {
    geocoder: false, //搜索框
    homeButton: false, //home键
    animation: false, //动画控件
    fullscreenButton: false, //全屏按钮
    sceneModePicker: false, //场景模式选择器
    timeline: false, //时间轴
    navigationHelpButton: false, //导航提示
    baseLayerPicker: false, //地图选择器
    infoBox: false, //是否显示信息框
    scene3DOnly: false, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
    selectionIndicator: false, //是否显示选取指示器组件
    baselLayerPicker: false, // 将图层选择的控件关掉,才能添加其他影像数据
  });
  viewer._cesiumWidget._creditContainer.style.display = "none";
  return viewer;
};

// 获取聚合数据
const mapCesiumData = () => {
  let queryData = [
    { lng: 104.023442, lat: 23.44321, name: "标点一" },
    { lng: 134.023442, lat: 27.44321, name: "标点二" },
    { lng: 105.023442, lat: 32.44321, name: "标点三" },
    { lng: 104.023442, lat: 23.44221, name: "标点四" },
    { lng: 105.023442, lat: 13.44321, name: "标点五" },
    { lng: 114.023442, lat: 33.44321, name: "标点六" },
    { lng: 124.023442, lat: 43.42321, name: "标点七" },
    { lng: 134.023442, lat: 33.42321, name: "标点八" },
    { lng: 144.023442, lat: 53.14321, name: "标点九" },
    { lng: 101.023442, lat: 23.44321, name: "标点十" },
  ];
  //  加载点位
  renderCesiumPoint(cesiumGather.cesiumViewer, queryData);

  // 添加点击事件
  handlePinClick();
};

// 加载点位
const renderCesiumPoint = (cesiumViewer, projectList) => {
  cesiumViewer.entities.removeAll();
  for (let i = 0; i < projectList.length; i++) {
    const pro = projectList[i];
    cesiumViewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(pro.lng, pro.lat, 1000),
      name: pro.name,
      property: pro, //自己加的相关属性,弹窗里需要用到
      billboard: {
        //图标
        image: "./static/images/markers/4.png",
        scale: 1, //图标比例
        width: 36,
        height: 36,
        // 垂直方向
        verticalOrigin: Cesium.VerticalOrigin.BASELINE,
        //水平方向
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
      },
      label: {
        // 文字标签
        text: pro.name,
        scale: 1,
        font: "16px monospace",
        fillColor: Cesium.Color.WHITE,
        showBackground: true, //设置背景颜色
        pixelOffset: new Cesium.Cartesian2(0, -44), //设置左右、上下移动
        // 垂直方向
        verticalOrigin: Cesium.VerticalOrigin.BASELINE,
        //水平方向
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
      },
    });
  }
};

// 点击地图上的点
const handlePinClick = () => {
  const cesiumViewer = cesiumGather.cesiumViewer;
  const handle3D = new Cesium.ScreenSpaceEventHandler(
    cesiumViewer.scene.canvas
  );
  handle3D.setInputAction((movement) => {
    const pick = cesiumViewer.scene.pick(movement.position);
    console.log(pick);
    if (!pick) {
      cesiumGather.popVisible = false;
      // 清除监听事件
      cesiumViewer.scene.postRender.removeEventListener(infoWindowPostRender);
      return;
    }
    const obj = pick.id.property;
    const coordinate = movement.position;
    // 解决点击不同点数据不更换问题
    if (cesiumGather.overlayChartObj != {}) {
      cesiumGather.popVisible = false;
      cesiumGather.overlayChartObj = {};
    }
    /*overlayChartObj是传给子组件(弹窗)的数据*/
    cesiumGather.overlayChartObj = obj;
    showOverlayChart(coordinate);
    // 添加地图移动监听:使地图移动弹窗跟着移动
    cesiumViewer.scene.postRender.addEventListener(infoWindowPostRender);
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};

//显示图表
const showOverlayChart = (position) => {
  const pop = document.getElementById("popup");
  pop.style.position = "absolute";
  pop.style.top = position.y - 100 + "px";
  pop.style.left = position.x - 120 + "px";
  pop.style.zIndex = 99;
  cesiumGather.popVisible = true;
};
// 地图移动时弹窗跟随
const infoWindowPostRender = () => {
  const cesiumViewer = cesiumGather.cesiumViewer;
  //经纬度转为世界坐标
  const gisPosition = Cesium.Cartesian3.fromDegrees(
    Number(cesiumGather.overlayChartObj.lng),
    Number(cesiumGather.overlayChartObj.lat),
    2500
  );
  //转化为屏幕坐标
  var windowPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
    cesiumViewer.scene,
    gisPosition
  );
  //解决滚动不隐藏问题
  const camerPosition = cesiumViewer.camera.position;
  let height =
    cesiumViewer.scene.globe.ellipsoid.cartesianToCartographic(
      camerPosition
    ).height;
  height += cesiumViewer.scene.globe.ellipsoid.maximumRadius;

  if (
    !(Cesium.Cartesian3.distance(camerPosition, gisPosition) > height) &&
    cesiumViewer.camera.positionCartographic.height < 50000000
  ) {
    cesiumGather.popVisible = true;
  } else {
    cesiumGather.popVisible = false;
  }
  if (Cesium.defined(windowPosition)) {
    setPopPosition(windowPosition);
  }
};
const setPopPosition = (position) => {
  const pop = document.getElementById("popup");
  pop.style.top = position.y - 100 + "px";
  pop.style.left = position.x - 120 + "px";
};
</script>

<style scoped></style>

Subensamblaje:

<template>
  <div class="cesium-popup">
    <span>姓名:{
   
   { overlayChartObj.name }}</span><br/>
    <span>坐标:X:{
   
   { overlayChartObj.lat }},Y:{
   
   { overlayChartObj.lng }}</span>
  </div>
</template>
<script setup>
// props父传子
const props = defineProps({
  overlayChartObj: {
    type: Object,
    default: function () {
      return {};
    },
  },
});
</script>
<style lang="scss" scoped>
.cesium-popup{
  width: 240px;
  height: 50px;
  background-color: #3df;
  span{
    font-size: 14px;
  }
}
</style>

 El autor del estilo de la ventana emergente aquí es aleatorio, puede usarlo usted mismo, si hay algo que no entiende, no dude en ponerse en contacto con el autor.

Artículo de referencia: ventana emergente personalizada de Cesium

Supongo que te gusta

Origin blog.csdn.net/qq_43474235/article/details/129230006
Recomendado
Clasificación