fix(ais): refresh changed static metadata without advancing position

This commit is contained in:
Sameh Khamis committed 2026-10-24 21:29:21 -07:00
1 parent b8f8a8685d
commit 77b485d619
4 files changed
+220 -10

No files matched your search

+50 -10
View File
@@ -43,11 +43,47 @@ export function ingestAisStreamEnvelope(envelope) {
if (!mmsi) return false;
if (messageType === 'ShipStaticData' || messageType === 'StaticDataReport') {
const previous = _aisStreamStatic.get(mmsi) || {};
const live = _aisStreamVessels.get(mmsi);
const liveName = live?.name === `MMSI ${mmsi}` ? '' : live?.name;
const fields =
messageType === 'StaticDataReport'
? {
Name:
message.ReportA?.Valid === false
? undefined
: message.ReportA?.Name,
Type:
message.ReportB?.Valid === false
? undefined
: message.ReportB?.ShipType,
}
: message;
// Static reports may be partial (including Class B's separate A/B parts).
// Keep known values in the cache as well as in the current live row.
const staticData = {
name: vesselNameFromAis(metadata, message, _aisStreamStatic.get(mmsi)),
type: vesselTypeFromAis(message, _aisStreamStatic.get(mmsi)),
destination: stringValue(message.Destination),
imo: stringValue(message.ImoNumber ?? message.IMO),
// The envelope repeats a cached name even on Class B's type-only part.
// Only an actual static name report replaces a known live name.
name:
stringValue(fields.Name ?? fields.ShipName) ||
liveName ||
previous.name ||
stringValue(metadata.ShipName),
type:
staticCode(fields.Type ?? fields.ShipType) ||
staticCode(live?.type) ||
staticCode(previous.type) ||
'',
destination:
stringValue(fields.Destination) ||
live?.destination ||
previous.destination ||
'',
imo:
staticCode(fields.ImoNumber ?? fields.IMO) ||
staticCode(live?.imo) ||
staticCode(previous.imo) ||
'',
};
_aisStreamStatic.set(mmsi, staticData);
mergeAisStaticIntoLiveVessel(mmsi, staticData);
@@ -196,12 +232,10 @@ function approxMetersBetween(lat1, lon1, lat2, lon2) {
function mergeAisStaticIntoLiveVessel(mmsi, staticData) {
const existing = _aisStreamVessels.get(mmsi);
if (!existing) return;
if (staticData.name && (!existing.name || existing.name === `MMSI ${mmsi}`))
existing.name = staticData.name;
if (staticData.type && !existing.type) existing.type = staticData.type;
if (staticData.destination && !existing.destination)
existing.destination = staticData.destination;
if (staticData.imo && !existing.imo) existing.imo = staticData.imo;
if (staticData.name) existing.name = staticData.name;
if (staticData.type) existing.type = staticData.type;
if (staticData.destination) existing.destination = staticData.destination;
if (staticData.imo) existing.imo = staticData.imo;
}
function vesselNameFromAis(metadata, message, staticData = {}) {
@@ -271,6 +305,12 @@ function stringValue(value) {
return String(value).trim();
}
// AIS uses zero for unavailable ship type and IMO, not as a replacement value.
function staticCode(value) {
const number = numberValue(value);
return Number.isInteger(number) && number > 0 ? String(number) : '';
}
function numberValue(value) {
if (value === null || value === undefined || value === '') return null;
const number = Number(value);