@lumikmz/kmz-file 0.2.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/dist/index.mjs ADDED
@@ -0,0 +1,1140 @@
1
+ import wasmInit, { initSync as initSync$1, jsonToKmz, kmzToJson } from "./wasm_kmz.js";
2
+ import { KmzError, degrees, meters, metersPerSecond } from "@lumikmz/kmz";
3
+ //#region src/init.ts
4
+ let initialized;
5
+ /**
6
+ * Initialize the underlying WASM module. Idempotent — repeated calls return the
7
+ * original promise. Pass `input` to control how the module is loaded (e.g. a
8
+ * URL, fetch Response, or pre-fetched bytes). With no arguments,
9
+ * wasm-bindgen uses its default loader.
10
+ */
11
+ function init(input) {
12
+ if (!initialized) initialized = wasmInit(input);
13
+ return initialized;
14
+ }
15
+ /** Synchronous WASM init. Accepts pre-fetched bytes or a compiled module. */
16
+ function initSync(input) {
17
+ return initSync$1(input);
18
+ }
19
+ //#endregion
20
+ //#region src/codec/utils.ts
21
+ function toArray(v) {
22
+ if (v == null) return [];
23
+ return Array.isArray(v) ? v : [v];
24
+ }
25
+ function fromArray(arr) {
26
+ if (arr.length === 1) return arr[0];
27
+ return arr;
28
+ }
29
+ function parseNum(s, field) {
30
+ if (s == null) throw new KmzError(`Missing required field "${field}"`);
31
+ const n = Number(s);
32
+ if (Number.isNaN(n)) throw new KmzError(`Expected number for "${field}", got "${s}"`);
33
+ return n;
34
+ }
35
+ function parseOptNum(s) {
36
+ if (s == null) return void 0;
37
+ const n = Number(s);
38
+ return Number.isNaN(n) ? void 0 : n;
39
+ }
40
+ function parseBool(s, field) {
41
+ if (s === "1") return true;
42
+ if (s === "0") return false;
43
+ throw new KmzError(`Expected "0" or "1" for "${field}", got "${String(s)}"`);
44
+ }
45
+ function parseOptBool(s) {
46
+ if (s == null) return void 0;
47
+ if (s === "1") return true;
48
+ if (s === "0") return false;
49
+ }
50
+ const formatBool = (b) => b ? "1" : "0";
51
+ /** Parse KML coordinates string `"lng,lat"` (KML order — lon first). */
52
+ function parseLngLat(coords) {
53
+ const parts = coords.trim().split(",");
54
+ if (parts.length < 2) throw new KmzError(`Invalid KML coordinates: "${coords}"`);
55
+ const lng = Number(parts[0]);
56
+ const lat = Number(parts[1]);
57
+ if (Number.isNaN(lng) || Number.isNaN(lat)) throw new KmzError(`Invalid KML coordinates: "${coords}"`);
58
+ return {
59
+ lng,
60
+ lat
61
+ };
62
+ }
63
+ const formatLngLat = (p) => `${p.lng},${p.lat}`;
64
+ /** Parse DJI composite `"lat,lng,height"` string (LAT FIRST). */
65
+ function parseLngLatHeight(s) {
66
+ const parts = s.trim().split(",");
67
+ if (parts.length < 3) throw new KmzError(`Invalid lat,lng,height triple: "${s}"`);
68
+ const lat = Number(parts[0]);
69
+ const lng = Number(parts[1]);
70
+ const height = Number(parts[2]);
71
+ if (Number.isNaN(lat) || Number.isNaN(lng) || Number.isNaN(height)) throw new KmzError(`Invalid lat,lng,height triple: "${s}"`);
72
+ return {
73
+ lng,
74
+ lat,
75
+ height: meters(height)
76
+ };
77
+ }
78
+ const formatLngLatHeight = (p) => `${p.lat},${p.lng},${p.height}`;
79
+ /** Parse comma- or semicolon-separated lens index list. Strips empty tokens. */
80
+ function parseLensList(s) {
81
+ if (!s) return [];
82
+ return s.split(/[;,]/).map((t) => t.trim()).filter(Boolean);
83
+ }
84
+ /** Spec says comma-separated, but DJI tools accept either; we emit commas to match spec. */
85
+ const formatLensList = (xs) => xs.join(",");
86
+ //#endregion
87
+ //#region src/codec/encode-action.ts
88
+ /**
89
+ * Encode an Action's `actionActuatorFuncParam` block. Each branch lays out the
90
+ * params with `wpml:` prefixes per the spec; optional fields are omitted when
91
+ * undefined.
92
+ */
93
+ function encodeActionParams(action) {
94
+ const a = action;
95
+ switch (a.actionActuatorFunc) {
96
+ case "takePhoto": {
97
+ const p = a.actionActuatorFuncParam;
98
+ return {
99
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
100
+ ...p.fileSuffix !== void 0 ? { "wpml:fileSuffix": p.fileSuffix } : {},
101
+ ...p.payloadLensIndex && p.payloadLensIndex.length > 0 ? { "wpml:payloadLensIndex": formatLensList(p.payloadLensIndex) } : {},
102
+ "wpml:useGlobalPayloadLensIndex": formatBool(p.useGlobalPayloadLensIndex)
103
+ };
104
+ }
105
+ case "startRecord": {
106
+ const p = a.actionActuatorFuncParam;
107
+ return {
108
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
109
+ ...p.fileSuffix !== void 0 ? { "wpml:fileSuffix": p.fileSuffix } : {},
110
+ ...p.payloadLensIndex && p.payloadLensIndex.length > 0 ? { "wpml:payloadLensIndex": formatLensList(p.payloadLensIndex) } : {},
111
+ "wpml:useGlobalPayloadLensIndex": formatBool(p.useGlobalPayloadLensIndex)
112
+ };
113
+ }
114
+ case "stopRecord": {
115
+ const p = a.actionActuatorFuncParam;
116
+ return {
117
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
118
+ ...p.payloadLensIndex && p.payloadLensIndex.length > 0 ? { "wpml:payloadLensIndex": formatLensList(p.payloadLensIndex) } : {}
119
+ };
120
+ }
121
+ case "focus": {
122
+ const p = a.actionActuatorFuncParam;
123
+ return {
124
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
125
+ "wpml:isPointFocus": formatBool(p.isPointFocus),
126
+ "wpml:focusX": String(p.focusX),
127
+ "wpml:focusY": String(p.focusY),
128
+ ...p.focusRegionWidth !== void 0 ? { "wpml:focusRegionWidth": String(p.focusRegionWidth) } : {},
129
+ ...p.focusRegionHeight !== void 0 ? { "wpml:focusRegionHeight": String(p.focusRegionHeight) } : {},
130
+ ...p.isInfiniteFocus !== void 0 ? { "wpml:isInfiniteFocus": formatBool(p.isInfiniteFocus) } : {}
131
+ };
132
+ }
133
+ case "zoom": {
134
+ const p = a.actionActuatorFuncParam;
135
+ return {
136
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
137
+ "wpml:focalLength": String(p.focalLength)
138
+ };
139
+ }
140
+ case "customDirName": {
141
+ const p = a.actionActuatorFuncParam;
142
+ return {
143
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
144
+ "wpml:directoryName": p.directoryName
145
+ };
146
+ }
147
+ case "gimbalRotate": {
148
+ const p = a.actionActuatorFuncParam;
149
+ return {
150
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
151
+ "wpml:gimbalHeadingYawBase": p.gimbalHeadingYawBase,
152
+ "wpml:gimbalRotateMode": p.gimbalRotateMode,
153
+ "wpml:gimbalPitchRotateEnable": formatBool(p.gimbalPitchRotateEnable),
154
+ "wpml:gimbalPitchRotateAngle": String(p.gimbalPitchRotateAngle),
155
+ "wpml:gimbalRollRotateEnable": formatBool(p.gimbalRollRotateEnable),
156
+ "wpml:gimbalRollRotateAngle": String(p.gimbalRollRotateAngle),
157
+ "wpml:gimbalYawRotateEnable": formatBool(p.gimbalYawRotateEnable),
158
+ "wpml:gimbalYawRotateAngle": String(p.gimbalYawRotateAngle),
159
+ "wpml:gimbalRotateTimeEnable": formatBool(p.gimbalRotateTimeEnable),
160
+ "wpml:gimbalRotateTime": String(p.gimbalRotateTime)
161
+ };
162
+ }
163
+ case "rotateYaw": {
164
+ const p = a.actionActuatorFuncParam;
165
+ return {
166
+ "wpml:aircraftHeading": String(p.aircraftHeading),
167
+ ...p.aircraftPathMode ? { "wpml:aircraftPathMode": p.aircraftPathMode } : {}
168
+ };
169
+ }
170
+ case "hover": {
171
+ const p = a.actionActuatorFuncParam;
172
+ return { "wpml:hoverTime": String(p.hoverTime) };
173
+ }
174
+ case "gimbalEvenlyRotate": {
175
+ const p = a.actionActuatorFuncParam;
176
+ return {
177
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
178
+ "wpml:gimbalPitchRotateAngle": String(p.gimbalPitchRotateAngle)
179
+ };
180
+ }
181
+ case "accurateShoot": {
182
+ const p = a.actionActuatorFuncParam;
183
+ return {
184
+ "wpml:gimbalPitchRotateAngle": String(p.gimbalPitchRotateAngle),
185
+ "wpml:gimbalYawRotateAngle": String(p.gimbalYawRotateAngle),
186
+ "wpml:focusX": String(p.focusX),
187
+ "wpml:focusY": String(p.focusY),
188
+ "wpml:focusRegionWidth": String(p.focusRegionWidth),
189
+ "wpml:focusRegionHeight": String(p.focusRegionHeight),
190
+ "wpml:focalLength": String(p.focalLength),
191
+ "wpml:aircraftHeading": String(p.aircraftHeading),
192
+ "wpml:accurateFrameValid": formatBool(p.accurateFrameValid),
193
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
194
+ "wpml:payloadLensIndex": formatLensList(p.payloadLensIndex),
195
+ "wpml:useGlobalPayloadLensIndex": formatBool(p.useGlobalPayloadLensIndex),
196
+ "wpml:targetAngle": String(p.targetAngle),
197
+ "wpml:imageWidth": String(p.imageWidth),
198
+ "wpml:imageHeight": String(p.imageHeight),
199
+ "wpml:AFPos": String(p.AFPos),
200
+ "wpml:gimbalPort": String(p.gimbalPort),
201
+ "wpml:accurateCameraType": String(p.accurateCameraType),
202
+ "wpml:accurateFilePath": p.accurateFilePath,
203
+ "wpml:accurateFileMD5": p.accurateFileMD5,
204
+ "wpml:accurateFileSize": String(p.accurateFileSize),
205
+ "wpml:accurateFileSuffix": p.accurateFileSuffix,
206
+ ...p.accurateCameraApertue !== void 0 ? { "wpml:accurateCameraApertue": String(p.accurateCameraApertue) } : {},
207
+ ...p.accurateCameraLuminance !== void 0 ? { "wpml:accurateCameraLuminance": String(p.accurateCameraLuminance) } : {},
208
+ ...p.accurateCameraShutterTime !== void 0 ? { "wpml:accurateCameraShutterTime": String(p.accurateCameraShutterTime) } : {},
209
+ ...p.accurateCameraISO !== void 0 ? { "wpml:accurateCameraISO": String(p.accurateCameraISO) } : {}
210
+ };
211
+ }
212
+ case "orientedShoot": {
213
+ const p = a.actionActuatorFuncParam;
214
+ return {
215
+ "wpml:gimbalPitchRotateAngle": String(p.gimbalPitchRotateAngle),
216
+ "wpml:gimbalYawRotateAngle": String(p.gimbalYawRotateAngle),
217
+ "wpml:focusX": String(p.focusX),
218
+ "wpml:focusY": String(p.focusY),
219
+ "wpml:focusRegionWidth": String(p.focusRegionWidth),
220
+ "wpml:focusRegionHeight": String(p.focusRegionHeight),
221
+ "wpml:focalLength": String(p.focalLength),
222
+ "wpml:aircraftHeading": String(p.aircraftHeading),
223
+ "wpml:accurateFrameValid": formatBool(p.accurateFrameValid),
224
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
225
+ "wpml:payloadLensIndex": formatLensList(p.payloadLensIndex),
226
+ "wpml:useGlobalPayloadLensIndex": formatBool(p.useGlobalPayloadLensIndex),
227
+ "wpml:targetAngle": String(p.targetAngle),
228
+ "wpml:actionUUID": p.actionUUID,
229
+ "wpml:imageWidth": String(p.imageWidth),
230
+ "wpml:imageHeight": String(p.imageHeight),
231
+ "wpml:AFPos": String(p.AFPos),
232
+ "wpml:gimbalPort": String(p.gimbalPort),
233
+ "wpml:orientedCameraType": String(p.orientedCameraType),
234
+ "wpml:orientedFilePath": p.orientedFilePath,
235
+ "wpml:orientedFileMD5": p.orientedFileMD5,
236
+ "wpml:orientedFileSize": String(p.orientedFileSize),
237
+ "wpml:orientedFileSuffix": p.orientedFileSuffix,
238
+ "wpml:orientedCameraApertue": String(p.orientedCameraApertue),
239
+ "wpml:orientedCameraLuminance": String(p.orientedCameraLuminance),
240
+ "wpml:orientedCameraShutterTime": String(p.orientedCameraShutterTime),
241
+ "wpml:orientedCameraISO": String(p.orientedCameraISO),
242
+ "wpml:orientedPhotoMode": p.orientedPhotoMode
243
+ };
244
+ }
245
+ case "panoShot": {
246
+ const p = a.actionActuatorFuncParam;
247
+ return {
248
+ ...p.payloadPositionIndex !== void 0 ? { "wpml:payloadPositionIndex": String(p.payloadPositionIndex) } : {},
249
+ ...p.payloadLensIndex && p.payloadLensIndex.length > 0 ? { "wpml:payloadLensIndex": formatLensList(p.payloadLensIndex) } : {},
250
+ ...p.useGlobalPayloadLensIndex !== void 0 ? { "wpml:useGlobalPayloadLensIndex": formatBool(p.useGlobalPayloadLensIndex) } : {},
251
+ "wpml:panoShotSubMode": p.panoShotSubMode
252
+ };
253
+ }
254
+ case "recordPointCloud": {
255
+ const p = a.actionActuatorFuncParam;
256
+ return {
257
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
258
+ "wpml:recordPointCloudOperate": p.recordPointCloudOperate
259
+ };
260
+ }
261
+ case "megaphone": {
262
+ const p = a.actionActuatorFuncParam;
263
+ return {
264
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
265
+ "wpml:actionUUID": p.actionUUID,
266
+ "wpml:megaphoneOperateType": String(p.megaphoneOperateType),
267
+ "wpml:megaphoneOperateVolume": String(p.megaphoneOperateVolume),
268
+ "wpml:megaphoneOperateLoop": formatBool(p.megaphoneOperateLoop),
269
+ "wpml:megaphoneOperateFilePath": p.megaphoneOperateFilePath,
270
+ "wpml:megaphoneFileName": p.megaphoneFileName,
271
+ "wpml:megaphoneFileOriginalName": p.megaphoneFileOriginalName,
272
+ "wpml:megaphoneFileMd5": p.megaphoneFileMd5,
273
+ "wpml:megaphoneFileBitrate": String(p.megaphoneFileBitrate)
274
+ };
275
+ }
276
+ case "searchlight": {
277
+ const p = a.actionActuatorFuncParam;
278
+ return {
279
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
280
+ ...p.actionUUID !== void 0 ? { "wpml:actionUUID": p.actionUUID } : {},
281
+ "wpml:searchlightOperateType": String(p.searchlightOperateType),
282
+ "wpml:searchlightBrightness": String(p.searchlightBrightness)
283
+ };
284
+ }
285
+ }
286
+ }
287
+ function encodeAction(action) {
288
+ return {
289
+ "wpml:actionId": String(action.actionId),
290
+ "wpml:actionActuatorFunc": action.actionActuatorFunc,
291
+ "wpml:actionActuatorFuncParam": encodeActionParams(action)
292
+ };
293
+ }
294
+ function encodeActionTrigger(trigger) {
295
+ return {
296
+ "wpml:actionTriggerType": trigger.actionTriggerType,
297
+ ...trigger.actionTriggerParam !== void 0 ? { "wpml:actionTriggerParam": String(trigger.actionTriggerParam) } : {}
298
+ };
299
+ }
300
+ function encodeActionGroup(g) {
301
+ const actions = g.action.map(encodeAction);
302
+ return {
303
+ "wpml:actionGroupId": String(g.actionGroupId),
304
+ "wpml:actionGroupStartIndex": String(g.actionGroupStartIndex),
305
+ "wpml:actionGroupEndIndex": String(g.actionGroupEndIndex),
306
+ "wpml:actionGroupMode": g.actionGroupMode,
307
+ "wpml:actionTrigger": encodeActionTrigger(g.actionTrigger),
308
+ ...actions.length > 0 ? { "wpml:action": fromArray(actions) } : {}
309
+ };
310
+ }
311
+ //#endregion
312
+ //#region src/codec/encode-mission-config.ts
313
+ function encodeMissionConfig(config) {
314
+ const payloads = config.payloadInfo.map((p) => ({
315
+ "wpml:payloadEnumValue": String(p.payloadEnumValue),
316
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex)
317
+ }));
318
+ return {
319
+ "wpml:flyToWaylineMode": config.flyToWaylineMode,
320
+ "wpml:finishAction": config.finishAction,
321
+ "wpml:exitOnRCLost": config.exitOnRCLost,
322
+ ...config.executeRCLostAction ? { "wpml:executeRCLostAction": config.executeRCLostAction } : {},
323
+ "wpml:takeOffSecurityHeight": String(config.takeOffSecurityHeight),
324
+ ...config.takeOffRefPoint !== void 0 ? { "wpml:takeOffRefPoint": formatLngLatHeight(config.takeOffRefPoint) } : {},
325
+ ...config.takeOffRefPointAGLHeight !== void 0 ? { "wpml:takeOffRefPointAGLHeight": String(config.takeOffRefPointAGLHeight) } : {},
326
+ "wpml:globalTransitionalSpeed": String(config.globalTransitionalSpeed),
327
+ "wpml:globalRTHHeight": String(config.globalRTHHeight),
328
+ "wpml:droneInfo": {
329
+ "wpml:droneEnumValue": String(config.droneInfo.droneEnumValue),
330
+ ...config.droneInfo.droneSubEnumValue !== void 0 ? { "wpml:droneSubEnumValue": String(config.droneInfo.droneSubEnumValue) } : {}
331
+ },
332
+ ...payloads.length > 0 ? { "wpml:payloadInfo": fromArray(payloads) } : {},
333
+ ...config.autoRerouteInfo ? { "wpml:autoRerouteInfo": {
334
+ "wpml:missionAutoRerouteMode": formatBool(config.autoRerouteInfo.missionAutoRerouteMode),
335
+ "wpml:transitionalAutoRerouteMode": formatBool(config.autoRerouteInfo.transitionalAutoRerouteMode)
336
+ } } : {}
337
+ };
338
+ }
339
+ //#endregion
340
+ //#region src/codec/encode-template.ts
341
+ function encodeCoordinateSysParam(p) {
342
+ return {
343
+ "wpml:coordinateMode": p.coordinateMode,
344
+ "wpml:heightMode": p.heightMode,
345
+ ...p.positioningType !== void 0 ? { "wpml:positioningType": p.positioningType } : {},
346
+ ...p.globalShootHeight !== void 0 ? { "wpml:globalShootHeight": String(p.globalShootHeight) } : {},
347
+ ...p.surfaceFollowModeEnable !== void 0 ? { "wpml:surfaceFollowModeEnable": formatBool(p.surfaceFollowModeEnable) } : {},
348
+ ...p.surfaceRelativeHeight !== void 0 ? { "wpml:surfaceRelativeHeight": String(p.surfaceRelativeHeight) } : {}
349
+ };
350
+ }
351
+ function encodePayloadParam(p) {
352
+ return {
353
+ "wpml:payloadPositionIndex": String(p.payloadPositionIndex),
354
+ ...p.focusMode !== void 0 ? { "wpml:focusMode": p.focusMode } : {},
355
+ ...p.meteringMode !== void 0 ? { "wpml:meteringMode": p.meteringMode } : {},
356
+ ...p.dewarpingEnable !== void 0 ? { "wpml:dewarpingEnable": formatBool(p.dewarpingEnable) } : {},
357
+ ...p.returnMode !== void 0 ? { "wpml:returnMode": p.returnMode } : {},
358
+ ...p.samplingRate !== void 0 ? { "wpml:samplingRate": String(p.samplingRate) } : {},
359
+ ...p.scanningMode !== void 0 ? { "wpml:scanningMode": p.scanningMode } : {},
360
+ ...p.modelColoringEnable !== void 0 ? { "wpml:modelColoringEnable": formatBool(p.modelColoringEnable) } : {},
361
+ "wpml:imageFormat": formatLensList(p.imageFormat)
362
+ };
363
+ }
364
+ function encodeWaypointHeadingParam(p) {
365
+ return {
366
+ "wpml:waypointHeadingMode": p.waypointHeadingMode,
367
+ ...p.waypointHeadingAngle !== void 0 ? { "wpml:waypointHeadingAngle": String(p.waypointHeadingAngle) } : {},
368
+ ...p.waypointPoiPoint !== void 0 ? { "wpml:waypointPoiPoint": formatLngLatHeight(p.waypointPoiPoint) } : {},
369
+ "wpml:waypointHeadingPathMode": p.waypointHeadingPathMode
370
+ };
371
+ }
372
+ function encodeWaypointTurnParam(p) {
373
+ return {
374
+ "wpml:waypointTurnMode": p.waypointTurnMode,
375
+ ...p.waypointTurnDampingDist !== void 0 ? { "wpml:waypointTurnDampingDist": String(p.waypointTurnDampingDist) } : {}
376
+ };
377
+ }
378
+ function encodeMappingHeadingParam(p) {
379
+ return {
380
+ "wpml:mappingHeadingMode": p.mappingHeadingMode,
381
+ ...p.mappingHeadingAngle !== void 0 ? { "wpml:mappingHeadingAngle": String(p.mappingHeadingAngle) } : {}
382
+ };
383
+ }
384
+ function encodeOverlap(o) {
385
+ const out = {};
386
+ if (o.orthoLidarOverlapH !== void 0) out["wpml:orthoLidarOverlapH"] = String(o.orthoLidarOverlapH);
387
+ if (o.orthoLidarOverlapW !== void 0) out["wpml:orthoLidarOverlapW"] = String(o.orthoLidarOverlapW);
388
+ if (o.orthoCameraOverlapH !== void 0) out["wpml:orthoCameraOverlapH"] = String(o.orthoCameraOverlapH);
389
+ if (o.orthoCameraOverlapW !== void 0) out["wpml:orthoCameraOverlapW"] = String(o.orthoCameraOverlapW);
390
+ if (o.inclinedLidarOverlapH !== void 0) out["wpml:inclinedLidarOverlapH"] = String(o.inclinedLidarOverlapH);
391
+ if (o.inclinedLidarOverlapW !== void 0) out["wpml:inclinedLidarOverlapW"] = String(o.inclinedLidarOverlapW);
392
+ if (o.inclinedCameraOverlapH !== void 0) out["wpml:inclinedCameraOverlapH"] = String(o.inclinedCameraOverlapH);
393
+ if (o.inclinedCameraOverlapW !== void 0) out["wpml:inclinedCameraOverlapW"] = String(o.inclinedCameraOverlapW);
394
+ return out;
395
+ }
396
+ function encodeWaypointPlacemark(p) {
397
+ const groups = (p.actionGroup ?? []).map(encodeActionGroup);
398
+ return {
399
+ Point: { coordinates: formatLngLat(p.Point.coordinates) },
400
+ "wpml:index": String(p.index),
401
+ "wpml:useGlobalHeight": formatBool(p.useGlobalHeight),
402
+ ...p.ellipsoidHeight !== void 0 ? { "wpml:ellipsoidHeight": String(p.ellipsoidHeight) } : {},
403
+ ...p.height !== void 0 ? { "wpml:height": String(p.height) } : {},
404
+ "wpml:useGlobalSpeed": formatBool(p.useGlobalSpeed),
405
+ ...p.waypointSpeed !== void 0 ? { "wpml:waypointSpeed": String(p.waypointSpeed) } : {},
406
+ "wpml:useGlobalHeadingParam": formatBool(p.useGlobalHeadingParam),
407
+ ...p.waypointHeadingParam !== void 0 ? { "wpml:waypointHeadingParam": encodeWaypointHeadingParam(p.waypointHeadingParam) } : {},
408
+ "wpml:useGlobalTurnParam": formatBool(p.useGlobalTurnParam),
409
+ ...p.waypointTurnParam !== void 0 ? { "wpml:waypointTurnParam": encodeWaypointTurnParam(p.waypointTurnParam) } : {},
410
+ ...p.useStraightLine !== void 0 ? { "wpml:useStraightLine": formatBool(p.useStraightLine) } : {},
411
+ ...p.gimbalPitchAngle !== void 0 ? { "wpml:gimbalPitchAngle": String(p.gimbalPitchAngle) } : {},
412
+ ...p.isRisky !== void 0 ? { "wpml:isRisky": formatBool(p.isRisky) } : {},
413
+ ...groups.length > 0 ? { "wpml:actionGroup": fromArray(groups) } : {}
414
+ };
415
+ }
416
+ function encodePolygonPlacemark(p) {
417
+ return { Polygon: { outerBoundaryIs: { LinearRing: { coordinates: p.Polygon.outerBoundaryIs.LinearRing.coordinates } } } };
418
+ }
419
+ function encodeLineStringPlacemark(p) {
420
+ return { LineString: { coordinates: p.LineString.coordinates } };
421
+ }
422
+ function encodeWaypointFolder(f) {
423
+ const placemarks = f.Placemark.map(encodeWaypointPlacemark);
424
+ return {
425
+ "wpml:templateType": "waypoint",
426
+ "wpml:templateId": String(f.templateId),
427
+ "wpml:waylineCoordinateSysParam": encodeCoordinateSysParam(f.waylineCoordinateSysParam),
428
+ "wpml:autoFlightSpeed": String(f.autoFlightSpeed),
429
+ ...f.payloadParam ? { "wpml:payloadParam": encodePayloadParam(f.payloadParam) } : {},
430
+ "wpml:globalWaypointTurnMode": f.globalWaypointTurnMode,
431
+ ...f.globalUseStraightLine !== void 0 ? { "wpml:globalUseStraightLine": formatBool(f.globalUseStraightLine) } : {},
432
+ "wpml:gimbalPitchMode": f.gimbalPitchMode,
433
+ "wpml:globalHeight": String(f.globalHeight),
434
+ "wpml:globalWaypointHeadingParam": encodeWaypointHeadingParam(f.globalWaypointHeadingParam),
435
+ ...placemarks.length > 0 ? { Placemark: fromArray(placemarks) } : {}
436
+ };
437
+ }
438
+ function encodeMapping2dFolder(f) {
439
+ return {
440
+ "wpml:templateType": "mapping2d",
441
+ "wpml:templateId": String(f.templateId),
442
+ "wpml:waylineCoordinateSysParam": encodeCoordinateSysParam(f.waylineCoordinateSysParam),
443
+ "wpml:autoFlightSpeed": String(f.autoFlightSpeed),
444
+ ...f.payloadParam ? { "wpml:payloadParam": encodePayloadParam(f.payloadParam) } : {},
445
+ ...f.caliFlightEnable !== void 0 ? { "wpml:caliFlightEnable": formatBool(f.caliFlightEnable) } : {},
446
+ "wpml:elevationOptimizeEnable": formatBool(f.elevationOptimizeEnable),
447
+ ...f.smartObliqueEnable !== void 0 ? { "wpml:smartObliqueEnable": formatBool(f.smartObliqueEnable) } : {},
448
+ ...f.smartObliqueGimbalPitch !== void 0 ? { "wpml:smartObliqueGimbalPitch": String(f.smartObliqueGimbalPitch) } : {},
449
+ "wpml:shootType": f.shootType,
450
+ "wpml:direction": String(f.direction),
451
+ "wpml:margin": String(f.margin),
452
+ "wpml:overlap": encodeOverlap(f.overlap),
453
+ "wpml:ellipsoidHeight": String(f.ellipsoidHeight),
454
+ "wpml:height": String(f.height),
455
+ ...f.facadeWaylineEnable !== void 0 ? { "wpml:facadeWaylineEnable": formatBool(f.facadeWaylineEnable) } : {},
456
+ ...f.mappingHeadingParam ? { "wpml:mappingHeadingParam": encodeMappingHeadingParam(f.mappingHeadingParam) } : {},
457
+ ...f.gimbalPitchMode !== void 0 ? { "wpml:gimbalPitchMode": f.gimbalPitchMode } : {},
458
+ ...f.gimbalPitchAngle !== void 0 ? { "wpml:gimbalPitchAngle": String(f.gimbalPitchAngle) } : {},
459
+ ...f.quickOrthoMappingEnable !== void 0 ? { "wpml:quickOrthoMappingEnable": formatBool(f.quickOrthoMappingEnable) } : {},
460
+ ...f.quickOrthoMappingPitch !== void 0 ? { "wpml:quickOrthoMappingPitch": String(f.quickOrthoMappingPitch) } : {},
461
+ Placemark: encodePolygonPlacemark(f.Placemark)
462
+ };
463
+ }
464
+ function encodeMapping3dFolder(f) {
465
+ return {
466
+ "wpml:templateType": "mapping3d",
467
+ "wpml:templateId": String(f.templateId),
468
+ "wpml:waylineCoordinateSysParam": encodeCoordinateSysParam(f.waylineCoordinateSysParam),
469
+ "wpml:autoFlightSpeed": String(f.autoFlightSpeed),
470
+ ...f.payloadParam ? { "wpml:payloadParam": encodePayloadParam(f.payloadParam) } : {},
471
+ ...f.caliFlightEnable !== void 0 ? { "wpml:caliFlightEnable": formatBool(f.caliFlightEnable) } : {},
472
+ "wpml:inclinedGimbalPitch": String(f.inclinedGimbalPitch),
473
+ "wpml:inclinedFlightSpeed": String(f.inclinedFlightSpeed),
474
+ "wpml:shootType": f.shootType,
475
+ "wpml:direction": String(f.direction),
476
+ "wpml:margin": String(f.margin),
477
+ "wpml:overlap": encodeOverlap(f.overlap),
478
+ "wpml:ellipsoidHeight": String(f.ellipsoidHeight),
479
+ "wpml:height": String(f.height),
480
+ Placemark: encodePolygonPlacemark(f.Placemark)
481
+ };
482
+ }
483
+ function encodeMappingStripFolder(f) {
484
+ return {
485
+ "wpml:templateType": "mappingStrip",
486
+ "wpml:templateId": String(f.templateId),
487
+ "wpml:waylineCoordinateSysParam": encodeCoordinateSysParam(f.waylineCoordinateSysParam),
488
+ "wpml:autoFlightSpeed": String(f.autoFlightSpeed),
489
+ ...f.payloadParam ? { "wpml:payloadParam": encodePayloadParam(f.payloadParam) } : {},
490
+ "wpml:caliFlightEnable": formatBool(f.caliFlightEnable),
491
+ "wpml:shootType": f.shootType,
492
+ "wpml:direction": String(f.direction),
493
+ "wpml:margin": String(f.margin),
494
+ "wpml:singleLineEnable": formatBool(f.singleLineEnable),
495
+ "wpml:cuttingDistance": String(f.cuttingDistance),
496
+ "wpml:boundaryOptimEnable": formatBool(f.boundaryOptimEnable),
497
+ "wpml:leftExtend": String(f.leftExtend),
498
+ "wpml:rightExtend": String(f.rightExtend),
499
+ "wpml:includeCenterEnable": formatBool(f.includeCenterEnable),
500
+ "wpml:overlap": encodeOverlap(f.overlap),
501
+ "wpml:ellipsoidHeight": String(f.ellipsoidHeight),
502
+ "wpml:height": String(f.height),
503
+ "wpml:stripUseTemplateAltitude": formatBool(f.stripUseTemplateAltitude),
504
+ Placemark: encodeLineStringPlacemark(f.Placemark)
505
+ };
506
+ }
507
+ function encodeTemplateFolder(t) {
508
+ switch (t.Folder.templateType) {
509
+ case "waypoint": return encodeWaypointFolder(t.Folder);
510
+ case "mapping2d": return encodeMapping2dFolder(t.Folder);
511
+ case "mapping3d": return encodeMapping3dFolder(t.Folder);
512
+ case "mappingStrip": return encodeMappingStripFolder(t.Folder);
513
+ }
514
+ }
515
+ function encodeTemplate(template) {
516
+ return { kml: {
517
+ "@xmlns": "http://www.opengis.net/kml/2.2",
518
+ "@xmlns:wpml": "http://www.dji.com/wpmz/1.0.6",
519
+ Document: {
520
+ ...template.author !== void 0 ? { "wpml:author": template.author } : {},
521
+ ...template.createTime !== void 0 ? { "wpml:createTime": String(template.createTime) } : {},
522
+ ...template.updateTime !== void 0 ? { "wpml:updateTime": String(template.updateTime) } : {},
523
+ "wpml:missionConfig": encodeMissionConfig(template.missionConfig),
524
+ Folder: encodeTemplateFolder(template)
525
+ }
526
+ } };
527
+ }
528
+ //#endregion
529
+ //#region src/codec/encode-waylines.ts
530
+ function encodeStartActionGroup(g) {
531
+ const items = g.action.map(encodeAction);
532
+ return {
533
+ "wpml:actionGroupId": String(g.actionGroupId),
534
+ "wpml:actionGroupStartIndex": String(g.actionGroupStartIndex),
535
+ "wpml:actionGroupEndIndex": String(g.actionGroupEndIndex),
536
+ "wpml:actionGroupMode": g.actionGroupMode,
537
+ "wpml:actionTrigger": {
538
+ "wpml:actionTriggerType": g.actionTrigger.actionTriggerType,
539
+ ...g.actionTrigger.actionTriggerParam !== void 0 ? { "wpml:actionTriggerParam": String(g.actionTrigger.actionTriggerParam) } : {}
540
+ },
541
+ ...items.length > 0 ? { "wpml:action": fromArray(items) } : {}
542
+ };
543
+ }
544
+ function encodePlacemark(p) {
545
+ const groups = (p.actionGroup ?? []).map(encodeActionGroup);
546
+ return {
547
+ Point: { coordinates: formatLngLat(p.Point.coordinates) },
548
+ "wpml:index": String(p.index),
549
+ "wpml:executeHeight": String(p.executeHeight),
550
+ "wpml:waypointSpeed": String(p.waypointSpeed),
551
+ "wpml:waypointHeadingParam": encodeWaypointHeadingParam(p.waypointHeadingParam),
552
+ "wpml:waypointTurnParam": encodeWaypointTurnParam(p.waypointTurnParam),
553
+ ...p.useStraightLine !== void 0 ? { "wpml:useStraightLine": formatBool(p.useStraightLine) } : {},
554
+ ...p.isRisky !== void 0 ? { "wpml:isRisky": formatBool(p.isRisky) } : {},
555
+ ...groups.length > 0 ? { "wpml:actionGroup": fromArray(groups) } : {}
556
+ };
557
+ }
558
+ function encodeFolder(f) {
559
+ const placemarks = f.Placemark.map(encodePlacemark);
560
+ return {
561
+ "wpml:templateId": String(f.templateId),
562
+ "wpml:waylineId": String(f.waylineId),
563
+ "wpml:executeHeightMode": f.executeHeightMode,
564
+ "wpml:autoFlightSpeed": String(f.autoFlightSpeed),
565
+ ...f.startActionGroup ? { "wpml:startActionGroup": encodeStartActionGroup(f.startActionGroup) } : {},
566
+ Placemark: fromArray(placemarks)
567
+ };
568
+ }
569
+ function encodeWaylines(waylines) {
570
+ const folders = waylines.Folder.map(encodeFolder);
571
+ return { kml: {
572
+ "@xmlns": "http://www.opengis.net/kml/2.2",
573
+ "@xmlns:wpml": "http://www.dji.com/wpmz/1.0.6",
574
+ Document: {
575
+ "wpml:missionConfig": encodeMissionConfig(waylines.missionConfig),
576
+ Folder: fromArray(folders)
577
+ }
578
+ } };
579
+ }
580
+ //#endregion
581
+ //#region src/pack.ts
582
+ /**
583
+ * Encode a Template + Waylines pair (plus optional resources) into a KMZ byte
584
+ * stream. `init()` must have completed before calling this.
585
+ */
586
+ function pack(template, waylines, resources = []) {
587
+ return jsonToKmz(JSON.stringify(encodeTemplate(template)), JSON.stringify(encodeWaylines(waylines)), resources);
588
+ }
589
+ //#endregion
590
+ //#region src/codec/decode-action.ts
591
+ function need(v, field) {
592
+ if (v === void 0) throw new KmzError(`Missing required field "${field}"`);
593
+ return v;
594
+ }
595
+ function decodeAction(raw) {
596
+ const p = raw["wpml:actionActuatorFuncParam"] ?? {};
597
+ const id = parseNum(raw["wpml:actionId"], "actionId");
598
+ const func = raw["wpml:actionActuatorFunc"];
599
+ switch (func) {
600
+ case "takePhoto": return {
601
+ actionId: id,
602
+ actionActuatorFunc: "takePhoto",
603
+ actionActuatorFuncParam: {
604
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
605
+ ...p["wpml:fileSuffix"] !== void 0 ? { fileSuffix: p["wpml:fileSuffix"] } : {},
606
+ ...p["wpml:payloadLensIndex"] ? { payloadLensIndex: parseLensList(p["wpml:payloadLensIndex"]) } : {},
607
+ useGlobalPayloadLensIndex: parseBool(p["wpml:useGlobalPayloadLensIndex"], "useGlobalPayloadLensIndex")
608
+ }
609
+ };
610
+ case "startRecord": return {
611
+ actionId: id,
612
+ actionActuatorFunc: "startRecord",
613
+ actionActuatorFuncParam: {
614
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
615
+ ...p["wpml:fileSuffix"] !== void 0 ? { fileSuffix: p["wpml:fileSuffix"] } : {},
616
+ ...p["wpml:payloadLensIndex"] ? { payloadLensIndex: parseLensList(p["wpml:payloadLensIndex"]) } : {},
617
+ useGlobalPayloadLensIndex: parseBool(p["wpml:useGlobalPayloadLensIndex"], "useGlobalPayloadLensIndex")
618
+ }
619
+ };
620
+ case "stopRecord": {
621
+ const lens = parseLensList(p["wpml:payloadLensIndex"]);
622
+ return {
623
+ actionId: id,
624
+ actionActuatorFunc: "stopRecord",
625
+ actionActuatorFuncParam: {
626
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
627
+ ...lens.length > 0 ? { payloadLensIndex: lens } : {}
628
+ }
629
+ };
630
+ }
631
+ case "focus": return {
632
+ actionId: id,
633
+ actionActuatorFunc: "focus",
634
+ actionActuatorFuncParam: {
635
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
636
+ isPointFocus: parseBool(p["wpml:isPointFocus"], "isPointFocus"),
637
+ focusX: parseNum(p["wpml:focusX"], "focusX"),
638
+ focusY: parseNum(p["wpml:focusY"], "focusY"),
639
+ ...p["wpml:focusRegionWidth"] !== void 0 ? { focusRegionWidth: parseNum(p["wpml:focusRegionWidth"], "focusRegionWidth") } : {},
640
+ ...p["wpml:focusRegionHeight"] !== void 0 ? { focusRegionHeight: parseNum(p["wpml:focusRegionHeight"], "focusRegionHeight") } : {},
641
+ ...p["wpml:isInfiniteFocus"] !== void 0 ? { isInfiniteFocus: parseBool(p["wpml:isInfiniteFocus"], "isInfiniteFocus") } : {}
642
+ }
643
+ };
644
+ case "zoom": return {
645
+ actionId: id,
646
+ actionActuatorFunc: "zoom",
647
+ actionActuatorFuncParam: {
648
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
649
+ focalLength: parseNum(p["wpml:focalLength"], "focalLength")
650
+ }
651
+ };
652
+ case "customDirName": return {
653
+ actionId: id,
654
+ actionActuatorFunc: "customDirName",
655
+ actionActuatorFuncParam: {
656
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
657
+ directoryName: need(p["wpml:directoryName"], "directoryName")
658
+ }
659
+ };
660
+ case "gimbalRotate": return {
661
+ actionId: id,
662
+ actionActuatorFunc: "gimbalRotate",
663
+ actionActuatorFuncParam: {
664
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
665
+ gimbalHeadingYawBase: need(p["wpml:gimbalHeadingYawBase"], "gimbalHeadingYawBase"),
666
+ gimbalRotateMode: need(p["wpml:gimbalRotateMode"], "gimbalRotateMode"),
667
+ gimbalPitchRotateEnable: parseBool(p["wpml:gimbalPitchRotateEnable"], "gimbalPitchRotateEnable"),
668
+ gimbalPitchRotateAngle: degrees(parseNum(p["wpml:gimbalPitchRotateAngle"], "gimbalPitchRotateAngle")),
669
+ gimbalRollRotateEnable: parseBool(p["wpml:gimbalRollRotateEnable"], "gimbalRollRotateEnable"),
670
+ gimbalRollRotateAngle: degrees(parseNum(p["wpml:gimbalRollRotateAngle"], "gimbalRollRotateAngle")),
671
+ gimbalYawRotateEnable: parseBool(p["wpml:gimbalYawRotateEnable"], "gimbalYawRotateEnable"),
672
+ gimbalYawRotateAngle: degrees(parseNum(p["wpml:gimbalYawRotateAngle"], "gimbalYawRotateAngle")),
673
+ gimbalRotateTimeEnable: parseBool(p["wpml:gimbalRotateTimeEnable"], "gimbalRotateTimeEnable"),
674
+ gimbalRotateTime: parseNum(p["wpml:gimbalRotateTime"], "gimbalRotateTime")
675
+ }
676
+ };
677
+ case "rotateYaw": return {
678
+ actionId: id,
679
+ actionActuatorFunc: "rotateYaw",
680
+ actionActuatorFuncParam: {
681
+ aircraftHeading: degrees(parseNum(p["wpml:aircraftHeading"], "aircraftHeading")),
682
+ ...p["wpml:aircraftPathMode"] !== void 0 ? { aircraftPathMode: p["wpml:aircraftPathMode"] } : {}
683
+ }
684
+ };
685
+ case "hover": return {
686
+ actionId: id,
687
+ actionActuatorFunc: "hover",
688
+ actionActuatorFuncParam: { hoverTime: parseNum(p["wpml:hoverTime"], "hoverTime") }
689
+ };
690
+ case "gimbalEvenlyRotate": return {
691
+ actionId: id,
692
+ actionActuatorFunc: "gimbalEvenlyRotate",
693
+ actionActuatorFuncParam: {
694
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
695
+ gimbalPitchRotateAngle: degrees(parseNum(p["wpml:gimbalPitchRotateAngle"], "gimbalPitchRotateAngle"))
696
+ }
697
+ };
698
+ case "accurateShoot": return {
699
+ actionId: id,
700
+ actionActuatorFunc: "accurateShoot",
701
+ actionActuatorFuncParam: {
702
+ gimbalPitchRotateAngle: degrees(parseNum(p["wpml:gimbalPitchRotateAngle"], "gimbalPitchRotateAngle")),
703
+ gimbalYawRotateAngle: degrees(parseNum(p["wpml:gimbalYawRotateAngle"], "gimbalYawRotateAngle")),
704
+ focusX: parseNum(p["wpml:focusX"], "focusX"),
705
+ focusY: parseNum(p["wpml:focusY"], "focusY"),
706
+ focusRegionWidth: parseNum(p["wpml:focusRegionWidth"], "focusRegionWidth"),
707
+ focusRegionHeight: parseNum(p["wpml:focusRegionHeight"], "focusRegionHeight"),
708
+ focalLength: parseNum(p["wpml:focalLength"], "focalLength"),
709
+ aircraftHeading: degrees(parseNum(p["wpml:aircraftHeading"], "aircraftHeading")),
710
+ accurateFrameValid: parseBool(p["wpml:accurateFrameValid"], "accurateFrameValid"),
711
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
712
+ payloadLensIndex: parseLensList(p["wpml:payloadLensIndex"]),
713
+ useGlobalPayloadLensIndex: parseBool(p["wpml:useGlobalPayloadLensIndex"], "useGlobalPayloadLensIndex"),
714
+ targetAngle: degrees(parseNum(p["wpml:targetAngle"], "targetAngle")),
715
+ imageWidth: parseNum(p["wpml:imageWidth"], "imageWidth"),
716
+ imageHeight: parseNum(p["wpml:imageHeight"], "imageHeight"),
717
+ AFPos: parseNum(p["wpml:AFPos"], "AFPos"),
718
+ gimbalPort: parseNum(p["wpml:gimbalPort"], "gimbalPort"),
719
+ accurateCameraType: parseNum(p["wpml:accurateCameraType"], "accurateCameraType"),
720
+ accurateFilePath: need(p["wpml:accurateFilePath"], "accurateFilePath"),
721
+ accurateFileMD5: need(p["wpml:accurateFileMD5"], "accurateFileMD5"),
722
+ accurateFileSize: parseNum(p["wpml:accurateFileSize"], "accurateFileSize"),
723
+ accurateFileSuffix: need(p["wpml:accurateFileSuffix"], "accurateFileSuffix"),
724
+ ...p["wpml:accurateCameraApertue"] !== void 0 ? { accurateCameraApertue: parseNum(p["wpml:accurateCameraApertue"], "accurateCameraApertue") } : {},
725
+ ...p["wpml:accurateCameraLuminance"] !== void 0 ? { accurateCameraLuminance: parseNum(p["wpml:accurateCameraLuminance"], "accurateCameraLuminance") } : {},
726
+ ...p["wpml:accurateCameraShutterTime"] !== void 0 ? { accurateCameraShutterTime: parseNum(p["wpml:accurateCameraShutterTime"], "accurateCameraShutterTime") } : {},
727
+ ...p["wpml:accurateCameraISO"] !== void 0 ? { accurateCameraISO: parseNum(p["wpml:accurateCameraISO"], "accurateCameraISO") } : {}
728
+ }
729
+ };
730
+ case "orientedShoot": return {
731
+ actionId: id,
732
+ actionActuatorFunc: "orientedShoot",
733
+ actionActuatorFuncParam: {
734
+ gimbalPitchRotateAngle: degrees(parseNum(p["wpml:gimbalPitchRotateAngle"], "gimbalPitchRotateAngle")),
735
+ gimbalYawRotateAngle: degrees(parseNum(p["wpml:gimbalYawRotateAngle"], "gimbalYawRotateAngle")),
736
+ focusX: parseNum(p["wpml:focusX"], "focusX"),
737
+ focusY: parseNum(p["wpml:focusY"], "focusY"),
738
+ focusRegionWidth: parseNum(p["wpml:focusRegionWidth"], "focusRegionWidth"),
739
+ focusRegionHeight: parseNum(p["wpml:focusRegionHeight"], "focusRegionHeight"),
740
+ focalLength: parseNum(p["wpml:focalLength"], "focalLength"),
741
+ aircraftHeading: degrees(parseNum(p["wpml:aircraftHeading"], "aircraftHeading")),
742
+ accurateFrameValid: parseBool(p["wpml:accurateFrameValid"], "accurateFrameValid"),
743
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
744
+ payloadLensIndex: parseLensList(p["wpml:payloadLensIndex"]),
745
+ useGlobalPayloadLensIndex: parseBool(p["wpml:useGlobalPayloadLensIndex"], "useGlobalPayloadLensIndex"),
746
+ targetAngle: degrees(parseNum(p["wpml:targetAngle"], "targetAngle")),
747
+ actionUUID: need(p["wpml:actionUUID"], "actionUUID"),
748
+ imageWidth: parseNum(p["wpml:imageWidth"], "imageWidth"),
749
+ imageHeight: parseNum(p["wpml:imageHeight"], "imageHeight"),
750
+ AFPos: parseNum(p["wpml:AFPos"], "AFPos"),
751
+ gimbalPort: parseNum(p["wpml:gimbalPort"], "gimbalPort"),
752
+ orientedCameraType: parseNum(p["wpml:orientedCameraType"], "orientedCameraType"),
753
+ orientedFilePath: need(p["wpml:orientedFilePath"], "orientedFilePath"),
754
+ orientedFileMD5: need(p["wpml:orientedFileMD5"], "orientedFileMD5"),
755
+ orientedFileSize: parseNum(p["wpml:orientedFileSize"], "orientedFileSize"),
756
+ orientedFileSuffix: need(p["wpml:orientedFileSuffix"], "orientedFileSuffix"),
757
+ orientedCameraApertue: parseNum(p["wpml:orientedCameraApertue"], "orientedCameraApertue"),
758
+ orientedCameraLuminance: parseNum(p["wpml:orientedCameraLuminance"], "orientedCameraLuminance"),
759
+ orientedCameraShutterTime: parseNum(p["wpml:orientedCameraShutterTime"], "orientedCameraShutterTime"),
760
+ orientedCameraISO: parseNum(p["wpml:orientedCameraISO"], "orientedCameraISO"),
761
+ orientedPhotoMode: need(p["wpml:orientedPhotoMode"], "orientedPhotoMode")
762
+ }
763
+ };
764
+ case "panoShot": {
765
+ const lens = parseLensList(p["wpml:payloadLensIndex"]);
766
+ return {
767
+ actionId: id,
768
+ actionActuatorFunc: "panoShot",
769
+ actionActuatorFuncParam: {
770
+ ...p["wpml:payloadPositionIndex"] !== void 0 ? { payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex") } : {},
771
+ ...lens.length > 0 ? { payloadLensIndex: lens } : {},
772
+ ...p["wpml:useGlobalPayloadLensIndex"] !== void 0 ? { useGlobalPayloadLensIndex: parseBool(p["wpml:useGlobalPayloadLensIndex"], "useGlobalPayloadLensIndex") } : {},
773
+ panoShotSubMode: need(p["wpml:panoShotSubMode"], "panoShotSubMode")
774
+ }
775
+ };
776
+ }
777
+ case "recordPointCloud": return {
778
+ actionId: id,
779
+ actionActuatorFunc: "recordPointCloud",
780
+ actionActuatorFuncParam: {
781
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
782
+ recordPointCloudOperate: need(p["wpml:recordPointCloudOperate"], "recordPointCloudOperate")
783
+ }
784
+ };
785
+ case "megaphone": return {
786
+ actionId: id,
787
+ actionActuatorFunc: "megaphone",
788
+ actionActuatorFuncParam: {
789
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
790
+ actionUUID: need(p["wpml:actionUUID"], "actionUUID"),
791
+ megaphoneOperateType: parseNum(p["wpml:megaphoneOperateType"], "megaphoneOperateType"),
792
+ megaphoneOperateVolume: parseNum(p["wpml:megaphoneOperateVolume"], "megaphoneOperateVolume"),
793
+ megaphoneOperateLoop: parseBool(p["wpml:megaphoneOperateLoop"], "megaphoneOperateLoop"),
794
+ megaphoneOperateFilePath: need(p["wpml:megaphoneOperateFilePath"], "megaphoneOperateFilePath"),
795
+ megaphoneFileName: need(p["wpml:megaphoneFileName"], "megaphoneFileName"),
796
+ megaphoneFileOriginalName: need(p["wpml:megaphoneFileOriginalName"], "megaphoneFileOriginalName"),
797
+ megaphoneFileMd5: need(p["wpml:megaphoneFileMd5"], "megaphoneFileMd5"),
798
+ megaphoneFileBitrate: parseNum(p["wpml:megaphoneFileBitrate"], "megaphoneFileBitrate")
799
+ }
800
+ };
801
+ case "searchlight": return {
802
+ actionId: id,
803
+ actionActuatorFunc: "searchlight",
804
+ actionActuatorFuncParam: {
805
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex"),
806
+ ...p["wpml:actionUUID"] !== void 0 ? { actionUUID: p["wpml:actionUUID"] } : {},
807
+ searchlightOperateType: parseNum(p["wpml:searchlightOperateType"], "searchlightOperateType"),
808
+ searchlightBrightness: parseNum(p["wpml:searchlightBrightness"], "searchlightBrightness")
809
+ }
810
+ };
811
+ default: throw new KmzError(`Unknown actionActuatorFunc: "${String(func)}"`);
812
+ }
813
+ }
814
+ function decodeActionTrigger(raw) {
815
+ const param = parseOptNum(raw["wpml:actionTriggerParam"]);
816
+ return {
817
+ actionTriggerType: raw["wpml:actionTriggerType"],
818
+ ...param !== void 0 ? { actionTriggerParam: param } : {}
819
+ };
820
+ }
821
+ function decodeActionGroup(raw) {
822
+ return {
823
+ actionGroupId: parseNum(raw["wpml:actionGroupId"], "actionGroupId"),
824
+ actionGroupStartIndex: parseNum(raw["wpml:actionGroupStartIndex"], "actionGroupStartIndex"),
825
+ actionGroupEndIndex: parseNum(raw["wpml:actionGroupEndIndex"], "actionGroupEndIndex"),
826
+ actionGroupMode: raw["wpml:actionGroupMode"] ?? "sequence",
827
+ actionTrigger: decodeActionTrigger(raw["wpml:actionTrigger"]),
828
+ action: toArray(raw["wpml:action"]).map(decodeAction)
829
+ };
830
+ }
831
+ function decodeActionGroups(raw) {
832
+ return toArray(raw).map(decodeActionGroup);
833
+ }
834
+ //#endregion
835
+ //#region src/codec/decode-mission-config.ts
836
+ function decodeMissionConfig(raw) {
837
+ if (!raw["wpml:droneInfo"]) throw new KmzError("Missing wpml:droneInfo in missionConfig");
838
+ const reroute = raw["wpml:autoRerouteInfo"];
839
+ return {
840
+ flyToWaylineMode: raw["wpml:flyToWaylineMode"],
841
+ finishAction: raw["wpml:finishAction"],
842
+ exitOnRCLost: raw["wpml:exitOnRCLost"],
843
+ ...raw["wpml:executeRCLostAction"] ? { executeRCLostAction: raw["wpml:executeRCLostAction"] } : {},
844
+ takeOffSecurityHeight: meters(parseNum(raw["wpml:takeOffSecurityHeight"], "takeOffSecurityHeight")),
845
+ ...raw["wpml:takeOffRefPoint"] !== void 0 ? { takeOffRefPoint: parseLngLatHeight(raw["wpml:takeOffRefPoint"]) } : {},
846
+ ...raw["wpml:takeOffRefPointAGLHeight"] !== void 0 ? { takeOffRefPointAGLHeight: meters(parseNum(raw["wpml:takeOffRefPointAGLHeight"], "takeOffRefPointAGLHeight")) } : {},
847
+ globalTransitionalSpeed: metersPerSecond(parseNum(raw["wpml:globalTransitionalSpeed"], "globalTransitionalSpeed")),
848
+ globalRTHHeight: meters(parseNum(raw["wpml:globalRTHHeight"], "globalRTHHeight")),
849
+ droneInfo: {
850
+ droneEnumValue: parseNum(raw["wpml:droneInfo"]["wpml:droneEnumValue"], "droneEnumValue"),
851
+ ...raw["wpml:droneInfo"]["wpml:droneSubEnumValue"] !== void 0 ? { droneSubEnumValue: parseOptNum(raw["wpml:droneInfo"]["wpml:droneSubEnumValue"]) } : {}
852
+ },
853
+ payloadInfo: toArray(raw["wpml:payloadInfo"]).map((p) => ({
854
+ payloadEnumValue: parseNum(p["wpml:payloadEnumValue"], "payloadEnumValue"),
855
+ payloadPositionIndex: parseNum(p["wpml:payloadPositionIndex"], "payloadPositionIndex")
856
+ })),
857
+ ...reroute ? { autoRerouteInfo: {
858
+ missionAutoRerouteMode: parseOptBool(reroute["wpml:missionAutoRerouteMode"]) ?? false,
859
+ transitionalAutoRerouteMode: parseOptBool(reroute["wpml:transitionalAutoRerouteMode"]) ?? false
860
+ } } : {}
861
+ };
862
+ }
863
+ //#endregion
864
+ //#region src/codec/decode-template.ts
865
+ function decodeCoordinateSysParam(raw) {
866
+ return {
867
+ coordinateMode: raw["wpml:coordinateMode"],
868
+ heightMode: raw["wpml:heightMode"],
869
+ ...raw["wpml:positioningType"] !== void 0 ? { positioningType: raw["wpml:positioningType"] } : {},
870
+ ...raw["wpml:globalShootHeight"] !== void 0 ? { globalShootHeight: meters(parseNum(raw["wpml:globalShootHeight"], "globalShootHeight")) } : {},
871
+ ...raw["wpml:surfaceFollowModeEnable"] !== void 0 ? { surfaceFollowModeEnable: parseBool(raw["wpml:surfaceFollowModeEnable"], "surfaceFollowModeEnable") } : {},
872
+ ...raw["wpml:surfaceRelativeHeight"] !== void 0 ? { surfaceRelativeHeight: meters(parseNum(raw["wpml:surfaceRelativeHeight"], "surfaceRelativeHeight")) } : {}
873
+ };
874
+ }
875
+ function decodePayloadParam(raw) {
876
+ return {
877
+ payloadPositionIndex: parseNum(raw["wpml:payloadPositionIndex"], "payloadPositionIndex"),
878
+ ...raw["wpml:focusMode"] !== void 0 ? { focusMode: raw["wpml:focusMode"] } : {},
879
+ ...raw["wpml:meteringMode"] !== void 0 ? { meteringMode: raw["wpml:meteringMode"] } : {},
880
+ ...raw["wpml:dewarpingEnable"] !== void 0 ? { dewarpingEnable: parseBool(raw["wpml:dewarpingEnable"], "dewarpingEnable") } : {},
881
+ ...raw["wpml:returnMode"] !== void 0 ? { returnMode: raw["wpml:returnMode"] } : {},
882
+ ...raw["wpml:samplingRate"] !== void 0 ? { samplingRate: parseNum(raw["wpml:samplingRate"], "samplingRate") } : {},
883
+ ...raw["wpml:scanningMode"] !== void 0 ? { scanningMode: raw["wpml:scanningMode"] } : {},
884
+ ...raw["wpml:modelColoringEnable"] !== void 0 ? { modelColoringEnable: parseBool(raw["wpml:modelColoringEnable"], "modelColoringEnable") } : {},
885
+ imageFormat: parseLensList(raw["wpml:imageFormat"])
886
+ };
887
+ }
888
+ function decodeWaypointHeadingParam(raw) {
889
+ return {
890
+ waypointHeadingMode: raw["wpml:waypointHeadingMode"],
891
+ ...raw["wpml:waypointHeadingAngle"] !== void 0 ? { waypointHeadingAngle: degrees(parseNum(raw["wpml:waypointHeadingAngle"], "waypointHeadingAngle")) } : {},
892
+ ...raw["wpml:waypointPoiPoint"] !== void 0 ? { waypointPoiPoint: parseLngLatHeight(raw["wpml:waypointPoiPoint"]) } : {},
893
+ waypointHeadingPathMode: raw["wpml:waypointHeadingPathMode"] ?? "followBadArc"
894
+ };
895
+ }
896
+ function decodeWaypointTurnParam(raw) {
897
+ return {
898
+ waypointTurnMode: raw["wpml:waypointTurnMode"],
899
+ ...raw["wpml:waypointTurnDampingDist"] !== void 0 ? { waypointTurnDampingDist: meters(parseNum(raw["wpml:waypointTurnDampingDist"], "waypointTurnDampingDist")) } : {}
900
+ };
901
+ }
902
+ function decodeMappingHeadingParam(raw) {
903
+ return {
904
+ mappingHeadingMode: raw["wpml:mappingHeadingMode"],
905
+ ...raw["wpml:mappingHeadingAngle"] !== void 0 ? { mappingHeadingAngle: degrees(parseNum(raw["wpml:mappingHeadingAngle"], "mappingHeadingAngle")) } : {}
906
+ };
907
+ }
908
+ function decodeOverlap(raw) {
909
+ const out = {};
910
+ if (raw["wpml:orthoLidarOverlapH"] !== void 0) out.orthoLidarOverlapH = parseNum(raw["wpml:orthoLidarOverlapH"], "orthoLidarOverlapH");
911
+ if (raw["wpml:orthoLidarOverlapW"] !== void 0) out.orthoLidarOverlapW = parseNum(raw["wpml:orthoLidarOverlapW"], "orthoLidarOverlapW");
912
+ if (raw["wpml:orthoCameraOverlapH"] !== void 0) out.orthoCameraOverlapH = parseNum(raw["wpml:orthoCameraOverlapH"], "orthoCameraOverlapH");
913
+ if (raw["wpml:orthoCameraOverlapW"] !== void 0) out.orthoCameraOverlapW = parseNum(raw["wpml:orthoCameraOverlapW"], "orthoCameraOverlapW");
914
+ if (raw["wpml:inclinedLidarOverlapH"] !== void 0) out.inclinedLidarOverlapH = parseNum(raw["wpml:inclinedLidarOverlapH"], "inclinedLidarOverlapH");
915
+ if (raw["wpml:inclinedLidarOverlapW"] !== void 0) out.inclinedLidarOverlapW = parseNum(raw["wpml:inclinedLidarOverlapW"], "inclinedLidarOverlapW");
916
+ if (raw["wpml:inclinedCameraOverlapH"] !== void 0) out.inclinedCameraOverlapH = parseNum(raw["wpml:inclinedCameraOverlapH"], "inclinedCameraOverlapH");
917
+ if (raw["wpml:inclinedCameraOverlapW"] !== void 0) out.inclinedCameraOverlapW = parseNum(raw["wpml:inclinedCameraOverlapW"], "inclinedCameraOverlapW");
918
+ return out;
919
+ }
920
+ function decodeWaypointPlacemark(raw) {
921
+ const out = {
922
+ Point: { coordinates: parseLngLat(raw.Point.coordinates) },
923
+ index: parseNum(raw["wpml:index"], "index"),
924
+ useGlobalHeight: parseOptBool(raw["wpml:useGlobalHeight"]) ?? true,
925
+ useGlobalSpeed: parseOptBool(raw["wpml:useGlobalSpeed"]) ?? true,
926
+ useGlobalHeadingParam: parseOptBool(raw["wpml:useGlobalHeadingParam"]) ?? true,
927
+ useGlobalTurnParam: parseOptBool(raw["wpml:useGlobalTurnParam"]) ?? true
928
+ };
929
+ if (raw["wpml:ellipsoidHeight"] !== void 0) out.ellipsoidHeight = meters(parseNum(raw["wpml:ellipsoidHeight"], "ellipsoidHeight"));
930
+ if (raw["wpml:height"] !== void 0) out.height = meters(parseNum(raw["wpml:height"], "height"));
931
+ if (raw["wpml:waypointSpeed"] !== void 0) out.waypointSpeed = metersPerSecond(parseNum(raw["wpml:waypointSpeed"], "waypointSpeed"));
932
+ if (raw["wpml:waypointHeadingParam"] !== void 0) out.waypointHeadingParam = decodeWaypointHeadingParam(raw["wpml:waypointHeadingParam"]);
933
+ if (raw["wpml:waypointTurnParam"] !== void 0) out.waypointTurnParam = decodeWaypointTurnParam(raw["wpml:waypointTurnParam"]);
934
+ if (raw["wpml:useStraightLine"] !== void 0) out.useStraightLine = parseBool(raw["wpml:useStraightLine"], "useStraightLine");
935
+ if (raw["wpml:gimbalPitchAngle"] !== void 0) out.gimbalPitchAngle = degrees(parseNum(raw["wpml:gimbalPitchAngle"], "gimbalPitchAngle"));
936
+ if (raw["wpml:isRisky"] !== void 0) out.isRisky = parseBool(raw["wpml:isRisky"], "isRisky");
937
+ const groups = decodeActionGroups(raw["wpml:actionGroup"]);
938
+ if (groups.length > 0) out.actionGroup = groups;
939
+ return out;
940
+ }
941
+ function decodePolygonPlacemark(raw) {
942
+ return { Polygon: { outerBoundaryIs: { LinearRing: { coordinates: raw.Polygon.outerBoundaryIs.LinearRing.coordinates } } } };
943
+ }
944
+ function decodeWaypointFolder(raw) {
945
+ const placemarks = toArray(raw.Placemark).map(decodeWaypointPlacemark);
946
+ return {
947
+ Folder: {
948
+ templateType: "waypoint",
949
+ templateId: parseNum(raw["wpml:templateId"], "templateId"),
950
+ waylineCoordinateSysParam: decodeCoordinateSysParam(raw["wpml:waylineCoordinateSysParam"]),
951
+ autoFlightSpeed: metersPerSecond(parseNum(raw["wpml:autoFlightSpeed"], "autoFlightSpeed")),
952
+ ...raw["wpml:payloadParam"] ? { payloadParam: decodePayloadParam(raw["wpml:payloadParam"]) } : {},
953
+ globalWaypointTurnMode: raw["wpml:globalWaypointTurnMode"],
954
+ ...raw["wpml:globalUseStraightLine"] !== void 0 ? { globalUseStraightLine: parseBool(raw["wpml:globalUseStraightLine"], "globalUseStraightLine") } : {},
955
+ gimbalPitchMode: raw["wpml:gimbalPitchMode"],
956
+ globalHeight: meters(parseNum(raw["wpml:globalHeight"], "globalHeight")),
957
+ globalWaypointHeadingParam: decodeWaypointHeadingParam(raw["wpml:globalWaypointHeadingParam"]),
958
+ Placemark: placemarks
959
+ },
960
+ missionConfig: void 0
961
+ };
962
+ }
963
+ function decodeMapping2dFolder(raw) {
964
+ return {
965
+ Folder: {
966
+ templateType: "mapping2d",
967
+ templateId: parseNum(raw["wpml:templateId"], "templateId"),
968
+ waylineCoordinateSysParam: decodeCoordinateSysParam(raw["wpml:waylineCoordinateSysParam"]),
969
+ autoFlightSpeed: metersPerSecond(parseNum(raw["wpml:autoFlightSpeed"], "autoFlightSpeed")),
970
+ ...raw["wpml:payloadParam"] ? { payloadParam: decodePayloadParam(raw["wpml:payloadParam"]) } : {},
971
+ ...raw["wpml:caliFlightEnable"] !== void 0 ? { caliFlightEnable: parseBool(raw["wpml:caliFlightEnable"], "caliFlightEnable") } : {},
972
+ elevationOptimizeEnable: parseBool(raw["wpml:elevationOptimizeEnable"], "elevationOptimizeEnable"),
973
+ ...raw["wpml:smartObliqueEnable"] !== void 0 ? { smartObliqueEnable: parseBool(raw["wpml:smartObliqueEnable"], "smartObliqueEnable") } : {},
974
+ ...raw["wpml:smartObliqueGimbalPitch"] !== void 0 ? { smartObliqueGimbalPitch: degrees(parseNum(raw["wpml:smartObliqueGimbalPitch"], "smartObliqueGimbalPitch")) } : {},
975
+ shootType: raw["wpml:shootType"],
976
+ direction: degrees(parseNum(raw["wpml:direction"], "direction")),
977
+ margin: parseNum(raw["wpml:margin"], "margin"),
978
+ overlap: decodeOverlap(raw["wpml:overlap"]),
979
+ ellipsoidHeight: meters(parseNum(raw["wpml:ellipsoidHeight"], "ellipsoidHeight")),
980
+ height: meters(parseNum(raw["wpml:height"], "height")),
981
+ ...raw["wpml:facadeWaylineEnable"] !== void 0 ? { facadeWaylineEnable: parseBool(raw["wpml:facadeWaylineEnable"], "facadeWaylineEnable") } : {},
982
+ ...raw["wpml:mappingHeadingParam"] ? { mappingHeadingParam: decodeMappingHeadingParam(raw["wpml:mappingHeadingParam"]) } : {},
983
+ ...raw["wpml:gimbalPitchMode"] !== void 0 ? { gimbalPitchMode: raw["wpml:gimbalPitchMode"] } : {},
984
+ ...raw["wpml:gimbalPitchAngle"] !== void 0 ? { gimbalPitchAngle: degrees(parseNum(raw["wpml:gimbalPitchAngle"], "gimbalPitchAngle")) } : {},
985
+ ...raw["wpml:quickOrthoMappingEnable"] !== void 0 ? { quickOrthoMappingEnable: parseBool(raw["wpml:quickOrthoMappingEnable"], "quickOrthoMappingEnable") } : {},
986
+ ...raw["wpml:quickOrthoMappingPitch"] !== void 0 ? { quickOrthoMappingPitch: degrees(parseNum(raw["wpml:quickOrthoMappingPitch"], "quickOrthoMappingPitch")) } : {},
987
+ Placemark: decodePolygonPlacemark(raw.Placemark)
988
+ },
989
+ missionConfig: void 0
990
+ };
991
+ }
992
+ function decodeMapping3dFolder(raw) {
993
+ return {
994
+ Folder: {
995
+ templateType: "mapping3d",
996
+ templateId: parseNum(raw["wpml:templateId"], "templateId"),
997
+ waylineCoordinateSysParam: decodeCoordinateSysParam(raw["wpml:waylineCoordinateSysParam"]),
998
+ autoFlightSpeed: metersPerSecond(parseNum(raw["wpml:autoFlightSpeed"], "autoFlightSpeed")),
999
+ ...raw["wpml:payloadParam"] ? { payloadParam: decodePayloadParam(raw["wpml:payloadParam"]) } : {},
1000
+ ...raw["wpml:caliFlightEnable"] !== void 0 ? { caliFlightEnable: parseBool(raw["wpml:caliFlightEnable"], "caliFlightEnable") } : {},
1001
+ inclinedGimbalPitch: degrees(parseNum(raw["wpml:inclinedGimbalPitch"], "inclinedGimbalPitch")),
1002
+ inclinedFlightSpeed: metersPerSecond(parseNum(raw["wpml:inclinedFlightSpeed"], "inclinedFlightSpeed")),
1003
+ shootType: raw["wpml:shootType"],
1004
+ direction: degrees(parseNum(raw["wpml:direction"], "direction")),
1005
+ margin: parseNum(raw["wpml:margin"], "margin"),
1006
+ overlap: decodeOverlap(raw["wpml:overlap"]),
1007
+ ellipsoidHeight: meters(parseNum(raw["wpml:ellipsoidHeight"], "ellipsoidHeight")),
1008
+ height: meters(parseNum(raw["wpml:height"], "height")),
1009
+ Placemark: decodePolygonPlacemark(raw.Placemark)
1010
+ },
1011
+ missionConfig: void 0
1012
+ };
1013
+ }
1014
+ function decodeMappingStripFolder(raw) {
1015
+ return {
1016
+ Folder: {
1017
+ templateType: "mappingStrip",
1018
+ templateId: parseNum(raw["wpml:templateId"], "templateId"),
1019
+ waylineCoordinateSysParam: decodeCoordinateSysParam(raw["wpml:waylineCoordinateSysParam"]),
1020
+ autoFlightSpeed: metersPerSecond(parseNum(raw["wpml:autoFlightSpeed"], "autoFlightSpeed")),
1021
+ ...raw["wpml:payloadParam"] ? { payloadParam: decodePayloadParam(raw["wpml:payloadParam"]) } : {},
1022
+ caliFlightEnable: parseBool(raw["wpml:caliFlightEnable"], "caliFlightEnable"),
1023
+ shootType: raw["wpml:shootType"],
1024
+ direction: degrees(parseNum(raw["wpml:direction"], "direction")),
1025
+ margin: parseNum(raw["wpml:margin"], "margin"),
1026
+ singleLineEnable: parseBool(raw["wpml:singleLineEnable"], "singleLineEnable"),
1027
+ cuttingDistance: parseNum(raw["wpml:cuttingDistance"], "cuttingDistance"),
1028
+ boundaryOptimEnable: parseBool(raw["wpml:boundaryOptimEnable"], "boundaryOptimEnable"),
1029
+ leftExtend: parseNum(raw["wpml:leftExtend"], "leftExtend"),
1030
+ rightExtend: parseNum(raw["wpml:rightExtend"], "rightExtend"),
1031
+ includeCenterEnable: parseBool(raw["wpml:includeCenterEnable"], "includeCenterEnable"),
1032
+ overlap: decodeOverlap(raw["wpml:overlap"]),
1033
+ ellipsoidHeight: meters(parseNum(raw["wpml:ellipsoidHeight"], "ellipsoidHeight")),
1034
+ height: meters(parseNum(raw["wpml:height"], "height")),
1035
+ stripUseTemplateAltitude: parseBool(raw["wpml:stripUseTemplateAltitude"], "stripUseTemplateAltitude"),
1036
+ Placemark: { LineString: { coordinates: raw.Placemark.LineString.coordinates } }
1037
+ },
1038
+ missionConfig: void 0
1039
+ };
1040
+ }
1041
+ function decodeTemplateFolder(raw) {
1042
+ switch (raw["wpml:templateType"]) {
1043
+ case "waypoint": return decodeWaypointFolder(raw);
1044
+ case "mapping2d": return decodeMapping2dFolder(raw);
1045
+ case "mapping3d": return decodeMapping3dFolder(raw);
1046
+ case "mappingStrip": return decodeMappingStripFolder(raw);
1047
+ default: throw new KmzError(`Unknown templateType: "${String(raw["wpml:templateType"])}"`);
1048
+ }
1049
+ }
1050
+ function decodeTemplate(raw) {
1051
+ const doc = raw.kml.Document;
1052
+ if (!doc["wpml:missionConfig"]) throw new KmzError("Missing wpml:missionConfig in template");
1053
+ const folder = toArray(doc.Folder)[0];
1054
+ if (!folder) throw new KmzError("No Folder in template document");
1055
+ return {
1056
+ ...decodeTemplateFolder(folder),
1057
+ missionConfig: decodeMissionConfig(doc["wpml:missionConfig"]),
1058
+ ...doc["wpml:author"] !== void 0 ? { author: doc["wpml:author"] } : {},
1059
+ ...doc["wpml:createTime"] !== void 0 ? { createTime: parseNum(doc["wpml:createTime"], "createTime") } : {},
1060
+ ...doc["wpml:updateTime"] !== void 0 ? { updateTime: parseNum(doc["wpml:updateTime"], "updateTime") } : {}
1061
+ };
1062
+ }
1063
+ //#endregion
1064
+ //#region src/codec/decode-waylines.ts
1065
+ function decodeStartActionGroup(raw) {
1066
+ return {
1067
+ actionGroupId: parseNum(raw["wpml:actionGroupId"], "actionGroupId"),
1068
+ actionGroupStartIndex: parseNum(raw["wpml:actionGroupStartIndex"], "actionGroupStartIndex"),
1069
+ actionGroupEndIndex: parseNum(raw["wpml:actionGroupEndIndex"], "actionGroupEndIndex"),
1070
+ actionGroupMode: raw["wpml:actionGroupMode"] ?? "sequence",
1071
+ actionTrigger: {
1072
+ actionTriggerType: raw["wpml:actionTrigger"]["wpml:actionTriggerType"],
1073
+ ...raw["wpml:actionTrigger"]["wpml:actionTriggerParam"] !== void 0 ? { actionTriggerParam: parseOptNum(raw["wpml:actionTrigger"]["wpml:actionTriggerParam"]) } : {}
1074
+ },
1075
+ action: toArray(raw["wpml:action"]).map(decodeAction)
1076
+ };
1077
+ }
1078
+ function decodePlacemark(raw) {
1079
+ const groups = decodeActionGroups(raw["wpml:actionGroup"]);
1080
+ const out = {
1081
+ Point: { coordinates: parseLngLat(raw.Point.coordinates) },
1082
+ index: parseNum(raw["wpml:index"], "index"),
1083
+ executeHeight: meters(parseNum(raw["wpml:executeHeight"], "executeHeight")),
1084
+ waypointSpeed: metersPerSecond(parseNum(raw["wpml:waypointSpeed"], "waypointSpeed")),
1085
+ waypointHeadingParam: decodeWaypointHeadingParam(raw["wpml:waypointHeadingParam"]),
1086
+ waypointTurnParam: decodeWaypointTurnParam(raw["wpml:waypointTurnParam"])
1087
+ };
1088
+ if (raw["wpml:useStraightLine"] !== void 0) out.useStraightLine = parseBool(raw["wpml:useStraightLine"], "useStraightLine");
1089
+ if (raw["wpml:isRisky"] !== void 0) out.isRisky = parseBool(raw["wpml:isRisky"], "isRisky");
1090
+ if (groups.length > 0) out.actionGroup = groups;
1091
+ return out;
1092
+ }
1093
+ function decodeFolder(raw) {
1094
+ const placemarks = toArray(raw.Placemark);
1095
+ if (placemarks.length === 0) throw new KmzError(`Folder "${raw["wpml:waylineId"]}" has no Placemark`);
1096
+ return {
1097
+ templateId: parseNum(raw["wpml:templateId"], "templateId"),
1098
+ waylineId: parseNum(raw["wpml:waylineId"], "waylineId"),
1099
+ executeHeightMode: raw["wpml:executeHeightMode"],
1100
+ autoFlightSpeed: metersPerSecond(parseNum(raw["wpml:autoFlightSpeed"], "autoFlightSpeed")),
1101
+ ...raw["wpml:startActionGroup"] ? { startActionGroup: decodeStartActionGroup(raw["wpml:startActionGroup"]) } : {},
1102
+ Placemark: placemarks.map(decodePlacemark)
1103
+ };
1104
+ }
1105
+ function decodeWaylines(raw) {
1106
+ const doc = raw.kml.Document;
1107
+ if (!doc["wpml:missionConfig"]) throw new KmzError("Missing wpml:missionConfig in waylines");
1108
+ const folders = toArray(doc.Folder);
1109
+ if (folders.length === 0) throw new KmzError("No Folder in waylines document");
1110
+ return {
1111
+ missionConfig: decodeMissionConfig(doc["wpml:missionConfig"]),
1112
+ Folder: folders.map(decodeFolder)
1113
+ };
1114
+ }
1115
+ //#endregion
1116
+ //#region src/unpack.ts
1117
+ /**
1118
+ * Decode a KMZ byte stream into typed Template + Waylines. `init()` must have
1119
+ * completed before calling this.
1120
+ */
1121
+ function unpack(bytes) {
1122
+ const raw = kmzToJson(bytes);
1123
+ const templateXml = JSON.parse(raw.template);
1124
+ const waylinesXml = JSON.parse(raw.waylines);
1125
+ return {
1126
+ template: decodeTemplate(templateXml),
1127
+ waylines: decodeWaylines(waylinesXml),
1128
+ resources: raw.resources
1129
+ };
1130
+ }
1131
+ //#endregion
1132
+ //#region src/index.ts
1133
+ var src_default = {
1134
+ pack,
1135
+ unpack,
1136
+ init,
1137
+ initSync
1138
+ };
1139
+ //#endregion
1140
+ export { src_default as default, init, initSync, pack, unpack };