Cesium-点击实体显示弹窗

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>20250227</title>
    <!-- 引入 Cesium 的 CSS 文件 -->
    <link
      href="https://cesium.com/downloads/cesiumjs/releases/1.87/Build/Cesium/Widgets/widgets.css"
      rel="stylesheet"
    />
    <style>
      html,
      body,
      #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }
      /* 定义弹窗样式 */
      #popup {
        position: absolute;
        background-color: white;
        padding: 10px;
        border: 1px solid #ccc;
        border-radius: 5px;
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
        display: none;
      }
    </style>
  </head>

  <body>
    <!-- 创建一个 div 作为 Cesium 视图的容器 -->
    <div id="cesiumContainer"></div>
    <!-- 创建弹窗元素 -->
    <div id="popup"></div>
    <!-- 引入 Cesium 的 JavaScript 文件 -->
    <script src="https://cesium.com/downloads/cesiumjs/releases/1.87/Build/Cesium/Cesium.js"></script>
    <script>
      // 初始化 Cesium 视图
      Cesium.Ion.defaultAccessToken =
        'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1ZDVlMTQ5ZC1kZTYxLTQzM2MtODU3ZS1kMjA4YzZiOTBjZGEiLCJpZCI6Mjc5NTY3LCJpYXQiOjE3NDA2NDMyODJ9.ScSAm-1y-8DT0uq4DXGt8NQrEPVo3b_f-P_5bghF7rU'
      const viewer = new Cesium.Viewer('cesiumContainer', {
        terrainProvider: Cesium.createWorldTerrain(),
        geocoder: false, //是否显示位置查找工具
        homeButton: false, //是否显示首页位置工具
        sceneModePicker: false, //是否显示视角模式切换工具
        baseLayerPicker: false, //是否显示默认图层选择工具
        navigationHelpButton: false, //是否显示导航帮助工具
        animation: false, //是否显示动画工具
        timeline: false, //是否显示时间轴工具
        fullscreenButton: false, //是否显示全屏按钮工具
        infoBox: false,
        creditContainer: document.createElement('div'), //移除左下角的版权信息
      })
      // 定义图标路径映射
      const iconPath = {
        崩塌: './灾害点图标/崩塌.gif',
        不稳定斜坡: './灾害点图标/不稳定斜坡.gif',
        地裂缝: './灾害点图标/地裂缝.gif',
        滑坡: './灾害点图标/滑坡.gif',
        泥石流: './灾害点图标/泥石流.gif',
        危岩: './灾害点图标/危岩.gif',
        岩溶地面塌陷: './灾害点图标/岩溶地面塌陷.gif',
      }
      // 获取弹窗元素
      const popup = document.getElementById('popup')
      // 发起一个 HTTP 请求来获取本地的 json 文件
      fetch('./potential_points.json')
        // 当请求成功后,将响应数据转换为 JSON 格式
        .then((response) => response.json())
        // 处理解析后的 JSON 数据
        .then((data) => {
          // 从 JSON 数据中提取记录数组
          records = data.RECORDS
          // 遍历记录数组中的每一条记录
          records.forEach((record) => {
            // 将记录中的经度字符串转换为浮点数
            const lon = parseFloat(record.lon)
            // 将记录中的纬度字符串转换为浮点数
            const lat = parseFloat(record.lat)
            // 根据经纬度创建一个笛卡尔坐标位置
            const position = Cesium.Cartesian3.fromDegrees(lon, lat)
            // 根据灾害类型从图标路径映射中获取对应的图标 URL
            const iconUrl = iconPath[record.dis_type]
            // 检查是否存在对应的图标 URL
            if (iconUrl) {
              // 在 Cesium 视图中添加一个实体
              const entity = viewer.entities.add({
                // 设置实体的位置
                position: position,
                // 设置实体的图标属性
                billboard: {
                  // 图标图像的 URL
                  image: iconUrl,
                  // 图标缩放比例
                  scale: 1.0,
                },
                // 设置实体的名称为灾害点名称
                name: record.pp_name,
              })
            }
          })
          // 创建一个屏幕空间事件处理器,用于处理鼠标点击事件
          const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas)
          // 为左键点击事件设置处理函数
          handler.setInputAction(function (movement) {
            // 获取鼠标点击位置对应的场景对象
            const pickedObject = viewer.scene.pick(movement.position)
            console.log(pickedObject);
            // 检查点击的对象是否为有效的实体
            if (
              Cesium.defined(pickedObject) &&
              pickedObject.id instanceof Cesium.Entity
            ) {
              // 获取点击的实体
              const entity = pickedObject.id
              // 将实体的名称显示在弹窗中
              popup.innerHTML = entity.name
              // 显示弹窗
              popup.style.display = 'block'
              // 设置弹窗的水平位置
              popup.style.left = movement.position.x + 'px'
              // 设置弹窗的垂直位置
              popup.style.top = movement.position.y + 'px'
            } else {
              // 隐藏弹窗
              popup.style.display = 'none'
            }
          }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
        })
        // 捕获并处理请求过程中可能出现的错误
        .catch((error) => console.error('Error loading JSON:', error))
    </script>
  </body>
</html>
posted @ 2025-03-02 22:45  Khru  阅读(360)  评论(0)    收藏  举报