@tak-ps/node-cot 14.38.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.
@@ -3,6 +3,12 @@ import { v4 as randomUUID } from 'uuid';
3
3
  import type { Static } from '@sinclair/typebox';
4
4
  import type {
5
5
  LinkAttributes,
6
+ RadMeasurementAttributes,
7
+ RadPhysicalModuleAttributes,
8
+ RadSpectrumAttributes,
9
+ RadIsotopeAttributes,
10
+ ChemDetectionAttributes,
11
+ BioMeasurementLevelAttributes,
6
12
  } from '../types/types.js'
7
13
  import {
8
14
  InputFeature,
@@ -194,6 +200,82 @@ export async function from_geojson(
194
200
  cot.event.detail.sensor = { _attributes: { ...feature.properties.sensor } };
195
201
  }
196
202
 
203
+ if (feature.properties.radsensordetail) {
204
+ const rad = feature.properties.radsensordetail;
205
+ cot.event.detail.radsensordetail = {
206
+ sensor_data: { _attributes: { ...rad.sensor_data } }
207
+ };
208
+
209
+ if (rad.radmeasurement) {
210
+ cot.event.detail.radsensordetail.radmeasurement = rad.radmeasurement.map((m: Static<typeof RadMeasurementAttributes>) => ({ _attributes: { ...m } }));
211
+ }
212
+
213
+ if (rad.physical_module) {
214
+ cot.event.detail.radsensordetail.physical_module = rad.physical_module.map((m: Static<typeof RadPhysicalModuleAttributes>) => ({ _attributes: { ...m } }));
215
+ }
216
+
217
+ if (rad.search_algorithm) {
218
+ cot.event.detail.radsensordetail.search_algorithm = { _attributes: { ...rad.search_algorithm } };
219
+ }
220
+
221
+ if (rad.spectrum) {
222
+ cot.event.detail.radsensordetail.spectrum = rad.spectrum.map((s: Static<typeof RadSpectrumAttributes>) => ({ _attributes: { ...s } }));
223
+ }
224
+
225
+ if (rad.isotope) {
226
+ cot.event.detail.radsensordetail.isotope = rad.isotope.map((i: Static<typeof RadIsotopeAttributes>) => ({ _attributes: { ...i } }));
227
+ }
228
+
229
+ if (rad.data_permissions) {
230
+ cot.event.detail.radsensordetail.data_permissions = { _attributes: { ...rad.data_permissions } };
231
+ }
232
+
233
+ if (rad.command_permissions) {
234
+ cot.event.detail.radsensordetail.command_permissions = { _attributes: { ...rad.command_permissions } };
235
+ }
236
+ }
237
+
238
+ if (feature.properties.chemsensordetail) {
239
+ const chem = feature.properties.chemsensordetail;
240
+ cot.event.detail.chemsensordetail = {
241
+ sensor_data: { _attributes: { ...chem.sensor_data } }
242
+ };
243
+
244
+ if (chem.detection) {
245
+ cot.event.detail.chemsensordetail.detection = chem.detection.map((d: Static<typeof ChemDetectionAttributes>) => ({ _attributes: { ...d } }));
246
+ }
247
+ }
248
+
249
+ if (feature.properties.biosensordetail) {
250
+ const bio = feature.properties.biosensordetail;
251
+ cot.event.detail.biosensordetail = {
252
+ sensor_data: { _attributes: { ...bio.sensor_data } }
253
+ };
254
+
255
+ if (bio.measurement) {
256
+ cot.event.detail.biosensordetail.measurement = bio.measurement.map((m) => {
257
+ const { level, ...attrs } = m;
258
+ const measurement: { _attributes: typeof attrs; level?: Array<{ _attributes: Static<typeof BioMeasurementLevelAttributes> }> } = { _attributes: { ...attrs } };
259
+ if (level) {
260
+ measurement.level = level.map((l: Static<typeof BioMeasurementLevelAttributes>) => ({ _attributes: { ...l } }));
261
+ }
262
+ return measurement;
263
+ });
264
+ }
265
+ }
266
+
267
+ if (feature.properties.spatial) {
268
+ const spatial = feature.properties.spatial;
269
+ cot.event.detail.spatial = {
270
+ attitude: { _attributes: { ...spatial.attitude } },
271
+ spin: { _attributes: { ...spatial.spin } }
272
+ };
273
+
274
+ if (spatial.version !== undefined) {
275
+ cot.event.detail.spatial._attributes = { version: spatial.version };
276
+ }
277
+ }
278
+
197
279
  if (feature.properties.ackrequest) {
198
280
  cot.event.detail.ackrequest = { _attributes: { ...feature.properties.ackrequest } };
199
281
  }
@@ -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({