Cesium快速入门到精通系列教程二十五:以较长经纬度跨度为基准,将多边形充满屏幕,返回此时的中心点坐标及相机高度

Cesium 1.138 四点外接矩形中心 + 自适应相机高度计算函数:

输入:4 个经纬度坐标点(WGS84)

输出:几何中心点 + 让四点组成多边形刚好充满屏幕的相机高度

计算规则:以南北 / 东西较短边为基准,以几何中心为视野中心,刚好充满视口

完整代码(Cesium 1.138 兼容)

复制代码
<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cesium GeoJSON 线要素加载示例</title>
    <!-- 引入 Cesium 库(这里使用官方 CDN,你也可以替换为本地路径) -->
    <script src="https://unpkg.com/cesium@1.138.0/Build/Cesium/Cesium.js"></script>
    <link
      href="https://unpkg.com/cesium@1.138.0/Build/Cesium/Widgets/widgets.css"
      rel="stylesheet"
    />
    <style>
      html,
      body,
      #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }
    </style>
  </head>

  <body>
    <div id="cesiumContainer"></div>

    <script>
      // 1. 初始化 Cesium 地图(替换 MFmap 为原生 Cesium 初始化)
      Cesium.Ion.defaultAccessToken =
        "defaultAccessToken"; // 替换为你的 Token,可从 Cesium 官网获取

      const viewer = new Cesium.Viewer("cesiumContainer", {
        geocoder: false,
        timeline: false,
        animation: false,
        baseLayerPicker: false,
        fullscreenButton: false,
        vrButton: false,
        homeButton: false,
        infoBox: false,
        selectionIndicator: false,
        navigationHelpButton: false,
        // imageryProvider: false, // 禁用默认的imageryProvider
        // 开启抗锯齿(MSAA)
        antialias: true,
        // 开启 FXAA 快速抗锯齿(补充 MSAA,更平滑)
        fxaa: true,
      });

      /**
       * 【终极无偏差版】获取4个点的几何中心 + 相机高度
       * 采用 Cesium 原生计算,绝对精准充满屏幕
       * @param {Cesium.Viewer} viewer
       * @param {Array<Array>} points - 4个经纬度点 [[lon,lat], ...]
       * @returns { center: [lon,lat], cameraHeight: 高度 }
       */
      async function getCenterAndCameraHeight(viewer, points) {
        // 1. 构建矩形范围
        const lons = points.map((p) => p[0]);
        const lats = points.map((p) => p[1]);
        const rectangle = Cesium.Rectangle.fromDegrees(
          Math.min(...lons),
          Math.min(...lats),
          Math.max(...lons),
          Math.max(...lats),
        );

        // 2. 计算几何中心点
        const centerCartographic = Cesium.Rectangle.center(rectangle);
        const center = [
          Cesium.Math.toDegrees(centerCartographic.longitude),
          Cesium.Math.toDegrees(centerCartographic.latitude),
        ];

        // 3. 【核心】调用 Cesium 原生相机计算:刚好充满屏幕的相机参数
        const cameraOpts =
          viewer.camera.getRectangleCameraCoordinates(rectangle);

        // 4. 提取相机高度
        const cartographic = Cesium.Cartographic.fromCartesian(cameraOpts);
        const cameraHeight = cartographic.height;

        return { center, cameraHeight };
      }

      /**
       * 飞行到4点区域,绝对刚好充满屏幕
       */
      async function flyToPerfectFit(viewer, points) {
        const { center, cameraHeight } = await getCenterAndCameraHeight(
          viewer,
          points,
        );

        viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(
            center[0],
            center[1],
            cameraHeight,
          ),
          orientation: {
            heading: 0,
            pitch: Cesium.Math.toRadians(-90), // 正俯视
            roll: 0,
          },
          duration: 1,
        });
      }

      // 1. 四个测试点(经纬度)
      const fourPoints = [
        [113.25, 23.12],
        [113.33, 23.1],
        [113.3, 23.03],
        [113.23, 23.06],
      ];

      // 2. 一键飞行(自动计算中心 + 自适应高度)
      flyToPerfectFit(viewer, fourPoints);

      // 1. 绘制带背景色的多边形
      viewer.entities.add({
        polygon: {
          // 坐标点:经纬度数组 → 直接转笛卡尔坐标
          hierarchy: Cesium.Cartesian3.fromDegreesArray(fourPoints.flat()),

          // 填充背景色(半透明蓝色,可自定义)
          fill: true,
          material: Cesium.Color.fromBytes(66, 135, 245, 120), // 最后一位是透明度 0-255

          // 边框(可选)
          outline: true,
          outlineColor: Cesium.Color.BLUE,
          outlineWidth: 2,
        },
      });
    </script>
  </body>
</html>

核心逻辑说明

几何中心点

取 4 个点的最小 / 最大经纬度

中心点 = (minLon+maxLon)/2、(minLat+maxLat)/2

是外接矩形中心,也是你要求的几何中心

距离计算

把经纬度差转换成真实地表距离(米)

分别计算:东西总长度、南北总长度

相机高度(核心公式)

以较短边为基准

高度 = (较短边长度 / 2) / tan(垂直视场角 / 2)

这个公式能保证:目标刚好充满屏幕视口

默认视场角

Cesium 默认垂直视场角:60°

你可以传入自定义弧度值

相关推荐
阿琳a_6 天前
在github上部署个人的vitepress文档网站
前端·vue.js·github·网站搭建·cesium
云上飞476369627 天前
glb模型在Cesium中发黑的机理分析
cesium·glb模型发黑
ct9788 天前
Cesium的Primitive API
gis·webgl·cesium
Irene19919 天前
OpenLayers 和 Cesium 都是流行的开源 JavaScript 库,用于在网页上构建地图和地理空间应用
openlayers·cesium
fxshy9 天前
前端直连模型 vs 完整 MCP:大模型驱动地图的原理与实践(技术栈Vue + Cesium + Node.js + WebSocket + MCP)
前端·vue.js·node.js·cesium·mcp
棋鬼王10 天前
Cesium(十) 动态修改白模颜色、白模渐变色、白模光圈特效、白模动态扫描光效、白模着色器
前端·javascript·vue.js·智慧城市·数字孪生·cesium
duansamve10 天前
Cesium快速入门到精通系列教程二十四:限制相机在特定的Level之间展示地图
cesium
duansamve13 天前
Vue3的Vite项目中直接引入的方式使用Cesium
cesium
WebGISer_白茶乌龙桃14 天前
基于 Cesium 的 GLB 建筑模型分层分房间点击拾取技术实现
前端·javascript·vue.js·webgl·cesium