@tak-ps/node-cot 14.39.0 → 14.40.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.
@@ -13,6 +13,14 @@ import type {
13
13
  Link,
14
14
  LinkAttributes,
15
15
  ColorAttributes,
16
+ RadMeasurement,
17
+ RadPhysicalModule,
18
+ RadSpectrum,
19
+ RadIsotope,
20
+ ChemDetection,
21
+ BioMeasurement,
22
+ BioMeasurementLevel,
23
+ BioMeasurementLevelAttributes,
16
24
  } from '../types/types.js'
17
25
  import Ellipse from '@turf/ellipse';
18
26
  import Truncate from '@turf/truncate';
@@ -91,6 +99,88 @@ export async function to_geojson(
91
99
  feat.properties.sensor = raw.event.detail.sensor._attributes;
92
100
  }
93
101
 
102
+ if (raw.event.detail.radsensordetail) {
103
+ const rad = raw.event.detail.radsensordetail;
104
+ feat.properties.radsensordetail = {
105
+ sensor_data: { ...rad.sensor_data._attributes }
106
+ };
107
+
108
+ if (rad.radmeasurement) {
109
+ const measurements = Array.isArray(rad.radmeasurement) ? rad.radmeasurement : [rad.radmeasurement];
110
+ feat.properties.radsensordetail.radmeasurement = measurements.map((m: Static<typeof RadMeasurement>) => ({ ...m._attributes }));
111
+ }
112
+
113
+ if (rad.physical_module) {
114
+ const modules = Array.isArray(rad.physical_module) ? rad.physical_module : [rad.physical_module];
115
+ feat.properties.radsensordetail.physical_module = modules.map((m: Static<typeof RadPhysicalModule>) => ({ ...m._attributes }));
116
+ }
117
+
118
+ if (rad.search_algorithm) {
119
+ feat.properties.radsensordetail.search_algorithm = { ...rad.search_algorithm._attributes };
120
+ }
121
+
122
+ if (rad.spectrum) {
123
+ const spectra = Array.isArray(rad.spectrum) ? rad.spectrum : [rad.spectrum];
124
+ feat.properties.radsensordetail.spectrum = spectra.map((s: Static<typeof RadSpectrum>) => ({ ...s._attributes }));
125
+ }
126
+
127
+ if (rad.isotope) {
128
+ const isotopes = Array.isArray(rad.isotope) ? rad.isotope : [rad.isotope];
129
+ feat.properties.radsensordetail.isotope = isotopes.map((i: Static<typeof RadIsotope>) => ({ ...i._attributes }));
130
+ }
131
+
132
+ if (rad.data_permissions) {
133
+ feat.properties.radsensordetail.data_permissions = { ...rad.data_permissions._attributes };
134
+ }
135
+
136
+ if (rad.command_permissions) {
137
+ feat.properties.radsensordetail.command_permissions = { ...rad.command_permissions._attributes };
138
+ }
139
+ }
140
+
141
+ if (raw.event.detail.chemsensordetail) {
142
+ const chem = raw.event.detail.chemsensordetail;
143
+ feat.properties.chemsensordetail = {
144
+ sensor_data: { ...chem.sensor_data._attributes }
145
+ };
146
+
147
+ if (chem.detection) {
148
+ const detections = Array.isArray(chem.detection) ? chem.detection : [chem.detection];
149
+ feat.properties.chemsensordetail.detection = detections.map((d: Static<typeof ChemDetection>) => ({ ...d._attributes }));
150
+ }
151
+ }
152
+
153
+ if (raw.event.detail.biosensordetail) {
154
+ const bio = raw.event.detail.biosensordetail;
155
+ feat.properties.biosensordetail = {
156
+ sensor_data: { ...bio.sensor_data._attributes }
157
+ };
158
+
159
+ if (bio.measurement) {
160
+ const measurements = Array.isArray(bio.measurement) ? bio.measurement : [bio.measurement];
161
+ feat.properties.biosensordetail.measurement = measurements.map((m: Static<typeof BioMeasurement>) => {
162
+ const measurement: { level?: Array<Static<typeof BioMeasurementLevelAttributes>> } & typeof m._attributes = { ...m._attributes };
163
+ if (m.level) {
164
+ const levels = Array.isArray(m.level) ? m.level : [m.level];
165
+ measurement.level = levels.map((l: Static<typeof BioMeasurementLevel>) => ({ ...l._attributes }));
166
+ }
167
+ return measurement;
168
+ });
169
+ }
170
+ }
171
+
172
+ if (raw.event.detail.spatial) {
173
+ const spatial = raw.event.detail.spatial;
174
+ feat.properties.spatial = {
175
+ attitude: { ...spatial.attitude._attributes },
176
+ spin: { ...spatial.spin._attributes }
177
+ };
178
+
179
+ if (spatial._attributes?.version !== undefined) {
180
+ feat.properties.spatial.version = spatial._attributes.version;
181
+ }
182
+ }
183
+
94
184
  if (raw.event.detail.range) {
95
185
  feat.properties.range = raw.event.detail.range._attributes.value;
96
186
  }
