cesium-xs-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,95 @@
1
+ /**
2
+ * 地理计算工具(距离、面积、高程)
3
+ */
4
+ export class GeoCalcUtil {
5
+ /**
6
+ * 计算两点地理坐标距离(米)
7
+ * @param {Array<number>} point1 [lng, lat, height]
8
+ * @param {Array<number>} point2 [lng, lat, height]
9
+ * @returns {number} 距离
10
+ */
11
+ static calcDistance(point1, point2) {
12
+ const coord1 = Cesium.Cartesian3.fromDegrees(...point1);
13
+ const coord2 = Cesium.Cartesian3.fromDegrees(...point2);
14
+ return Cesium.Cartesian3.distance(coord1, coord2);
15
+ }
16
+
17
+ /**
18
+ * 计算多边形面积(平方米)
19
+ * 使用球面多边形面积公式(基于 Cesium 几何顶点)
20
+ * @param {Array<Array<number>>} points 地理坐标点集 [lon, lat, height?]
21
+ * @returns {number} 面积
22
+ */
23
+ static calcArea(points) {
24
+ if (!points || points.length < 3) return 0;
25
+
26
+ const positions = points.map(p => Cesium.Cartesian3.fromDegrees(p[0], p[1], p[2] || 0));
27
+ const polygon = new Cesium.PolygonGeometry({
28
+ polygonHierarchy: new Cesium.PolygonHierarchy(positions)
29
+ });
30
+ const geometry = Cesium.PolygonGeometry.createGeometry(polygon);
31
+
32
+ if (!geometry || !geometry.attributes || !geometry.attributes.position) {
33
+ return 0;
34
+ }
35
+
36
+ const values = geometry.attributes.position.values;
37
+ const vertexPositions = [];
38
+ for (let i = 0; i < values.length; i += 3) {
39
+ vertexPositions.push(new Cesium.Cartesian3(values[i], values[i + 1], values[i + 2]));
40
+ }
41
+
42
+ // 球面多边形面积(基于单位球上的多边形面积公式)
43
+ const area = GeoCalcUtil.#sphericalPolygonArea(vertexPositions);
44
+ return Math.abs(area);
45
+ }
46
+
47
+ /**
48
+ * 单位球面上多边形的有向面积(平方米)
49
+ * 采用局部切平面投影法:以多边形重心为原点建立切平面,投影后计算二维多边形面积。
50
+ * 对于常规 GIS 多边形精度足够;极大规模多边形可后续替换为更严格的球面 excess 算法。
51
+ * @param {Cesium.Cartesian3[]} positions 世界坐标顶点
52
+ * @returns {number} 面积(平方米)
53
+ */
54
+ static #sphericalPolygonArea(positions) {
55
+ const ellipsoid = Cesium.Ellipsoid.WGS84;
56
+ const n = positions.length;
57
+ if (n < 3) return 0;
58
+
59
+ // 计算近似重心(归一化到椭球面)
60
+ let center = new Cesium.Cartesian3(0, 0, 0);
61
+ for (const p of positions) {
62
+ center = Cesium.Cartesian3.add(center, p, center);
63
+ }
64
+ center = Cesium.Cartesian3.normalize(center, new Cesium.Cartesian3());
65
+ center = ellipsoid.scaleToGeodeticSurface(center, new Cesium.Cartesian3()) || center;
66
+
67
+ // 在重心处建立东北天(ENU)局部坐标系
68
+ const tangentPlane = new Cesium.EllipsoidTangentPlane(center, ellipsoid);
69
+
70
+ // 投影到切平面
71
+ const projected = positions.map(p => tangentPlane.projectPointOntoPlane(p, new Cesium.Cartesian2()));
72
+
73
+ // 计算二维多边形面积(Shoelace 公式)
74
+ let area2 = 0;
75
+ for (let i = 0; i < n; i++) {
76
+ const p1 = projected[i];
77
+ const p2 = projected[(i + 1) % n];
78
+ area2 += p1.x * p2.y - p2.x * p1.y;
79
+ }
80
+
81
+ return Math.abs(area2) * 0.5;
82
+ }
83
+
84
+ /**
85
+ * 获取指定地理坐标的高程
86
+ * @param {Cesium.Viewer} viewer Cesium 实例
87
+ * @param {Array<number>} coord [lng, lat]
88
+ * @returns {Promise<number>} 高程值
89
+ */
90
+ static async getHeight(viewer, coord) {
91
+ const cartographic = Cesium.Cartographic.fromDegrees(coord[0], coord[1]);
92
+ const results = await Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [cartographic]);
93
+ return results[0]?.height ?? 0;
94
+ }
95
+ }