AIS fix
This commit is contained in:
@@ -48,16 +48,6 @@ let airTraffic: AirTrafficLayer
|
|||||||
let aisLayer: AISLayer
|
let aisLayer: AISLayer
|
||||||
let range: RangeLayer
|
let range: RangeLayer
|
||||||
|
|
||||||
const hourTickIndices = computed(() => {
|
|
||||||
const indices: number[] = []
|
|
||||||
let lastHour = -1
|
|
||||||
radarFrames.value.forEach((f, i) => {
|
|
||||||
const h = new Date(f.time * 1000).getHours()
|
|
||||||
if (h !== lastHour) { indices.push(i); lastHour = h }
|
|
||||||
})
|
|
||||||
return indices
|
|
||||||
})
|
|
||||||
|
|
||||||
function buildWindSrc(lat: number, lon: number, zoom: number) {
|
function buildWindSrc(lat: number, lon: number, zoom: number) {
|
||||||
return `https://embed.windy.com/embed2.html?lat=${lat.toFixed(4)}&lon=${lon.toFixed(4)}&detailLat=${lat.toFixed(4)}&detailLon=${lon.toFixed(4)}&zoom=${Math.round(zoom)}&level=surface&overlay=wind&product=ecmwf&menu=&message=&marker=&calendar=now&pressure=&type=map&location=coordinates&detail=&metricWind=kt&metricTemp=%C2%B0C&radarRange=-1`
|
return `https://embed.windy.com/embed2.html?lat=${lat.toFixed(4)}&lon=${lon.toFixed(4)}&detailLat=${lat.toFixed(4)}&detailLon=${lon.toFixed(4)}&zoom=${Math.round(zoom)}&level=surface&overlay=wind&product=ecmwf&menu=&message=&marker=&calendar=now&pressure=&type=map&location=coordinates&detail=&metricWind=kt&metricTemp=%C2%B0C&radarRange=-1`
|
||||||
}
|
}
|
||||||
@@ -98,29 +88,15 @@ function seekRadar(index: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSliderInput(e: Event) {
|
|
||||||
seekRadar(Number((e.target as HTMLInputElement).value))
|
|
||||||
}
|
|
||||||
|
|
||||||
function frameLabel(frame: { time: number }) {
|
|
||||||
return new Date(frame.time * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
|
||||||
}
|
|
||||||
|
|
||||||
function hourLabel(frame: { time: number }) {
|
|
||||||
return new Date(frame.time * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false })
|
|
||||||
}
|
|
||||||
|
|
||||||
function tickPercent(index: number) {
|
|
||||||
return (index / (radarFrames.value.length - 1)) * 100
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleAT() {
|
function toggleAT() {
|
||||||
if(atActive.value) {
|
if(atActive.value) {
|
||||||
aisLayer.hide()
|
aisLayer.hide()
|
||||||
airTraffic.hide()
|
airTraffic.hide()
|
||||||
|
range.hide()
|
||||||
} else {
|
} else {
|
||||||
aisLayer.show()
|
aisLayer.show()
|
||||||
airTraffic.show()
|
airTraffic.show()
|
||||||
|
range.show()
|
||||||
}
|
}
|
||||||
atActive.value = !atActive.value
|
atActive.value = !atActive.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,62 +2,81 @@ import {cfg} from './config.mjs';
|
|||||||
|
|
||||||
const CHANNEL_MAP = {0: 'A, B', 1: 'A', 2: 'B'};
|
const CHANNEL_MAP = {0: 'A, B', 1: 'A', 2: 'B'};
|
||||||
const SENDER_TYPE = {
|
const SENDER_TYPE = {
|
||||||
0: 'Unknown',
|
0: 'Other', 1: 'Unknown', 2: 'Cargo', 3: 'Class B',
|
||||||
1: 'Base Station',
|
4: 'Passenger', 5: 'Special', 6: 'Tanker', 7: 'High Speed',
|
||||||
2: 'Class A',
|
8: 'Fishing', 9: 'Aircraft', 10: 'Helicopter', 11: 'Base Station',
|
||||||
3: 'Class B',
|
12: 'AtoN', 13: 'SART/EPIRB'
|
||||||
4: 'SAR Aircraft',
|
|
||||||
5: 'Aid to Navigation',
|
|
||||||
6: 'Class B CS',
|
|
||||||
7: 'Sart/Epirb/MOB'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function decodeMsgTypes(status_raw) {
|
function decodeMsgTypes(raw) {
|
||||||
const types = [];
|
const types = [];
|
||||||
for (let i = 0; i < 32; i++) {
|
for (let i = 0; i < 32; i++) {
|
||||||
if (status_raw & (1 << i)) types.push(i);
|
if (raw & (1 << i)) types.push(i);
|
||||||
}
|
}
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function decodeFlags(flags) {
|
||||||
|
return {
|
||||||
|
validated: flags & 3,
|
||||||
|
validated2: (flags & 3) == 2 ? -1 : flags & 3,
|
||||||
|
repeat: (flags >> 2) & 3,
|
||||||
|
virtual_aid: (flags >> 4) & 1,
|
||||||
|
approx: (flags >> 5) & 1,
|
||||||
|
channels: (flags >> 6) & 15,
|
||||||
|
cs_unit: (flags >> 10) & 3,
|
||||||
|
raim: (flags >> 12) & 3,
|
||||||
|
dte: (flags >> 14) & 3,
|
||||||
|
assigned: (flags >> 16) & 3,
|
||||||
|
display: (flags >> 18) & 3,
|
||||||
|
dsc: (flags >> 20) & 3,
|
||||||
|
band: (flags >> 22) & 3,
|
||||||
|
msg22: (flags >> 24) & 3,
|
||||||
|
off_position: (flags >> 26) & 3,
|
||||||
|
maneuver: (flags >> 28) & 3,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export async function getAIS() {
|
export async function getAIS() {
|
||||||
const {ADSB_URL} = cfg();
|
const {ADSB_URL} = cfg();
|
||||||
if(!ADSB_URL) return {data: []};
|
if (!ADSB_URL) return {data: []};
|
||||||
const r = await fetch(`${ADSB_URL}:9990/api/ships_array.json`);
|
const r = await fetch(`${ADSB_URL}:9990/api/ships_array.json`);
|
||||||
const {dynamic, static: staticRows} = await r.json();
|
const {dynamic, static: staticRows, time} = await r.json();
|
||||||
|
|
||||||
const staticMap = new Map(staticRows.map(row => [row[0], row]));
|
const staticMap = new Map(staticRows.map(row => [row[0], row]));
|
||||||
|
|
||||||
const boats = dynamic.map(row => {
|
return dynamic.map(row => {
|
||||||
const [
|
const [mmsi, lat, lon, distance, bearing, heading,
|
||||||
mmsi, lat, lon, distance, bearing,
|
cog, speed, status, rrsi, ppm, count, msg_type,
|
||||||
speed, heading, course,
|
last_signal, last_group, group_mask, flags, altitude,
|
||||||
unknownA, rssi, drift, count,
|
received_stations, mmsi_type, shipclass, country] = row;
|
||||||
channelsMaybe, unknown, unknownB, unknownC, receiver, sender,
|
|
||||||
unknownD, altitude, unknownE, unknownF, unknownG, country,
|
|
||||||
// Known missing: sender_type, last_signal, in_range,
|
|
||||||
] = row;
|
|
||||||
|
|
||||||
const s = staticMap.get(mmsi) ?? [];
|
const s = staticMap.get(mmsi) ?? [];
|
||||||
const [
|
const [_mmsi, shipname, callsign, destination, shiptype,
|
||||||
_mmsi, name, name2, name3,
|
imo, to_bow, to_stern, to_port, to_starboard, draught,
|
||||||
unknown1, unknown2, unknown3, unknown4, unknown5, unknown6, unknown7, unknown8, unknown9, unknown10, unknown11
|
eta_month, eta_day, eta_hour, eta_minute] = s;
|
||||||
] = s;
|
|
||||||
|
const f = decodeFlags(flags);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mmsi, type: SENDER_TYPE[sender_type],
|
mmsi,
|
||||||
|
type: SENDER_TYPE[shipclass],
|
||||||
lat, lon, altitude,
|
lat, lon, altitude,
|
||||||
heading, drift, speed,
|
heading, cog, speed,
|
||||||
distance, bearing, course,
|
distance, bearing,
|
||||||
destination, eta,
|
destination,
|
||||||
rssi, count, receiver, sources,
|
rrsi, ppm, count,
|
||||||
msg_type: decodeMsgTypes(status_raw),
|
msg_type: decodeMsgTypes(msg_type),
|
||||||
channels: CHANNEL_MAP[channels] ?? channels,
|
channels: CHANNEL_MAP[f.channels] ?? f.channels,
|
||||||
ship_type, imo, draught,
|
...f,
|
||||||
country, callsign, name: name || name2 || name3,
|
shiptype, imo, draught,
|
||||||
last_signal, in_range
|
country, callsign,
|
||||||
|
shipname,
|
||||||
|
to_bow, to_stern, to_port, to_starboard,
|
||||||
|
eta_month, eta_day, eta_hour, eta_minute,
|
||||||
|
last_signal: last_signal ? time - last_signal : null,
|
||||||
|
last_group, group_mask,
|
||||||
|
received_stations, shipclass,
|
||||||
|
status
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return boats;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user