@@ -15,7 +15,21 @@ import {
15
15
  TrackAttributes,
16
16
  LinkAttributes,
17
17
  SensorAttributes,
18
- VideoAttributes
18
+ VideoAttributes,
19
+ RadSensorDataAttributes,
20
+ RadMeasurementAttributes,
21
+ RadPhysicalModuleAttributes,
22
+ RadSearchAlgorithmAttributes,
23
+ RadSpectrumAttributes,
24
+ RadIsotopeAttributes,
25
+ RadPermissionsAttributes,
26
+ ChemSensorDataAttributes,
27
+ ChemDetectionAttributes,
28
+ BioSensorDataAttributes,
29
+ BioMeasurementAttributes,
30
+ BioMeasurementLevelAttributes,
31
+ SpatialAttitudeAttributes,
32
+ SpatialSpinAttributes
19
33
  } from './types.js';
20
34
 
21
35
  export const Position = Type.Array(Type.Number(), {
@@ -75,6 +89,47 @@ export const FeaturePropertyMission = Type.Object({
75
89
  missionChanges: Type.Optional(Type.Array(FeaturePropertyMissionChange))
76
90
  });
77
91
 
92
+ // === CBRN Sensor GeoJSON Types (flattened - no _attributes wrapper) ===
93
+
94
+ export const FeaturePropertyRadSensorDetail = Type.Object({
95
+ sensor_data: RadSensorDataAttributes,
96
+ radmeasurement: Type.Optional(Type.Array(RadMeasurementAttributes)),
97
+ physical_module: Type.Optional(Type.Array(RadPhysicalModuleAttributes)),
98
+ search_algorithm: Type.Optional(RadSearchAlgorithmAttributes),
99
+ spectrum: Type.Optional(Type.Array(RadSpectrumAttributes)),
100
+ isotope: Type.Optional(Type.Array(RadIsotopeAttributes)),
101
+ data_permissions: Type.Optional(RadPermissionsAttributes),
102
+ command_permissions: Type.Optional(RadPermissionsAttributes)
103
+ });
104
+
105
+ export const FeaturePropertyChemSensorDetail = Type.Object({
106
+ sensor_data: ChemSensorDataAttributes,
107
+ detection: Type.Optional(Type.Array(ChemDetectionAttributes))
108
+ });
109
+
110
+ export const FeaturePropertyBioMeasurementLevel = Type.Object({
111
+ levelName: Type.String(),
112
+ levelValue: Type.String()
113
+ });
114
+
115
+ export const FeaturePropertyBioMeasurement = Type.Composite([
116
+ BioMeasurementAttributes,
117
+ Type.Object({
118
+ level: Type.Optional(Type.Array(BioMeasurementLevelAttributes))
119
+ })
120
+ ]);
121
+
122
+ export const FeaturePropertyBioSensorDetail = Type.Object({
123
+ sensor_data: BioSensorDataAttributes,
124
+ measurement: Type.Optional(Type.Array(FeaturePropertyBioMeasurement))
125
+ });
126
+
127
+ export const FeaturePropertySpatial = Type.Object({
128
+ version: Type.Optional(Type.Number()),
129
+ attitude: SpatialAttitudeAttributes,
130
+ spin: SpatialSpinAttributes
131
+ });
132
+
78
133
  export const Properties = Type.Object({
79
134
  callsign: Type.String({ default: 'UNKNOWN' }),
80
135
  type: Type.String({ default: 'a-f-G' }),
@@ -146,6 +201,10 @@ export const Properties = Type.Object({
146
201
  status: Type.Optional(StatusAttributes),
147
202
  precisionlocation: Type.Optional(PrecisionLocationAttributes),
148
203
  flow: Type.Optional(Type.Record(Type.String(), Type.String())),
204
+ radsensordetail: Type.Optional(FeaturePropertyRadSensorDetail),
205
+ chemsensordetail: Type.Optional(FeaturePropertyChemSensorDetail),
206
+ biosensordetail: Type.Optional(FeaturePropertyBioSensorDetail),
207
+ spatial: Type.Optional(FeaturePropertySpatial),
149
208
  })
150
209
 
151
210
  export const Point = Type.Object({
@@ -394,6 +394,66 @@ export const Sensor = Type.Object({
394
394
  _attributes: SensorAttributes
395
395
  })
396
396
 
397
+ export const SpatialAttitudeAttributes = Type.Object({
398
+ roll: Type.Number({
399
+ description: 'Roll of entity in degrees. Positive indicates listing to the right.'
400
+ }),
401
+ pitch: Type.Number({
402
+ description: 'Pitch of entity in degrees. Positive indicates nose point up.'
403
+ }),
404
+ yaw: Type.Optional(Type.Number({
405
+ description: 'Yaw of entity in degrees. Positive indicates turned to the right.'
406
+ })),
407
+ eRoll: Type.Optional(Type.Number({
408
+ description: '1-sigma error of roll with respect to a zero mean normal Gaussian distribution.'
409
+ })),
410
+ ePitch: Type.Optional(Type.Number({
411
+ description: '1-sigma error of pitch with respect to a zero mean normal Gaussian distribution.'
412
+ })),
413
+ eYaw: Type.Optional(Type.Number({
414
+ description: '1-sigma error of yaw with respect to a zero mean normal Gaussian distribution.'
415
+ }))
416
+ });
417
+
418
+ export const SpatialAttitude = Type.Object({
419
+ _attributes: SpatialAttitudeAttributes
420
+ });
421
+
422
+ export const SpatialSpinAttributes = Type.Object({
423
+ roll: Type.Number({
424
+ description: 'Degrees per second with positive indicating to the pilots right'
425
+ }),
426
+ pitch: Type.Number({
427
+ description: 'Degrees per second with positive indicating nose up.'
428
+ }),
429
+ yaw: Type.Optional(Type.Number({
430
+ description: 'Degrees per second with positive indicating right.'
431
+ })),
432
+ eRoll: Type.Optional(Type.Number({
433
+ description: '1-sigma error of roll with respect to a zero mean normal Gaussian distribution.'
434
+ })),
435
+ ePitch: Type.Optional(Type.Number({
436
+ description: '1-sigma error of pitch with respect to a zero mean normal Gaussian distribution.'
437
+ })),
438
+ eYaw: Type.Optional(Type.Number({
439
+ description: '1-sigma error of yaw with respect to a zero mean normal Gaussian distribution.'
440
+ }))
441
+ });
442
+
443
+ export const SpatialSpin = Type.Object({
444
+ _attributes: SpatialSpinAttributes
445
+ });
446
+
447
+ export const Spatial = Type.Object({
448
+ _attributes: Type.Optional(Type.Object({
449
+ version: Type.Optional(Type.Number({
450
+ description: 'Version tag for this sub schema.'
451
+ }))
452
+ })),
453
+ attitude: SpatialAttitude,
454
+ spin: SpatialSpin
455
+ });
456
+
397
457
  export const VideoAttributes = Type.Object({
398
458
  uid: Type.Optional(Type.String()),
399
459
  sensor: Type.Optional(Type.String()),
@@ -1210,7 +1270,10 @@ export const Detail = Type.Object({
1210
1270
  // CBRN Sensor Details
1211
1271
  radsensordetail: Type.Optional(RadSensorDetail),
1212
1272
  chemsensordetail: Type.Optional(ChemSensorDetail),
1213
- biosensordetail: Type.Optional(BioSensorDetail)
1273
+ biosensordetail: Type.Optional(BioSensorDetail),
1274
+
1275
+ // Spatial information
1276
+ spatial: Type.Optional(Spatial)
1214
1277
  })
1215
1278
 
1216
1279
  export const Point = Type.Object({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tak-ps/node-cot",
3
3
  "type": "module",
4
- "version": "14.39.0",
4
+ "version": "14.40.0",
5
5
  "description": "Lightweight JavaScript library for parsing and manipulating TAK messages",
6
6
  "author": "Nick Ingalls <nick@ingalls.ca>",
7
7
  "types": "index.ts",