mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
fix(ais): refresh changed static metadata without advancing position
This commit is contained in:
1 parent
b8f8a8685d
commit
77b485d619
4 files changed
+220
-10
No files matched your search
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user