cesium-multi-target-framework 0.1.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.
- package/README.md +474 -0
- package/dist/assets/renderWorker-118e8f3b.js +1 -0
- package/dist/cesium-multi-target-framework.js +4605 -0
- package/dist/cesium-multi-target-framework.umd.cjs +101 -0
- package/dist/cluster/QuadCluster.d.ts +66 -0
- package/dist/cluster/clusterClient.d.ts +44 -0
- package/dist/cluster/clusterWorker.d.ts +1 -0
- package/dist/config/types.d.ts +266 -0
- package/dist/core/EventEmitter.d.ts +9 -0
- package/dist/core/MultiTargetFramework.d.ts +184 -0
- package/dist/core/MultiTargetScene.d.ts +224 -0
- package/dist/data/types.d.ts +67 -0
- package/dist/events/bus.d.ts +336 -0
- package/dist/index.d.ts +22 -0
- package/dist/render/AirGroundReferenceRenderer.d.ts +20 -0
- package/dist/render/InstancedGltfBatch.d.ts +37 -0
- package/dist/render/InstancedSymbolRenderer.d.ts +65 -0
- package/dist/render/LowModelInstancedRenderer.d.ts +39 -0
- package/dist/render/ModelPoolRenderer.d.ts +43 -0
- package/dist/render/PointCloudRenderer.d.ts +135 -0
- package/dist/render/SelectionOverlayRenderer.d.ts +37 -0
- package/dist/render/targetVisualMetrics.d.ts +9 -0
- package/dist/site/SiteLayer.d.ts +43 -0
- package/dist/site/SiteLowModelRenderer.d.ts +12 -0
- package/dist/site/SiteSpatialIndex.d.ts +10 -0
- package/dist/site/types.d.ts +72 -0
- package/dist/track/TrackHoverPicker.d.ts +26 -0
- package/dist/track/TrackManager.d.ts +42 -0
- package/dist/track/TrackRenderer.d.ts +29 -0
- package/dist/track/types.d.ts +27 -0
- package/dist/worker/protocol.d.ts +182 -0
- package/dist/worker/renderWorker.d.ts +1 -0
- package/doc//345/244/232/347/233/256/346/240/207/344/274/230/345/214/226/344/270/216/351/242/204/346/265/213/346/270/262/346/237/223/350/257/264/346/230/216.md +186 -0
- package/doc//345/244/232/347/273/204/344/273/266/344/272/213/344/273/266/346/226/271/346/241/210.md +410 -0
- package/doc//345/257/271/345/244/226/346/216/245/345/217/243/350/257/264/346/230/216.md +519 -0
- package/doc//345/267/245/344/275/234/350/256/241/345/210/222.md +59 -0
- package/doc//346/270/262/346/237/223/344/270/232/345/212/241/351/200/273/350/276/221.md +202 -0
- package/doc//347/253/231/347/202/271/346/270/262/346/237/223/344/270/216/345/217/263/351/224/256/350/217/234/345/215/225/345/256/236/347/216/260/350/257/264/346/230/216.md +49 -0
- package/doc//350/247/206/345/217/243/351/251/261/345/212/250/346/225/260/346/215/256/346/265/201/347/250/213/344/277/256/346/224/271/350/256/241/345/210/222.md +69 -0
- package/doc//351/241/271/347/233/256/350/257/264/346/230/216/344/271/246.md +729 -0
- package/package.json +51 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
export interface LodConfig {
|
|
2
|
+
pointAbove: number;
|
|
3
|
+
animatedBelow: number;
|
|
4
|
+
}
|
|
5
|
+
export declare const TARGET_DOMAINS: {
|
|
6
|
+
readonly SURFACE: "surface";
|
|
7
|
+
readonly AIR: "air";
|
|
8
|
+
readonly UNDERWATER: "underwater";
|
|
9
|
+
};
|
|
10
|
+
export type TargetDomain = (typeof TARGET_DOMAINS)[keyof typeof TARGET_DOMAINS];
|
|
11
|
+
export interface ModelAssetConfig {
|
|
12
|
+
url: string;
|
|
13
|
+
scale?: number;
|
|
14
|
+
headingOffset?: number;
|
|
15
|
+
pitchOffset?: number;
|
|
16
|
+
rollOffset?: number;
|
|
17
|
+
runAnimations?: boolean;
|
|
18
|
+
animationLoop?: "none" | "repeat" | "mirroredRepeat";
|
|
19
|
+
animationMultiplier?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface NodeTypeConfig {
|
|
22
|
+
name: string;
|
|
23
|
+
type: string;
|
|
24
|
+
targetDomain?: TargetDomain;
|
|
25
|
+
forceHighModelInLowLod?: boolean;
|
|
26
|
+
iconPath?: string;
|
|
27
|
+
defaultColor?: string;
|
|
28
|
+
highModel?: ModelAssetConfig;
|
|
29
|
+
lowModel?: ModelAssetConfig;
|
|
30
|
+
highModelUrl?: string;
|
|
31
|
+
lowModelUrl?: string;
|
|
32
|
+
pointIcon?: string;
|
|
33
|
+
pointPixelSize?: number;
|
|
34
|
+
pointHeadingOffset?: number;
|
|
35
|
+
scale?: number;
|
|
36
|
+
modelHeadingOffset?: number;
|
|
37
|
+
modelPitchOffset?: number;
|
|
38
|
+
modelRollOffset?: number;
|
|
39
|
+
lod?: Partial<LodConfig>;
|
|
40
|
+
smoothMove?: boolean;
|
|
41
|
+
smoothMoveMinCameraHeight?: number;
|
|
42
|
+
moveAnimationDurationMs?: number;
|
|
43
|
+
smoothMoveDurationMs?: number;
|
|
44
|
+
predictMove?: boolean;
|
|
45
|
+
predictMinCameraHeight?: number;
|
|
46
|
+
predictSeconds?: number;
|
|
47
|
+
predictFitSeconds?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface ResolvedNodeTypeConfig extends NodeTypeConfig {
|
|
50
|
+
iconPath: string;
|
|
51
|
+
defaultColor: string;
|
|
52
|
+
targetDomain: TargetDomain;
|
|
53
|
+
forceHighModelInLowLod: boolean;
|
|
54
|
+
smoothMove: boolean;
|
|
55
|
+
pointHeadingOffset: number;
|
|
56
|
+
smoothMoveMinCameraHeight: number;
|
|
57
|
+
smoothMoveDurationMs: number;
|
|
58
|
+
predictMove: boolean;
|
|
59
|
+
predictMinCameraHeight: number;
|
|
60
|
+
predictSeconds?: number;
|
|
61
|
+
predictFitSeconds?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface PoolConfig {
|
|
64
|
+
size: number;
|
|
65
|
+
}
|
|
66
|
+
export interface AnimatedPoolConfig {
|
|
67
|
+
size: number;
|
|
68
|
+
}
|
|
69
|
+
export interface MergeConfig {
|
|
70
|
+
enabled: boolean;
|
|
71
|
+
mode?: "viewport" | "global";
|
|
72
|
+
maxVisible?: number;
|
|
73
|
+
globalRootLimit?: number;
|
|
74
|
+
globalMaxLevels?: number;
|
|
75
|
+
globalRebuildIntervalMs?: number;
|
|
76
|
+
globalViewportHeight?: number;
|
|
77
|
+
/** 低于/等于该相机高度不合并,单位米;默认 100000 = 100km */
|
|
78
|
+
cameraMergeBaseHeight?: number;
|
|
79
|
+
/** 相机高度每增加多少米,合并半径增加一档;默认 10000 */
|
|
80
|
+
cameraMergeStepHeight?: number;
|
|
81
|
+
/** 每档合并半径增加多少米;默认 100 */
|
|
82
|
+
cameraMergeStepRadius?: number;
|
|
83
|
+
innerRatio?: number;
|
|
84
|
+
radii?: number[];
|
|
85
|
+
byType?: boolean;
|
|
86
|
+
minSecrecy?: number;
|
|
87
|
+
bucketCellDeg?: number;
|
|
88
|
+
}
|
|
89
|
+
export interface PickConfig {
|
|
90
|
+
enabled?: boolean;
|
|
91
|
+
pixelThreshold?: number;
|
|
92
|
+
hover?: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface CullConfig {
|
|
95
|
+
enabled?: boolean;
|
|
96
|
+
padding?: number;
|
|
97
|
+
viewportCull?: boolean;
|
|
98
|
+
viewportBufferRatio?: number;
|
|
99
|
+
/**
|
|
100
|
+
* 视口缓冲的绝对下限(米)。相机贴近目标时视野矩形极小,单纯按
|
|
101
|
+
* viewportBufferRatio 的相对缓冲也会非常小,近处快速移动的目标容易
|
|
102
|
+
* 在一帧节流窗口内移出缓冲被裁掉造成闪烁。实际缓冲取
|
|
103
|
+
* max(相对缓冲, 该下限对应的经纬度),高空时相对缓冲远大于此值故不受影响。
|
|
104
|
+
*/
|
|
105
|
+
viewportBufferMinMeters?: number;
|
|
106
|
+
}
|
|
107
|
+
export interface HorizonCullConfig {
|
|
108
|
+
enabled?: boolean;
|
|
109
|
+
pitchThreshold?: number;
|
|
110
|
+
minDistance?: number;
|
|
111
|
+
maxDistance?: number;
|
|
112
|
+
cameraHeightMultiplier?: number;
|
|
113
|
+
maxCameraHeight?: number;
|
|
114
|
+
}
|
|
115
|
+
export type LabelFieldSource = "standard" | "custom";
|
|
116
|
+
export interface LabelFieldConfig {
|
|
117
|
+
key: string;
|
|
118
|
+
label?: string;
|
|
119
|
+
source?: LabelFieldSource;
|
|
120
|
+
fallback?: string;
|
|
121
|
+
minCameraHeight?: number;
|
|
122
|
+
maxCameraHeight?: number;
|
|
123
|
+
}
|
|
124
|
+
export interface LabelStyleConfig {
|
|
125
|
+
backgroundColor?: string;
|
|
126
|
+
textColor?: string;
|
|
127
|
+
fontSize?: number;
|
|
128
|
+
fontFamily?: string;
|
|
129
|
+
backgroundRadius?: number;
|
|
130
|
+
connectorColor?: string;
|
|
131
|
+
connectorWidth?: number;
|
|
132
|
+
connectorStemLength?: number;
|
|
133
|
+
offsetX?: number;
|
|
134
|
+
offsetY?: number;
|
|
135
|
+
}
|
|
136
|
+
export interface LabelTypeConfig extends LabelStyleConfig {
|
|
137
|
+
fields?: LabelFieldConfig[];
|
|
138
|
+
style?: LabelStyleConfig;
|
|
139
|
+
maxCameraHeight?: number;
|
|
140
|
+
maxCount?: number;
|
|
141
|
+
}
|
|
142
|
+
export interface NameplateContext {
|
|
143
|
+
id: string;
|
|
144
|
+
type: string;
|
|
145
|
+
data: import('../data/types').TargetData | undefined;
|
|
146
|
+
cameraHeight: number;
|
|
147
|
+
distance?: number;
|
|
148
|
+
count: number;
|
|
149
|
+
}
|
|
150
|
+
export interface LabelConfig {
|
|
151
|
+
enabled?: boolean;
|
|
152
|
+
maxCount?: number;
|
|
153
|
+
maxCameraHeight?: number;
|
|
154
|
+
maxDistance?: number;
|
|
155
|
+
fields?: LabelFieldConfig[];
|
|
156
|
+
byType?: Record<string, LabelTypeConfig>;
|
|
157
|
+
resolve?: (ctx: NameplateContext) => string | string[] | null | undefined;
|
|
158
|
+
backgroundColor?: string;
|
|
159
|
+
textColor?: string;
|
|
160
|
+
fontSize?: number;
|
|
161
|
+
fontFamily?: string;
|
|
162
|
+
backgroundRadius?: number;
|
|
163
|
+
overlapThreshold?: number;
|
|
164
|
+
occlusionGraceMs?: number;
|
|
165
|
+
offsetX?: number;
|
|
166
|
+
offsetY?: number;
|
|
167
|
+
connectorColor?: string;
|
|
168
|
+
connectorWidth?: number;
|
|
169
|
+
connectorStemLength?: number;
|
|
170
|
+
showFieldLabels?: boolean;
|
|
171
|
+
}
|
|
172
|
+
export type ResolvedLabelConfig = Required<Omit<LabelConfig, "maxDistance" | "byType" | "resolve">> & Pick<LabelConfig, "maxDistance" | "byType" | "resolve">;
|
|
173
|
+
export interface FrameConfig {
|
|
174
|
+
maxScanPerFrame?: number;
|
|
175
|
+
maxScanMs?: number;
|
|
176
|
+
maxIngestPerFrame?: number;
|
|
177
|
+
maxLowModelRenderItems?: number;
|
|
178
|
+
maxModelRenderItems?: number;
|
|
179
|
+
suspendRenderUpdateWhileMoving?: boolean;
|
|
180
|
+
heatmapAboveHeight?: number;
|
|
181
|
+
heatmapBelowHeight?: number;
|
|
182
|
+
heatmapSwitchSettleMs?: number;
|
|
183
|
+
heatmapUpdateIntervalMs?: number;
|
|
184
|
+
}
|
|
185
|
+
export interface DataPipelineConfig {
|
|
186
|
+
commitIntervalMs?: number;
|
|
187
|
+
leading?: boolean;
|
|
188
|
+
worker?: boolean;
|
|
189
|
+
}
|
|
190
|
+
export type QualityTier = "high" | "medium" | "low" | "potato";
|
|
191
|
+
export interface AdaptiveConfig {
|
|
192
|
+
enabled?: boolean;
|
|
193
|
+
dynamic?: boolean;
|
|
194
|
+
minFps?: number;
|
|
195
|
+
upFps?: number;
|
|
196
|
+
windowMs?: number;
|
|
197
|
+
baseTier?: QualityTier;
|
|
198
|
+
}
|
|
199
|
+
export interface SceneConfig {
|
|
200
|
+
nodeTypes: NodeTypeConfig[];
|
|
201
|
+
lod?: LodConfig;
|
|
202
|
+
pool?: PoolConfig;
|
|
203
|
+
animatedPool?: AnimatedPoolConfig;
|
|
204
|
+
updateFps?: number;
|
|
205
|
+
predictSeconds?: number;
|
|
206
|
+
predictFitSeconds?: number;
|
|
207
|
+
fadeMs?: number;
|
|
208
|
+
masterHideHeight?: number;
|
|
209
|
+
merge?: MergeConfig;
|
|
210
|
+
pick?: PickConfig;
|
|
211
|
+
cull?: CullConfig;
|
|
212
|
+
horizonCull?: HorizonCullConfig;
|
|
213
|
+
label?: LabelConfig;
|
|
214
|
+
frame?: FrameConfig;
|
|
215
|
+
data?: DataPipelineConfig;
|
|
216
|
+
adaptive?: AdaptiveConfig;
|
|
217
|
+
/** 点档单目标用"地表实例化有向符号"渲染(默认 false=billboard)。 */
|
|
218
|
+
groundSymbols?: boolean;
|
|
219
|
+
/** 地表符号像素大小(恒定屏幕尺寸)。 */
|
|
220
|
+
groundSymbolPixelSize?: number;
|
|
221
|
+
}
|
|
222
|
+
export declare const DEFAULT_LOD: LodConfig;
|
|
223
|
+
export declare const DEFAULT_POOL: PoolConfig;
|
|
224
|
+
export declare const DEFAULT_ANIMATED_POOL: AnimatedPoolConfig;
|
|
225
|
+
export declare const DEFAULT_SCENE: Required<Pick<SceneConfig, "updateFps" | "predictSeconds" | "predictFitSeconds" | "masterHideHeight">>;
|
|
226
|
+
export interface ResolvedMergeConfig {
|
|
227
|
+
enabled: boolean;
|
|
228
|
+
mode: "viewport" | "global";
|
|
229
|
+
maxVisible: number;
|
|
230
|
+
globalRootLimit: number;
|
|
231
|
+
globalMaxLevels: number;
|
|
232
|
+
globalRebuildIntervalMs: number;
|
|
233
|
+
globalViewportHeight: number;
|
|
234
|
+
cameraMergeBaseHeight: number;
|
|
235
|
+
cameraMergeStepHeight: number;
|
|
236
|
+
cameraMergeStepRadius: number;
|
|
237
|
+
innerRatio: number;
|
|
238
|
+
radii: number[];
|
|
239
|
+
byType: boolean;
|
|
240
|
+
minSecrecy?: number;
|
|
241
|
+
bucketCellDeg: number;
|
|
242
|
+
}
|
|
243
|
+
export interface ResolvedConfig {
|
|
244
|
+
nodeTypes: Map<string, NodeTypeConfig>;
|
|
245
|
+
renderTypes: ResolvedNodeTypeConfig[];
|
|
246
|
+
lod: LodConfig;
|
|
247
|
+
poolSize: number;
|
|
248
|
+
animatedCapacity: number;
|
|
249
|
+
updateFps: number;
|
|
250
|
+
predictSeconds: number;
|
|
251
|
+
predictFitSeconds: number;
|
|
252
|
+
fadeMs: number;
|
|
253
|
+
masterHideHeight: number;
|
|
254
|
+
merge: ResolvedMergeConfig | undefined;
|
|
255
|
+
pick: Required<PickConfig>;
|
|
256
|
+
cull: Required<CullConfig>;
|
|
257
|
+
horizonCull: Required<HorizonCullConfig>;
|
|
258
|
+
label: ResolvedLabelConfig;
|
|
259
|
+
frame: Required<FrameConfig>;
|
|
260
|
+
data: Required<DataPipelineConfig>;
|
|
261
|
+
adaptive: Required<AdaptiveConfig>;
|
|
262
|
+
groundSymbols: boolean;
|
|
263
|
+
groundSymbolPixelSize: number;
|
|
264
|
+
}
|
|
265
|
+
export declare function resolveConfig(config: SceneConfig): ResolvedConfig;
|
|
266
|
+
export declare function resolveLabelConfig(label: LabelConfig | undefined): ResolvedLabelConfig;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type Handler<T> = (payload: T) => void;
|
|
2
|
+
export declare class EventEmitter<EventMap extends object> {
|
|
3
|
+
private readonly handlers;
|
|
4
|
+
on<K extends keyof EventMap>(event: K, handler: Handler<EventMap[K]>): () => void;
|
|
5
|
+
off<K extends keyof EventMap>(event: K, handler: Handler<EventMap[K]>): void;
|
|
6
|
+
emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void;
|
|
7
|
+
clear(): void;
|
|
8
|
+
}
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { Cartesian3, Viewer } from 'cesium';
|
|
2
|
+
import { LabelConfig, ModelAssetConfig, SceneConfig, TargetDomain } from '../config/types';
|
|
3
|
+
import { IncrementalPayload, StandardTargetData } from '../data/types';
|
|
4
|
+
import { TrackManagerApi } from '../track/types';
|
|
5
|
+
import { TargetSnapshot } from '../worker/protocol';
|
|
6
|
+
import { MultiTargetScene } from './MultiTargetScene';
|
|
7
|
+
|
|
8
|
+
export interface MultiTargetTypeConfig {
|
|
9
|
+
/** 目标类型,数据中的 type 必须命中这里的某一项。 */
|
|
10
|
+
type: string;
|
|
11
|
+
name?: string;
|
|
12
|
+
targetDomain?: TargetDomain;
|
|
13
|
+
forceHighModelInLowLod?: boolean;
|
|
14
|
+
/** 图标路径,建议使用黑白 mask 图;框架会在 canvas 中转成可染色图标。 */
|
|
15
|
+
iconPath: string;
|
|
16
|
+
defaultColor?: string;
|
|
17
|
+
highModel?: ModelAssetConfig;
|
|
18
|
+
lowModel?: ModelAssetConfig;
|
|
19
|
+
highModelUrl?: string;
|
|
20
|
+
lowModelUrl?: string;
|
|
21
|
+
pointPixelSize?: number;
|
|
22
|
+
pointHeadingOffset?: number;
|
|
23
|
+
scale?: number;
|
|
24
|
+
modelHeadingOffset?: number;
|
|
25
|
+
modelPitchOffset?: number;
|
|
26
|
+
modelRollOffset?: number;
|
|
27
|
+
smoothMove?: boolean;
|
|
28
|
+
/** 相机高度低于/等于该值时开启平滑,默认 25000 米。 */
|
|
29
|
+
smoothMoveMinCameraHeight?: number;
|
|
30
|
+
/** 单次位置变化的移动动画时长,默认 400ms。 */
|
|
31
|
+
moveAnimationDurationMs?: number;
|
|
32
|
+
/** 单次位置变化的移动动画时长,默认 400ms。 */
|
|
33
|
+
smoothMoveDurationMs?: number;
|
|
34
|
+
predict?: boolean;
|
|
35
|
+
predictMove?: boolean;
|
|
36
|
+
/** 相机高度低于/等于该值时开启预测,默认 25000 米。 */
|
|
37
|
+
predictMinCameraHeight?: number;
|
|
38
|
+
/** 预测窗口秒数;未设置时使用 scene.predictSeconds。 */
|
|
39
|
+
predictSeconds?: number;
|
|
40
|
+
/** 新数据到来后的航线拟合秒数;未设置时使用 scene.predictFitSeconds。 */
|
|
41
|
+
predictFitSeconds?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface MultiTargetFrameworkOptions {
|
|
44
|
+
targetTypes: MultiTargetTypeConfig[];
|
|
45
|
+
scene?: Omit<SceneConfig, "nodeTypes">;
|
|
46
|
+
}
|
|
47
|
+
export interface MultiTargetFrameworkApi {
|
|
48
|
+
readonly tracks: TrackManagerApi;
|
|
49
|
+
/** 引擎就绪信号:可在加载依赖底座的其它组件前 await。 */
|
|
50
|
+
readonly ready: Promise<void>;
|
|
51
|
+
addTarget(target: StandardTargetData): StandardTargetData;
|
|
52
|
+
updateTarget(target: StandardTargetData): StandardTargetData;
|
|
53
|
+
setTargetData(targets: StandardTargetData[]): void;
|
|
54
|
+
upsertTargetData(targets: StandardTargetData[]): void;
|
|
55
|
+
removeTargetData(ids: string[]): void;
|
|
56
|
+
applyTargetIncremental(payload: IncrementalPayload): void;
|
|
57
|
+
setTargetColor(id: TargetIdInput, color: string, options?: TargetStyleOptions): void;
|
|
58
|
+
setTargetGlow(id: TargetIdInput, enabled: boolean, color?: string, options?: TargetStyleOptions): void;
|
|
59
|
+
hideTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
60
|
+
showTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
61
|
+
disappearTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
62
|
+
appearTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
63
|
+
setNameplateConfig(config: LabelConfig): void;
|
|
64
|
+
selectTarget(id: string, options?: TargetStyleOptions): Promise<TargetSnapshot | null>;
|
|
65
|
+
selectTargets(ids: readonly string[], options?: TargetStyleOptions): Promise<TargetSnapshot[]>;
|
|
66
|
+
unselectTarget(id: string): void;
|
|
67
|
+
clearSelection(): void;
|
|
68
|
+
boxTarget(id: TargetIdInput, enabled?: boolean, options?: TargetStyleOptions): void;
|
|
69
|
+
unboxTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
70
|
+
locateTarget(id: string, options?: LocateTargetOptions): Promise<TargetSnapshot | null>;
|
|
71
|
+
registerContextMenuItem(item: ContextMenuItemRegistration): () => void;
|
|
72
|
+
showContextMenu(ctx: ContextMenuContext): Promise<void>;
|
|
73
|
+
closeContextMenu(): void;
|
|
74
|
+
destroy(): void;
|
|
75
|
+
}
|
|
76
|
+
export type ContextMenuTargetKind = "target" | "ground" | "site";
|
|
77
|
+
export interface ContextMenuTargetTarget {
|
|
78
|
+
kind: "target";
|
|
79
|
+
id: string;
|
|
80
|
+
type: string;
|
|
81
|
+
data: TargetSnapshot;
|
|
82
|
+
}
|
|
83
|
+
export interface ContextMenuGroundTarget {
|
|
84
|
+
kind: "ground";
|
|
85
|
+
lon: number;
|
|
86
|
+
lat: number;
|
|
87
|
+
height: number;
|
|
88
|
+
}
|
|
89
|
+
export interface ContextMenuSiteTarget {
|
|
90
|
+
kind: "site";
|
|
91
|
+
id: string;
|
|
92
|
+
siteType: string;
|
|
93
|
+
data?: unknown;
|
|
94
|
+
}
|
|
95
|
+
export type ContextMenuTarget = ContextMenuTargetTarget | ContextMenuGroundTarget | ContextMenuSiteTarget;
|
|
96
|
+
export interface ContextMenuContext {
|
|
97
|
+
screenX: number;
|
|
98
|
+
screenY: number;
|
|
99
|
+
cartesian?: Cartesian3;
|
|
100
|
+
target: ContextMenuTarget;
|
|
101
|
+
viewer: Viewer;
|
|
102
|
+
scene: MultiTargetScene;
|
|
103
|
+
framework: MultiTargetFramework;
|
|
104
|
+
}
|
|
105
|
+
export interface ContextMenuItemRegistration {
|
|
106
|
+
key: string;
|
|
107
|
+
label: string;
|
|
108
|
+
targetKinds?: readonly ContextMenuTargetKind[];
|
|
109
|
+
order?: number;
|
|
110
|
+
visible?: (ctx: ContextMenuContext) => boolean;
|
|
111
|
+
onClick: (ctx: ContextMenuContext) => void | Promise<void>;
|
|
112
|
+
}
|
|
113
|
+
export interface LocateTargetOptions {
|
|
114
|
+
/** 相机离目标的距离,单位米;优先于 height。 */
|
|
115
|
+
range?: number;
|
|
116
|
+
/** @deprecated 使用 range;保留该字段兼容旧调用。 */
|
|
117
|
+
height?: number;
|
|
118
|
+
duration?: number;
|
|
119
|
+
pitch?: number;
|
|
120
|
+
heading?: number;
|
|
121
|
+
}
|
|
122
|
+
export type TargetIdInput = string | readonly string[];
|
|
123
|
+
export interface TargetStyleOptions {
|
|
124
|
+
clearBefore?: boolean;
|
|
125
|
+
clearBefor?: boolean;
|
|
126
|
+
}
|
|
127
|
+
export declare class MultiTargetFramework implements MultiTargetFrameworkApi {
|
|
128
|
+
readonly scene: MultiTargetScene;
|
|
129
|
+
readonly viewer: Viewer;
|
|
130
|
+
readonly tracks: TrackManagerApi;
|
|
131
|
+
/** 引擎就绪信号(转发自 scene.ready):可在加载依赖底座的其它组件前 await。 */
|
|
132
|
+
readonly ready: Promise<void>;
|
|
133
|
+
private boxedTargetIds;
|
|
134
|
+
private readonly contextMenuItems;
|
|
135
|
+
private readonly contextMenuRoot;
|
|
136
|
+
private readonly contextMenuList;
|
|
137
|
+
private readonly removeSceneContextMenuListener;
|
|
138
|
+
private readonly eventBusBinding;
|
|
139
|
+
private readonly handleDocumentPointerDownBound;
|
|
140
|
+
private readonly handleKeyDownBound;
|
|
141
|
+
private activeContextMenuContext;
|
|
142
|
+
constructor(viewer: Viewer, options: MultiTargetFrameworkOptions);
|
|
143
|
+
setData(targets: StandardTargetData[]): void;
|
|
144
|
+
upsert(targets: StandardTargetData[]): void;
|
|
145
|
+
remove(ids: string[]): void;
|
|
146
|
+
addTarget(target: StandardTargetData): StandardTargetData;
|
|
147
|
+
updateTarget(target: StandardTargetData): StandardTargetData;
|
|
148
|
+
setTargetData(targets: StandardTargetData[]): void;
|
|
149
|
+
upsertTargetData(targets: StandardTargetData[]): void;
|
|
150
|
+
removeTargetData(ids: string[]): void;
|
|
151
|
+
applyTargetIncremental(payload: IncrementalPayload): void;
|
|
152
|
+
setTargetColor(id: TargetIdInput, color: string, options?: TargetStyleOptions): void;
|
|
153
|
+
setTargetGlow(id: TargetIdInput, enabled?: boolean, color?: string, options?: TargetStyleOptions): void;
|
|
154
|
+
hideTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
155
|
+
showTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
156
|
+
disappearTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
157
|
+
appearTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
158
|
+
setNameplateConfig(config: LabelConfig): void;
|
|
159
|
+
selectTarget(id: string, options?: TargetStyleOptions): Promise<TargetSnapshot | null>;
|
|
160
|
+
selectTargets(ids: readonly string[], options?: TargetStyleOptions): Promise<TargetSnapshot[]>;
|
|
161
|
+
unselectTarget(id: string): void;
|
|
162
|
+
clearSelection(): void;
|
|
163
|
+
boxTarget(id: TargetIdInput, enabled?: boolean, options?: TargetStyleOptions): void;
|
|
164
|
+
unboxTarget(id: TargetIdInput, options?: TargetStyleOptions): void;
|
|
165
|
+
locateTarget(id: string, options?: LocateTargetOptions): Promise<TargetSnapshot | null>;
|
|
166
|
+
registerContextMenuItem(item: ContextMenuItemRegistration): () => void;
|
|
167
|
+
showContextMenu(ctx: ContextMenuContext): Promise<void>;
|
|
168
|
+
closeContextMenu(): void;
|
|
169
|
+
destroy(): void;
|
|
170
|
+
/**
|
|
171
|
+
* 异步工厂:构造实例并等待引擎就绪后再 resolve。
|
|
172
|
+
* 适合「初始化完成后再加载依赖底座的其它组件」的接入方:`const mt = await MultiTargetFramework.create(viewer, options);`
|
|
173
|
+
* 若需在就绪前挂事件/调方法,请改用同步 `new MultiTargetFramework(...)` 再 `await mt.ready`。
|
|
174
|
+
*/
|
|
175
|
+
static create(viewer: Viewer, options: MultiTargetFrameworkOptions): Promise<MultiTargetFramework>;
|
|
176
|
+
private handleSceneContextMenu;
|
|
177
|
+
private toContextMenuContext;
|
|
178
|
+
private renderContextMenu;
|
|
179
|
+
private resolveVisibleContextMenuItems;
|
|
180
|
+
private repositionContextMenu;
|
|
181
|
+
private handleDocumentPointerDown;
|
|
182
|
+
private handleDocumentKeyDown;
|
|
183
|
+
}
|
|
184
|
+
export declare function createMultiTargetFramework(viewer: Viewer, options: MultiTargetFrameworkOptions): Promise<MultiTargetFramework>;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { Cartesian3, Viewer } from 'cesium';
|
|
2
|
+
import { LabelConfig, ResolvedConfig, SceneConfig } from '../config/types';
|
|
3
|
+
import { DiffResult, IncrementalPayload, PackedDiffResult, PackedTargetData, TargetData } from '../data/types';
|
|
4
|
+
import { EventEmitter } from './EventEmitter';
|
|
5
|
+
import { ModelPoolRenderer, RenderedTargetFrame } from '../render/ModelPoolRenderer';
|
|
6
|
+
import { PointCloudRenderer } from '../render/PointCloudRenderer';
|
|
7
|
+
import { InstancedSymbolRenderer } from '../render/InstancedSymbolRenderer';
|
|
8
|
+
import { SelectionOverlayRenderer } from '../render/SelectionOverlayRenderer';
|
|
9
|
+
import { TrackManager } from '../track/TrackManager';
|
|
10
|
+
import { TargetSnapshot, TargetStylePatch } from '../worker/protocol';
|
|
11
|
+
|
|
12
|
+
export type TickPerfEvent = {
|
|
13
|
+
phase: "tick-slow";
|
|
14
|
+
at: number;
|
|
15
|
+
totalMs: number;
|
|
16
|
+
flushMs: number;
|
|
17
|
+
ingestMs: number;
|
|
18
|
+
scanMs: number;
|
|
19
|
+
visualMs: number;
|
|
20
|
+
motionMs: number;
|
|
21
|
+
renderMs: number;
|
|
22
|
+
rendered: number;
|
|
23
|
+
};
|
|
24
|
+
export type ScenePerfEvent = {
|
|
25
|
+
phase: "input";
|
|
26
|
+
kind: "packed" | "set-data" | "incremental";
|
|
27
|
+
upserts: number;
|
|
28
|
+
removes: number;
|
|
29
|
+
pendingBatches: number;
|
|
30
|
+
} | {
|
|
31
|
+
phase: "worker-submit";
|
|
32
|
+
full: number;
|
|
33
|
+
batches: number;
|
|
34
|
+
upserts: number;
|
|
35
|
+
submitMs: number;
|
|
36
|
+
} | {
|
|
37
|
+
phase: "worker-done";
|
|
38
|
+
added: number;
|
|
39
|
+
updated: number;
|
|
40
|
+
removed: number;
|
|
41
|
+
size: number;
|
|
42
|
+
computeMs: number;
|
|
43
|
+
roundTripMs: number;
|
|
44
|
+
} | {
|
|
45
|
+
phase: "worker-fallback";
|
|
46
|
+
full: number;
|
|
47
|
+
batches: number;
|
|
48
|
+
} | TickPerfEvent | {
|
|
49
|
+
phase: "sync-commit";
|
|
50
|
+
added: number;
|
|
51
|
+
updated: number;
|
|
52
|
+
removed: number;
|
|
53
|
+
};
|
|
54
|
+
export interface PickedNodeLike {
|
|
55
|
+
id: string;
|
|
56
|
+
type: string;
|
|
57
|
+
data: TargetData;
|
|
58
|
+
}
|
|
59
|
+
export interface SceneEvents {
|
|
60
|
+
perf: ScenePerfEvent;
|
|
61
|
+
dirty: DiffResult;
|
|
62
|
+
packedDirty: PackedDiffResult;
|
|
63
|
+
pick: PickedNodeLike | null;
|
|
64
|
+
hover: PickedNodeLike | null;
|
|
65
|
+
selection: PickedNodeLike[];
|
|
66
|
+
contextmenu: SceneContextMenuPayload | null;
|
|
67
|
+
}
|
|
68
|
+
export interface SceneContextMenuPayload {
|
|
69
|
+
kind: "target" | "ground";
|
|
70
|
+
target: PickedNodeLike | null;
|
|
71
|
+
screenX: number;
|
|
72
|
+
screenY: number;
|
|
73
|
+
cartesian?: Cartesian3;
|
|
74
|
+
lon?: number;
|
|
75
|
+
lat?: number;
|
|
76
|
+
height?: number;
|
|
77
|
+
}
|
|
78
|
+
export interface SceneNodeStats {
|
|
79
|
+
visibleCount: number;
|
|
80
|
+
bufferCount: number;
|
|
81
|
+
renderedCount: number;
|
|
82
|
+
clusterCount: number;
|
|
83
|
+
lastMergeRadius: number;
|
|
84
|
+
pointRenderCount: number;
|
|
85
|
+
mergedPointRenderCount: number;
|
|
86
|
+
plainPointRenderCount: number;
|
|
87
|
+
lowModelRenderCount: number;
|
|
88
|
+
highModelRenderCount: number;
|
|
89
|
+
mergedLowModelRenderCount: number;
|
|
90
|
+
mergedHighModelRenderCount: number;
|
|
91
|
+
forcedPointMode: boolean;
|
|
92
|
+
level: number;
|
|
93
|
+
outsideLevel: number;
|
|
94
|
+
}
|
|
95
|
+
export type WrappedScene = MultiTargetScene & Viewer;
|
|
96
|
+
export { type ResolvedConfig };
|
|
97
|
+
export declare class MultiTargetScene extends EventEmitter<SceneEvents> {
|
|
98
|
+
private readonly viewer;
|
|
99
|
+
readonly config: ResolvedConfig;
|
|
100
|
+
readonly render: PointCloudRenderer;
|
|
101
|
+
readonly models: ModelPoolRenderer;
|
|
102
|
+
readonly symbols?: InstancedSymbolRenderer;
|
|
103
|
+
readonly selection: SelectionOverlayRenderer;
|
|
104
|
+
readonly tracks: TrackManager;
|
|
105
|
+
/** 引擎就绪信号:内部 Web Worker 完成 init 握手后 resolve。可在加载依赖底座的其它组件前 await。 */
|
|
106
|
+
readonly ready: Promise<void>;
|
|
107
|
+
readonly nodes: SceneNodeStats;
|
|
108
|
+
readonly quality: {
|
|
109
|
+
tier: "high";
|
|
110
|
+
};
|
|
111
|
+
private readonly worker;
|
|
112
|
+
private resolveReady;
|
|
113
|
+
private readyResolved;
|
|
114
|
+
private readonly commitIntervalMs;
|
|
115
|
+
private commitTimer;
|
|
116
|
+
private rafId;
|
|
117
|
+
private paused;
|
|
118
|
+
private destroyed;
|
|
119
|
+
private total;
|
|
120
|
+
private commitRequestId;
|
|
121
|
+
private viewportRequestId;
|
|
122
|
+
private dataRevision;
|
|
123
|
+
private readonly viewportRequestRevisions;
|
|
124
|
+
private readonly globalViewportRequestIds;
|
|
125
|
+
private globalViewportRevision;
|
|
126
|
+
private targetQueryRequestId;
|
|
127
|
+
private readonly targetQueryResolvers;
|
|
128
|
+
private viewportInFlight;
|
|
129
|
+
private viewportDirty;
|
|
130
|
+
private lastCommitSubmitAt;
|
|
131
|
+
private lastFrameAt;
|
|
132
|
+
private lastPredictionViewportAt;
|
|
133
|
+
private lastSymbolsUpdateAt;
|
|
134
|
+
private stagedUpserts;
|
|
135
|
+
private stagedBatches;
|
|
136
|
+
private readonly removeCameraListener;
|
|
137
|
+
private readonly inputHandler;
|
|
138
|
+
private readonly selectedIds;
|
|
139
|
+
private readonly selectedTargets;
|
|
140
|
+
private hoverRequestSerial;
|
|
141
|
+
private pickRequestSerial;
|
|
142
|
+
private contextMenuRequestSerial;
|
|
143
|
+
private hoverPickPosition;
|
|
144
|
+
private hoverPickRafId;
|
|
145
|
+
private lastHoverPickAt;
|
|
146
|
+
private lastHoverPointerSample;
|
|
147
|
+
private hoverPointerSpeedPxPerMs;
|
|
148
|
+
private pointerButtonsMask;
|
|
149
|
+
private wheelSuppressPickUntil;
|
|
150
|
+
private cameraMoving;
|
|
151
|
+
private cameraMoveTrailingTimer;
|
|
152
|
+
private wheelSuppressResetTimer;
|
|
153
|
+
private cameraViewportThrottleTimer;
|
|
154
|
+
private lastCameraViewportAt;
|
|
155
|
+
private lastHoverId;
|
|
156
|
+
private readonly hoverTargetCache;
|
|
157
|
+
private readonly labelDataById;
|
|
158
|
+
private latestRenderPacket;
|
|
159
|
+
private hoverPickIndex;
|
|
160
|
+
private hoverPickWarmupRafId;
|
|
161
|
+
private cameraRevision;
|
|
162
|
+
private labelConfig;
|
|
163
|
+
constructor(viewer: Viewer, config: SceneConfig);
|
|
164
|
+
get targetCount(): number;
|
|
165
|
+
setData(targets: TargetData[]): void;
|
|
166
|
+
applyIncremental(payload: IncrementalPayload): void;
|
|
167
|
+
applyRealtimeUpsert(targets: TargetData[]): void;
|
|
168
|
+
applyRealtimeRemove(ids: string[]): void;
|
|
169
|
+
applyPacked(payload: PackedTargetData): void;
|
|
170
|
+
applyTargetStyle(patches: TargetStylePatch[]): void;
|
|
171
|
+
setBoxedTargetIds(ids: readonly string[]): void;
|
|
172
|
+
setLabelConfig(config: LabelConfig): void;
|
|
173
|
+
selectTarget(id: string, clearBefore?: boolean): Promise<PickedNodeLike | null>;
|
|
174
|
+
selectTargets(ids: readonly string[], clearBefore?: boolean): Promise<PickedNodeLike[]>;
|
|
175
|
+
unselectTarget(id: string): void;
|
|
176
|
+
clearSelection(emit?: boolean): void;
|
|
177
|
+
flushNow(): void;
|
|
178
|
+
getTargetSnapshot(id: string): Promise<TargetSnapshot | null>;
|
|
179
|
+
pause(): void;
|
|
180
|
+
resume(): void;
|
|
181
|
+
destroy(): void;
|
|
182
|
+
private startCommitLoop;
|
|
183
|
+
private startRenderLoop;
|
|
184
|
+
private commitNow;
|
|
185
|
+
private requestViewportThrottled;
|
|
186
|
+
private requestViewport;
|
|
187
|
+
private handleWorkerMessage;
|
|
188
|
+
private applyRenderPacket;
|
|
189
|
+
private updateSymbolsThrottled;
|
|
190
|
+
private applyStats;
|
|
191
|
+
private applyActualRenderStats;
|
|
192
|
+
private shouldRefreshPredictionViewport;
|
|
193
|
+
private handlePickAt;
|
|
194
|
+
private handleContextMenuAt;
|
|
195
|
+
private bindHoverSuppressionInput;
|
|
196
|
+
private scheduleHoverPick;
|
|
197
|
+
private flushHoverPick;
|
|
198
|
+
private handleHoverAt;
|
|
199
|
+
private pickIndexedTargetId;
|
|
200
|
+
private ensureHoverPickIndex;
|
|
201
|
+
private pickTargetId;
|
|
202
|
+
getRenderedTargetFrame(id: string, result?: Cartesian3): RenderedTargetFrame | undefined;
|
|
203
|
+
getRenderedTargetPosition(id: string, result?: Cartesian3): Cartesian3 | null;
|
|
204
|
+
private pickGroundCartesian;
|
|
205
|
+
private shouldSkipHoverPick;
|
|
206
|
+
private noteHoverPointerSample;
|
|
207
|
+
private cancelPendingHoverPick;
|
|
208
|
+
private onViewManipulationStart;
|
|
209
|
+
private noteWheelInteraction;
|
|
210
|
+
private noteCameraMovement;
|
|
211
|
+
private scheduleHoverPickIndexWarmup;
|
|
212
|
+
private cacheHoverTarget;
|
|
213
|
+
private getPickedNode;
|
|
214
|
+
private replaceLabelData;
|
|
215
|
+
private applyLabelIncremental;
|
|
216
|
+
private upsertLabelData;
|
|
217
|
+
private removeLabelData;
|
|
218
|
+
private nameplateText;
|
|
219
|
+
private setSelectedTargetIds;
|
|
220
|
+
private emitSelection;
|
|
221
|
+
private isModelRenderActive;
|
|
222
|
+
private currentBounds;
|
|
223
|
+
private postWithTiming;
|
|
224
|
+
}
|