cesium-pocket 0.7.2-alpha → 0.7.3-alpha

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cesium-pocket",
3
- "version": "0.7.2-alpha",
3
+ "version": "0.7.3-alpha",
4
4
  "description": "cesium的插件库;基于vue3的开发",
5
5
  "module": "./index.js",
6
6
  "types": "./index.d.ts",
@@ -0,0 +1,294 @@
1
+ import { Cartographic as f, Math as x, sampleTerrainMostDetailed as y, Cartesian3 as w, ClippingPolygonCollection as I, ClippingPolygon as E, Color as D, Transforms as b, Matrix4 as M, EllipsoidGeodesic as L, ImageMaterialProperty as A, Cartesian2 as B, CallbackProperty as T } from "cesium";
2
+ class v {
3
+ constructor(t, n) {
4
+ this.viewer = t, this.positions = n;
5
+ }
6
+ cartesianToLonLats(t) {
7
+ return t.map((e) => {
8
+ const r = f.fromCartesian(e);
9
+ return [
10
+ x.toDegrees(r.longitude),
11
+ x.toDegrees(r.latitude)
12
+ ];
13
+ });
14
+ }
15
+ }
16
+ class j extends v {
17
+ constructor(t, n, e) {
18
+ super(t, n), this.lonLats = [], this.digDepth = 450, this.stepMeter = 20, this.wallGap = 5, this.topOffset = 20, this.minTerrainHeight = null, this.lonLats = super.cartesianToLonLats(this.positions), this.viewer.scene.globe.depthTestAgainstTerrain = !0, e && (this.digDepth = e.digDepth ?? 450, this.stepMeter = e.stepMeter ?? 20, this.wallGap = e.wallGap ?? 5, this.topOffset = e.topOffset ?? 20);
19
+ }
20
+ /**
21
+ *
22
+ * @param terrainProvider 挖掘操作
23
+ * @returns
24
+ */
25
+ clipping(t) {
26
+ return new Promise((n, e) => {
27
+ const r = this.insetPolygon(this.lonLats, this.wallGap), i = this.densifyBoundary(r, this.stepMeter);
28
+ return y(
29
+ t,
30
+ i.map((s) => s.carto)
31
+ ).then((s) => {
32
+ const a = s.map((l) => l.height);
33
+ this.minTerrainHeight = Math.min(...a);
34
+ const o = i.map(
35
+ (l) => w.fromDegrees(l.lon, l.lat)
36
+ );
37
+ n(o), this.viewer.scene.globe.clippingPolygons = new I({
38
+ polygons: [new E({ positions: this.positions })],
39
+ enabled: !0,
40
+ inverse: !1
41
+ }), this.generateEntities(o, a);
42
+ }).catch((s) => {
43
+ e(s);
44
+ });
45
+ });
46
+ }
47
+ generateEntities(t, n) {
48
+ const e = Math.min(...n) - this.digDepth;
49
+ this.viewer.entities.add({
50
+ name: "坑底",
51
+ polygon: {
52
+ hierarchy: t,
53
+ height: e,
54
+ material: this.soilMaterial(16, 16),
55
+ outline: !0,
56
+ outlineColor: D.fromCssColorString("#3d2914")
57
+ }
58
+ });
59
+ const r = [...t, t[0]], i = [...n, n[0]];
60
+ this.viewer.entities.add({
61
+ name: "侧面土层",
62
+ wall: {
63
+ positions: r,
64
+ maximumHeights: i.map((s) => s + this.topOffset),
65
+ minimumHeights: i.map(() => e),
66
+ material: this.soilMaterial(48, 6)
67
+ }
68
+ });
69
+ }
70
+ /**
71
+ * 规则部分体积,立方米。
72
+ * 边界最低点所在水平面到坑底是等高的柱体,高度就是 digDepth。
73
+ */
74
+ calcRegularVolume() {
75
+ return this.polygonArea(this.lonLats) * this.digDepth;
76
+ }
77
+ /**
78
+ * 整个开挖体积,立方米。
79
+ * 多边形内从地形表面挖到坑底,等于规则柱体再加上最低点以上的地形土方。
80
+ * 须先调用 clipping,或传入 terrainProvider。
81
+ */
82
+ calcTotalVolume(t, n = 4e3) {
83
+ if (!t)
84
+ return Promise.reject(new Error("计算开挖体积前请先调用 clipping,或传入 terrainProvider"));
85
+ const e = this.minTerrainHeight == null ? this.sampleBoundaryMinHeight(t) : Promise.resolve(this.minTerrainHeight);
86
+ return Promise.all([
87
+ e,
88
+ this.sampleMeanInteriorHeight(t, n)
89
+ ]).then(([r, i]) => {
90
+ const s = r - this.digDepth;
91
+ return (i - s) * this.polygonArea(this.lonLats);
92
+ });
93
+ }
94
+ /** 与坑壁同一套内缩边界上的最低高程,保证体积和坑底是同一个最低点 */
95
+ sampleBoundaryMinHeight(t) {
96
+ return new Promise((n, e) => {
97
+ const r = this.insetPolygon(this.lonLats, this.wallGap), i = this.densifyBoundary(r, this.stepMeter);
98
+ y(
99
+ t,
100
+ i.map((s) => s.carto)
101
+ ).then((s) => {
102
+ let a = Math.min(...s.map((o) => o.height));
103
+ n(a);
104
+ }).catch((s) => {
105
+ e(s);
106
+ });
107
+ });
108
+ }
109
+ /** 多边形内均匀取样的平均地面高程 */
110
+ sampleMeanInteriorHeight(t, n) {
111
+ const { enu: e, inverse: r } = this.createEnuFrame(this.lonLats), i = this.toLocalPoints(this.lonLats, r), s = Math.abs(this.shoelace(i)) / 2;
112
+ let a = 1 / 0, o = -1 / 0, l = 1 / 0, c = -1 / 0;
113
+ for (const h of i)
114
+ a = Math.min(a, h.x), o = Math.max(o, h.x), l = Math.min(l, h.y), c = Math.max(c, h.y);
115
+ const g = Math.min(500, Math.max(30, Math.sqrt(s / n))), u = [];
116
+ for (let h = a + g / 2; h <= o; h += g)
117
+ for (let m = l + g / 2; m <= c; m += g)
118
+ this.pointInPolygon(h, m, i) && u.push(this.localToCartographic(h, m, e));
119
+ if (u.length === 0) {
120
+ const h = i.reduce((p, d) => p + d.x, 0) / i.length, m = i.reduce((p, d) => p + d.y, 0) / i.length;
121
+ u.push(this.localToCartographic(h, m, e));
122
+ }
123
+ return new Promise((h, m) => {
124
+ y(t, u).then((p) => {
125
+ let d = 0, H = 0;
126
+ for (const P of p)
127
+ Number.isFinite(P.height) && (d += P.height, H++);
128
+ if (H === 0)
129
+ throw new Error("开挖范围内没有可用的地形高程");
130
+ h(d / H);
131
+ }).catch((p) => {
132
+ m(p);
133
+ });
134
+ });
135
+ }
136
+ /** 开挖多边形的水平面积,平方米。投影到质心的东北天平面后用鞋带公式 */
137
+ polygonArea(t) {
138
+ const { inverse: n } = this.createEnuFrame(t);
139
+ return Math.abs(this.shoelace(this.toLocalPoints(t, n))) / 2;
140
+ }
141
+ createEnuFrame(t) {
142
+ const n = t.reduce((a, o) => a + o[0], 0) / t.length, e = t.reduce((a, o) => a + o[1], 0) / t.length, r = w.fromDegrees(n, e), i = b.eastNorthUpToFixedFrame(r), s = M.inverse(i, new M());
143
+ return { enu: i, inverse: s };
144
+ }
145
+ toLocalPoints(t, n) {
146
+ return t.map(([e, r]) => {
147
+ const i = M.multiplyByPoint(
148
+ n,
149
+ w.fromDegrees(e, r),
150
+ new w()
151
+ );
152
+ return { x: i.x, y: i.y };
153
+ });
154
+ }
155
+ localToCartographic(t, n, e) {
156
+ const r = M.multiplyByPoint(e, new w(t, n, 0), new w());
157
+ return f.fromCartesian(r);
158
+ }
159
+ shoelace(t) {
160
+ let n = 0;
161
+ for (let e = 0; e < t.length; e++) {
162
+ const r = (e + 1) % t.length;
163
+ n += t[e].x * t[r].y - t[r].x * t[e].y;
164
+ }
165
+ return n;
166
+ }
167
+ pointInPolygon(t, n, e) {
168
+ let r = !1;
169
+ for (let i = 0, s = e.length - 1; i < e.length; s = i++) {
170
+ const a = e[i].y, o = e[s].y;
171
+ a > n != o > n && t < (e[s].x - e[i].x) * (n - a) / (o - a) + e[i].x && (r = !r);
172
+ }
173
+ return r;
174
+ }
175
+ /** 多边形向质心内收固定米数,避免按比例内缩在大范围上留出宽缝 */
176
+ insetPolygon(t, n) {
177
+ const e = t.reduce((i, s) => i + s[0], 0) / t.length, r = t.reduce((i, s) => i + s[1], 0) / t.length;
178
+ return t.map(([i, s]) => {
179
+ const a = s * Math.PI / 180, o = (i - e) * 111320 * Math.cos(a), l = (s - r) * 110540, c = Math.hypot(o, l);
180
+ if (c <= n) return [i, s];
181
+ const g = (c - n) / c;
182
+ return [e + (i - e) * g, r + (s - r) * g];
183
+ });
184
+ }
185
+ /** 沿闭合边线按间距加密 */
186
+ densifyBoundary(t, n) {
187
+ const e = [], r = t.length;
188
+ for (let i = 0; i < r; i++) {
189
+ const [s, a] = t[i], [o, l] = t[(i + 1) % r], c = new L(
190
+ f.fromDegrees(s, a),
191
+ f.fromDegrees(o, l)
192
+ ), g = Math.max(1, Math.ceil(c.surfaceDistance / n));
193
+ for (let u = 0; u < g; u++) {
194
+ const h = c.interpolateUsingFraction(u / g);
195
+ e.push({
196
+ lon: x.toDegrees(h.longitude),
197
+ lat: x.toDegrees(h.latitude),
198
+ carto: h
199
+ });
200
+ }
201
+ }
202
+ return e;
203
+ }
204
+ /** 画一张近似土壤的贴图,侧面和底部共用 */
205
+ createSoilImage() {
206
+ const n = document.createElement("canvas");
207
+ n.width = n.height = 128;
208
+ const e = n.getContext("2d"), r = e.createImageData(128, 128), i = r.data;
209
+ for (let s = 0; s < i.length; s += 4) {
210
+ const a = Math.random();
211
+ i[s] = 100 + a * 60, i[s + 1] = 58 + a * 36, i[s + 2] = 26 + a * 18, i[s + 3] = 255;
212
+ }
213
+ return e.putImageData(r, 0, 0), n;
214
+ }
215
+ soilMaterial(t, n) {
216
+ return new A({
217
+ image: this.createSoilImage(),
218
+ repeat: new B(t, n)
219
+ });
220
+ }
221
+ }
222
+ const F = 10;
223
+ class G extends v {
224
+ //最低高度向下的高度差(terrainMinH不一定是实际的最低高度)
225
+ constructor(t, n, e) {
226
+ super(t, n), this.lonLats = [], this.waterHeight = 0, this.terrainMinH = 0, this.terrainMaxH = 0, this.downwardDistance = 50, this.upwardDistance = 100, e && (this.downwardDistance = e.downwardDistance || 50, this.upwardDistance = e.upwardDistance || 100);
227
+ }
228
+ init(t) {
229
+ return this.lonLats = super.cartesianToLonLats(this.positions), this.initFlood(t);
230
+ }
231
+ getMinHight() {
232
+ return this.terrainMinH - this.downwardDistance;
233
+ }
234
+ getMaxHight() {
235
+ return this.terrainMaxH + this.upwardDistance;
236
+ }
237
+ getWaterHight() {
238
+ return this.waterHeight;
239
+ }
240
+ setWaterHeight(t) {
241
+ this.terrainMinH - this.downwardDistance > t && (t = this.terrainMinH - this.downwardDistance), this.terrainMaxH + this.upwardDistance < t && (t = this.terrainMaxH + this.upwardDistance), this.waterHeight = t;
242
+ }
243
+ /**
244
+ * 沿闭合多边形边线按间距加密,得到贴地采样点
245
+ * 只采边界(贴地线),不采多边形内部
246
+ */
247
+ densifyBoundary(t, n) {
248
+ const e = [], r = t.length;
249
+ console.log(r);
250
+ for (let i = 0; i < r; i++) {
251
+ const [s, a] = t[i], [o, l] = t[(i + 1) % r], c = new L(
252
+ f.fromDegrees(s, a),
253
+ f.fromDegrees(o, l)
254
+ ), g = Math.max(1, Math.ceil(c.surfaceDistance / n));
255
+ for (let u = 0; u < g; u++)
256
+ e.push(c.interpolateUsingFraction(u / g));
257
+ }
258
+ return e;
259
+ }
260
+ /** 采样贴地高程 → 定水位范围 → 画范围线与立体水体 */
261
+ initFlood(t) {
262
+ return new Promise((n, e) => {
263
+ this.viewer.scene.globe.depthTestAgainstTerrain = !0, y(
264
+ t,
265
+ this.densifyBoundary(this.lonLats, F)
266
+ ).then((r) => {
267
+ const i = r.map((a) => a.height);
268
+ this.terrainMinH = Math.round(Math.min(...i)), this.terrainMaxH = Math.round(Math.max(...i)), this.waterHeight = Math.round(this.terrainMinH / 2 + this.terrainMaxH / 2);
269
+ let s = this.getWaterEntity();
270
+ n(s);
271
+ }).catch((r) => {
272
+ e(r);
273
+ });
274
+ });
275
+ }
276
+ getWaterEntity() {
277
+ return this.viewer.entities.add({
278
+ polygon: {
279
+ hierarchy: this.positions,
280
+ height: new T(() => this.terrainMinH - this.downwardDistance, !1),
281
+ extrudedHeight: new T(() => this.waterHeight, !1),
282
+ material: D.fromCssColorString("#1e90ff").withAlpha(0.45),
283
+ outline: !0,
284
+ outlineColor: D.CYAN,
285
+ closeTop: !0,
286
+ closeBottom: !0
287
+ }
288
+ });
289
+ }
290
+ }
291
+ export {
292
+ j as C,
293
+ G as S
294
+ };