- prediction: G-01/G-04/G-05/G-06 위반 분류 + 쌍끌이 공조 탐지 추가 - backend: 모선 확정/제외 API + signal-batch 항적 프록시 + ParentResolution 점수 근거 필드 확장 - frontend: 어구 탐지 그리드 다중필터/지도 flyTo, 후보 검토 패널(점수 근거+확정/제외), 24h convex hull 리플레이 + TripsLayer 애니메이션 - gitignore: 루트 .venv/ 추가
96 lines
2.5 KiB
TypeScript
96 lines
2.5 KiB
TypeScript
/**
|
|
* 수역 코드 카탈로그
|
|
*
|
|
* SSOT: prediction/algorithms/location.py classify_zone()
|
|
* 사용처: GearDetection, RealVesselAnalysis, VesselDetail
|
|
*/
|
|
|
|
import type { BadgeIntent } from '@lib/theme/variants';
|
|
|
|
export type ZoneCode =
|
|
| 'ZONE_I'
|
|
| 'ZONE_II'
|
|
| 'ZONE_III'
|
|
| 'ZONE_IV'
|
|
| 'TERRITORIAL_SEA'
|
|
| 'CONTIGUOUS_ZONE'
|
|
| 'EEZ_OR_BEYOND';
|
|
|
|
interface ZoneCodeMeta {
|
|
code: ZoneCode;
|
|
i18nKey: string;
|
|
fallback: { ko: string; en: string };
|
|
intent: BadgeIntent;
|
|
allowedGears: string[];
|
|
}
|
|
|
|
export const ZONE_CODES: Record<ZoneCode, ZoneCodeMeta> = {
|
|
ZONE_I: {
|
|
code: 'ZONE_I',
|
|
i18nKey: 'zone.ZONE_I',
|
|
fallback: { ko: '특정해역 I (동해)', en: 'Zone I (East Sea)' },
|
|
intent: 'purple',
|
|
allowedGears: ['PS', 'FC'],
|
|
},
|
|
ZONE_II: {
|
|
code: 'ZONE_II',
|
|
i18nKey: 'zone.ZONE_II',
|
|
fallback: { ko: '특정해역 II (남해)', en: 'Zone II (South Sea)' },
|
|
intent: 'info',
|
|
allowedGears: ['PT', 'OT', 'GN', 'PS', 'FC'],
|
|
},
|
|
ZONE_III: {
|
|
code: 'ZONE_III',
|
|
i18nKey: 'zone.ZONE_III',
|
|
fallback: { ko: '특정해역 III (서남해)', en: 'Zone III (Southwest Sea)' },
|
|
intent: 'info',
|
|
allowedGears: ['PT', 'OT', 'GN', 'PS', 'FC'],
|
|
},
|
|
ZONE_IV: {
|
|
code: 'ZONE_IV',
|
|
i18nKey: 'zone.ZONE_IV',
|
|
fallback: { ko: '특정해역 IV (서해)', en: 'Zone IV (West Sea)' },
|
|
intent: 'warning',
|
|
allowedGears: ['GN', 'PS', 'FC'],
|
|
},
|
|
TERRITORIAL_SEA: {
|
|
code: 'TERRITORIAL_SEA',
|
|
i18nKey: 'zone.TERRITORIAL_SEA',
|
|
fallback: { ko: '영해', en: 'Territorial Sea' },
|
|
intent: 'critical',
|
|
allowedGears: [],
|
|
},
|
|
CONTIGUOUS_ZONE: {
|
|
code: 'CONTIGUOUS_ZONE',
|
|
i18nKey: 'zone.CONTIGUOUS_ZONE',
|
|
fallback: { ko: '접속수역', en: 'Contiguous Zone' },
|
|
intent: 'high',
|
|
allowedGears: [],
|
|
},
|
|
EEZ_OR_BEYOND: {
|
|
code: 'EEZ_OR_BEYOND',
|
|
i18nKey: 'zone.EEZ_OR_BEYOND',
|
|
fallback: { ko: 'EEZ 외', en: 'EEZ or Beyond' },
|
|
intent: 'muted',
|
|
allowedGears: [],
|
|
},
|
|
};
|
|
|
|
export function getZoneCodeIntent(code: string): BadgeIntent {
|
|
return ZONE_CODES[code as ZoneCode]?.intent ?? 'muted';
|
|
}
|
|
|
|
export function getZoneCodeLabel(
|
|
code: string,
|
|
t: (k: string, opts?: { defaultValue?: string }) => string,
|
|
lang: 'ko' | 'en' = 'ko',
|
|
): string {
|
|
const meta = ZONE_CODES[code as ZoneCode];
|
|
if (!meta) return code || '-';
|
|
return t(meta.i18nKey, { defaultValue: meta.fallback[lang] });
|
|
}
|
|
|
|
export function getZoneAllowedGears(code: string): string[] {
|
|
return ZONE_CODES[code as ZoneCode]?.allowedGears ?? [];
|
|
}
|