@lumikmz/kmz 0.7.0 → 0.8.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.
@@ -204,7 +204,7 @@ function shootSectionStartActions(
204
204
  actionActuatorFuncParam: {
205
205
  payloadPositionIndex: 0,
206
206
  useGlobalPayloadLensIndex: false,
207
- payloadLensIndex: "visable",
207
+ payloadLensIndex: ["visable"],
208
208
  minShootInterval: shootInterval,
209
209
  },
210
210
  },
@@ -256,7 +256,7 @@ function shootSectionStopActions(
256
256
  {
257
257
  actionId: 0,
258
258
  actionActuatorFunc: "stopTimeLapse",
259
- actionActuatorFuncParam: { payloadPositionIndex: 0, payloadLensIndex: "visable" },
259
+ actionActuatorFuncParam: { payloadPositionIndex: 0, payloadLensIndex: ["visable"] },
260
260
  },
261
261
  { actionId: 1, actionActuatorFunc: "gimbalAngleUnlock" } satisfies Action,
262
262
  ],
@@ -293,8 +293,8 @@ export type StopSmartObliqueAction = ActionBase<"stopSmartOblique", StopSmartObl
293
293
  export interface StartTimeLapseParam {
294
294
  payloadPositionIndex: number;
295
295
  useGlobalPayloadLensIndex: boolean;
296
- /** Single lens token (not a list — mapping strips use one lens). */
297
- payloadLensIndex: LensType;
296
+ /** Comma-separated in WPML; may contain visible and infrared lenses together. */
297
+ payloadLensIndex: LensType[];
298
298
  /** Minimum shoot interval in seconds. Derived from `forwardGroundSpacing / speed`. */
299
299
  minShootInterval: number;
300
300
  }
@@ -303,7 +303,7 @@ export type StartTimeLapseAction = ActionBase<"startTimeLapse", StartTimeLapsePa
303
303
  /** Stops interval shooting for a mapping strip. */
304
304
  export interface StopTimeLapseParam {
305
305
  payloadPositionIndex: number;
306
- payloadLensIndex: LensType;
306
+ payloadLensIndex: LensType[];
307
307
  }
308
308
  export type StopTimeLapseAction = ActionBase<"stopTimeLapse", StopTimeLapseParam>;
309
309
 
@@ -118,12 +118,16 @@ export interface Mapping3dPlacemark {
118
118
  /** `Placemark` inside a `mappingStrip` Folder — uses a LineString; params live here. */
119
119
  export interface MappingStripPlacemark {
120
120
  caliFlightEnable: boolean;
121
+ /** Optional field observed in FlightHub 2 mappingStrip exports. */
122
+ elevationOptimizeEnable?: boolean;
121
123
  shootType: ShootType;
122
124
  direction: Degrees;
123
125
  /** Float meters (vs integer in mapping2d/3d). */
124
126
  margin: number;
125
127
  singleLineEnable: boolean;
126
128
  cuttingDistance: number;
129
+ /** FlightHub 2 region merge ranges, serialized as JSON (for example `[[1,3]]`). */
130
+ stripMergedRegions?: number[][];
127
131
  boundaryOptimEnable: boolean;
128
132
  leftExtend: number;
129
133
  rightExtend: number;
@@ -73,17 +73,65 @@ function validateMapping3dFolder(t: Mapping3dTemplate, path: string): Issue[] {
73
73
  }
74
74
 
75
75
  function validateMappingStripFolder(t: MappingStripTemplate, path: string): Issue[] {
76
- const tuples = t.Folder.Placemark.LineString.coordinates.trim().split(/\s+/);
77
- if (tuples.length < 2) {
78
- return [
79
- {
80
- path: `${path}.Placemark.LineString`,
81
- message: `LineString must have at least 2 vertices, got ${tuples.length}`,
76
+ const placemark = t.Folder.Placemark;
77
+ const tuples = placemark.LineString.coordinates.trim().split(/\s+/).filter(Boolean);
78
+ const distinct = new Set(
79
+ tuples.map((tuple) => {
80
+ const [lng, lat] = tuple.split(",");
81
+ return `${lng},${lat}`;
82
+ }),
83
+ );
84
+ const issues: Issue[] = [];
85
+ if (tuples.length < 2 || distinct.size < 2) {
86
+ issues.push({
87
+ path: `${path}.Placemark.LineString`,
88
+ message: "LineString must contain at least 2 distinct vertices",
89
+ severity: "error",
90
+ });
91
+ }
92
+ if (!Number.isFinite(placemark.leftExtend) || placemark.leftExtend < 0) {
93
+ issues.push({
94
+ path: `${path}.Placemark.leftExtend`,
95
+ message: "leftExtend must be finite and non-negative",
96
+ severity: "error",
97
+ });
98
+ }
99
+ if (!Number.isFinite(placemark.rightExtend) || placemark.rightExtend < 0) {
100
+ issues.push({
101
+ path: `${path}.Placemark.rightExtend`,
102
+ message: "rightExtend must be finite and non-negative",
103
+ severity: "error",
104
+ });
105
+ }
106
+ if (!Number.isFinite(placemark.cuttingDistance) || placemark.cuttingDistance <= 0) {
107
+ issues.push({
108
+ path: `${path}.Placemark.cuttingDistance`,
109
+ message: "cuttingDistance must be finite and greater than zero",
110
+ severity: "error",
111
+ });
112
+ }
113
+ if (placemark.stripMergedRegions) {
114
+ const ranges = placemark.stripMergedRegions
115
+ .map((range) => ({ start: range[0], end: range[1], length: range.length }))
116
+ .sort((a, b) => (a.start ?? 0) - (b.start ?? 0));
117
+ const malformed = ranges.some(
118
+ ({ start, end, length }, index) =>
119
+ length !== 2 ||
120
+ !Number.isInteger(start) ||
121
+ !Number.isInteger(end) ||
122
+ start! < 1 ||
123
+ end! < start! ||
124
+ (index > 0 && start! <= ranges[index - 1]!.end!),
125
+ );
126
+ if (malformed) {
127
+ issues.push({
128
+ path: `${path}.Placemark.stripMergedRegions`,
129
+ message: "stripMergedRegions must contain non-overlapping one-based [start,end] ranges",
82
130
  severity: "error",
83
- },
84
- ];
131
+ });
132
+ }
85
133
  }
86
- return [];
134
+ return issues;
87
135
  }
88
136
 
89
137
  function validatePolygonRing(coords: string, path: string): Issue[] {