Skip to content

Commit e1565f6

Browse files
authored
Merge pull request #1 from talentedbrute/spoi_integration
Add sensor FOV visualization using SPOI data
2 parents 87413ba + 2862bae commit e1565f6

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

task.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,52 @@ import { Feature } from '@tak-ps/node-cot';
33
import ETL, { Event, SchemaType, handler as internal, local, DataFlowType, InvocationType } from '@tak-ps/etl';
44
import { fetch } from '@tak-ps/etl';
55

6+
/**
7+
* Calculate the bearing (azimuth) from point 1 to point 2.
8+
* @param lat1 - Latitude of starting point (degrees)
9+
* @param lon1 - Longitude of starting point (degrees)
10+
* @param lat2 - Latitude of destination point (degrees)
11+
* @param lon2 - Longitude of destination point (degrees)
12+
* @returns Bearing in degrees (0-360, where 0 is north)
13+
*/
14+
function calculateBearing(lat1: number, lon1: number, lat2: number, lon2: number): number {
15+
const lat1Rad = lat1 * Math.PI / 180;
16+
const lat2Rad = lat2 * Math.PI / 180;
17+
const deltaLon = (lon2 - lon1) * Math.PI / 180;
18+
19+
const x = Math.sin(deltaLon) * Math.cos(lat2Rad);
20+
const y = Math.cos(lat1Rad) * Math.sin(lat2Rad) -
21+
Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLon);
22+
23+
const bearing = Math.atan2(x, y) * 180 / Math.PI;
24+
25+
// Normalize to 0-360
26+
return (bearing + 360) % 360;
27+
}
28+
29+
/**
30+
* Calculate the distance between two points using Haversine formula.
31+
* @param lat1 - Latitude of point 1 (degrees)
32+
* @param lon1 - Longitude of point 1 (degrees)
33+
* @param lat2 - Latitude of point 2 (degrees)
34+
* @param lon2 - Longitude of point 2 (degrees)
35+
* @returns Distance in meters
36+
*/
37+
function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
38+
const R = 6371000; // Earth's radius in meters
39+
40+
const lat1Rad = lat1 * Math.PI / 180;
41+
const lat2Rad = lat2 * Math.PI / 180;
42+
const deltaLat = (lat2 - lat1) * Math.PI / 180;
43+
const deltaLon = (lon2 - lon1) * Math.PI / 180;
44+
45+
const a = Math.sin(deltaLat / 2) ** 2 +
46+
Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.sin(deltaLon / 2) ** 2;
47+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
48+
49+
return R * c;
50+
}
51+
652
const DroneSenseLocation = Type.Object({
753
id: Type.String(),
854
callSign: Type.String(),
@@ -130,6 +176,38 @@ export default class Task extends ETL {
130176
}
131177
}
132178

179+
// Add sensor FOV when SPOI (Sensor Point of Interest) data is available
180+
// SPOI indicates where the drone's camera is pointing
181+
if (record.spoiLat !== 0 && record.spoiLng !== 0) {
182+
const azimuth = calculateBearing(
183+
record.latitude, record.longitude,
184+
record.spoiLat, record.spoiLng
185+
);
186+
const range = calculateDistance(
187+
record.latitude, record.longitude,
188+
record.spoiLat, record.spoiLng
189+
);
190+
191+
feat.properties.sensor = {
192+
azimuth: azimuth,
193+
fov: 45,
194+
vfov: 45,
195+
range: range,
196+
elevation: 0,
197+
roll: 0,
198+
displayMagneticReference: 0,
199+
strokeColor: -16777216,
200+
strokeWeight: 0.5,
201+
fovRed: 1.0,
202+
fovGreen: 0.5,
203+
fovBlue: 0.0,
204+
fovAlpha: 0.3,
205+
rangeLines: 100,
206+
rangeLineStrokeColor: -16777216,
207+
rangeLineStrokeWeight: 1.0
208+
};
209+
}
210+
133211
fc.features.push(feat);
134212
}
135213

0 commit comments

Comments
 (0)