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°
你可以传入自定义弧度值