64 lines
2.4 KiB
TypeScript
64 lines
2.4 KiB
TypeScript
import type { AisTarget } from '../../../entities/aisTarget/model/types';
|
|
import type { LegacyVesselInfo } from '../../../entities/legacyVessel/model/types';
|
|
import { SIGNAL_KIND, SIGNAL_SOURCE_AIS, type LiveShipFeature, type SignalKindCode } from '../model/liveShip.types';
|
|
|
|
function mapVesselTypeToSignalKind(vesselType: string | undefined): SignalKindCode {
|
|
if (!vesselType) return SIGNAL_KIND.NORMAL;
|
|
const vt = vesselType.toLowerCase();
|
|
if (vt.includes('fishing')) return SIGNAL_KIND.FISHING;
|
|
if (vt.includes('passenger')) return SIGNAL_KIND.PASSENGER;
|
|
if (vt.includes('cargo')) return SIGNAL_KIND.CARGO;
|
|
if (vt.includes('tanker')) return SIGNAL_KIND.TANKER;
|
|
if (vt.includes('military') || vt.includes('law') || vt.includes('government')) return SIGNAL_KIND.GOV;
|
|
if (vt.includes('buoy')) return SIGNAL_KIND.BUOY;
|
|
return SIGNAL_KIND.NORMAL;
|
|
}
|
|
|
|
function mapLegacyShipCodeToSignalKind(shipCode: string | undefined): SignalKindCode {
|
|
if (!shipCode) return SIGNAL_KIND.NORMAL;
|
|
if (shipCode === 'FC') return SIGNAL_KIND.CARGO;
|
|
return SIGNAL_KIND.FISHING;
|
|
}
|
|
|
|
export function toLiveShipFeature(target: AisTarget, legacy: LegacyVesselInfo | undefined | null): LiveShipFeature {
|
|
const targetId = String(target.mmsi);
|
|
const signalKindCode = legacy
|
|
? mapLegacyShipCodeToSignalKind(legacy.shipCode)
|
|
: mapVesselTypeToSignalKind(target.vesselType);
|
|
|
|
return {
|
|
mmsi: target.mmsi,
|
|
featureId: `${SIGNAL_SOURCE_AIS}${targetId}`,
|
|
targetId,
|
|
originalTargetId: targetId,
|
|
signalSourceCode: SIGNAL_SOURCE_AIS,
|
|
signalKindCode,
|
|
shipName: (target.name || '').trim(),
|
|
longitude: target.lon,
|
|
latitude: target.lat,
|
|
sog: Number.isFinite(target.sog) ? target.sog : 0,
|
|
cog: Number.isFinite(target.cog) ? target.cog : 0,
|
|
heading: Number.isFinite(target.heading) ? target.heading : 0,
|
|
messageTimestamp: target.messageTimestamp || target.receivedDate || new Date().toISOString(),
|
|
nationalCode: legacy ? 'CN' : '',
|
|
vesselType: target.vesselType,
|
|
raw: target,
|
|
};
|
|
}
|
|
|
|
export function toLiveShipFeatures(
|
|
targets: AisTarget[],
|
|
legacyHits?: Map<number, LegacyVesselInfo> | null,
|
|
): LiveShipFeature[] {
|
|
const out: LiveShipFeature[] = [];
|
|
|
|
for (const target of targets) {
|
|
if (!target) continue;
|
|
if (!Number.isFinite(target.mmsi)) continue;
|
|
if (!Number.isFinite(target.lon) || !Number.isFinite(target.lat)) continue;
|
|
out.push(toLiveShipFeature(target, legacyHits?.get(target.mmsi) ?? null));
|
|
}
|
|
|
|
return out;
|
|
}
|