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/analysis.js +5 -0
- package/czml.d.ts +1 -1
- package/czml.js +319 -0
- package/index.js +728 -1017
- package/package.json +1 -1
- package/submerger-Bqh-bzY0.js +294 -0
package/package.json
CHANGED
|
@@ -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
|
+
};
|