cesium-pocket 0.7.2-alpha → 0.7.4-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.
@@ -44,6 +44,12 @@ export declare class CP2dDrawer extends DataCenter {
44
44
  private moveCtrlEvent;
45
45
  private measurePoint;
46
46
  protected editMoveFun(event: any, cartesian: Cartesian3): void;
47
+ /**
48
+ * 按当前顶点数创建预览图形。
49
+ * 顶点不够时不创建:面至少要 3 个点、线至少要 2 个点,
50
+ * 否则会生成无效几何,让 Cesium 报错甚至停止渲染。
51
+ */
52
+ private syncPreview;
47
53
  private createMainLine;
48
54
  private createMainPolygon;
49
55
  private createDashline;
@@ -27,6 +27,18 @@ export declare class DataCenter extends DrawerStatus {
27
27
  * @returns Cartesian3[]
28
28
  */
29
29
  protected dsToMd(): Cartesian3[];
30
+ /**
31
+ * 复制成普通坐标对象。
32
+ * 一是去掉挂在上面的附加属性;二是万一外部把响应式代理传进来,
33
+ * 复制后就是普通对象,可以安全地 postMessage 给 Web Worker。
34
+ */
35
+ protected toPlainCartesian3(cartesian: Cartesian3): Cartesian3;
36
+ /**
37
+ * 过滤出合法坐标并复制成普通对象。
38
+ * 数组里可能混入 undefined(绘制过程中还没拾取到地表点),
39
+ * 直接交给 Cesium 会抛出 “Cannot set properties of undefined”。
40
+ */
41
+ protected toPlainPositions(positions: ReadonlyArray<Cartesian3 | undefined | null> | undefined | null): Cartesian3[];
30
42
  /**
31
43
  * 根据mainData更新dataSource
32
44
  * @returns Cartesian3[]
@@ -1,4 +1,4 @@
1
- import { Cartesian3, Viewer, PolylineGraphics, PolygonGraphics, PointGraphics } from 'cesium';
1
+ import { Cartesian3, Viewer, Entity, PolylineGraphics, PolygonGraphics, PointGraphics } from 'cesium';
2
2
  import { DataCenter } from './DataCenter';
3
3
  export type RectMoveFn = (cartesians: Cartesian3[]) => void;
4
4
  export interface RectOptions {
@@ -22,7 +22,7 @@ export declare class RectDrawer extends DataCenter {
22
22
  private rectOverFun;
23
23
  constructor(viewer: Viewer, options?: RectOptions);
24
24
  start(): void;
25
- getEntity(): void;
25
+ getEntity(): Entity | null;
26
26
  getPositions(): Cartesian3[];
27
27
  /**
28
28
  * 根据数据直接生成图形
@@ -37,6 +37,12 @@ export declare class RectDrawer extends DataCenter {
37
37
  private rect_moveEvent;
38
38
  private rectMove;
39
39
  private initMainData;
40
+ /**
41
+ * 按当前顶点数创建预览图形。
42
+ * 顶点不够时不创建:面至少要 3 个点、线至少要 2 个点,
43
+ * 否则会生成无效几何,让 Cesium 报错甚至停止渲染。
44
+ */
45
+ private syncPreview;
40
46
  private createLine;
41
47
  private createPolygon;
42
48
  }
@@ -1,4 +1,16 @@
1
1
  import { Cartesian3 } from 'cesium';
2
+ /**
3
+ * 取出 Vue 响应式对象的原始值。
4
+ * Cesium 生成几何体时会通过 postMessage 把参数发到 Web Worker,
5
+ * 而 Vue 的 Proxy 无法被结构化克隆,会抛 DataCloneError,
6
+ * 所以所有交给 Cesium 的对象都必须先去掉响应式代理。
7
+ */
8
+ export declare const getRaw: <T>(value: T) => T;
9
+ /**
10
+ * 复制成全新的 Cartesian3,去掉 Vue 代理以及挂在上面的附加属性,
11
+ * 保证进入 Cesium 几何参数的始终是纯净、可序列化的坐标。
12
+ */
13
+ export declare const toPlainCartesian3: (position: Cartesian3) => Cartesian3;
2
14
  export declare const getGroundDistance: (cartesian1: Cartesian3, cartesian2: Cartesian3) => number;
3
15
  export declare const getCenterPosition: (cartesian1: Cartesian3, cartesian2: Cartesian3) => Cartesian3;
4
16
  export declare const getDistanceLabel: (distance: number) => string;
@@ -22,3 +34,15 @@ export declare const getAreaText: (area: number) => string;
22
34
  * @returns
23
35
  */
24
36
  export declare const calculatePlanarArea: (positions: Cartesian3[]) => string;
37
+ /**
38
+ * 计算柱体体积,单位立方米。
39
+ * @param area 底面积,单位平方米
40
+ * @param height 向上拉伸的高度,单位米
41
+ */
42
+ export declare const getSolidVolume: (area: number, height: number) => number;
43
+ /**
44
+ * 把体积(立方米)换算成合适的单位显示。
45
+ * 1 立方公里 = 1e9 立方米,1 万立方公里 = 1e13 立方米。
46
+ * @param volume 体积,单位立方米
47
+ */
48
+ export declare const getVolumeText: (volume: number) => string;
@@ -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
+ };
@@ -1,9 +0,0 @@
1
- import { Cartesian3, Label, Viewer } from 'cesium';
2
- export declare const getTimeStr: () => string;
3
- export declare const getGroundDistance: (cartesian1: Cartesian3, cartesian2: Cartesian3) => number;
4
- export declare const getCenterPosition: (cartesian1: Cartesian3, cartesian2: Cartesian3) => Cartesian3;
5
- export declare const getTextlabel: (viewer: Viewer, cartesian: Cartesian3, text: string, label?: Label | null) => import('cesium').Entity;
6
- export declare const getDistanceLabel: (distance: number) => string;
7
- export declare const getAreaLabel: (area: number) => string;
8
- export declare const getCentroid: (positions: Cartesian3[]) => Cartesian3 | null;
9
- export declare const calculatePlanarArea: (positions: Cartesian3[]) => number;