release: 어구 그룹핑 조건 추가 #137

병합
htlee develop 에서 main 로 2 commits 를 머지했습니다 2026-03-20 18:50:38 +09:00
2개의 변경된 파일21개의 추가작업 그리고 1개의 파일을 삭제

파일 보기

@ -82,8 +82,11 @@ export function AnalysisStatsPanel({ stats, lastUpdated, isLoading, analysisMap,
const gearStats = useMemo(() => {
const source = allShips ?? ships;
const gearPattern = /^(.+?)_\d+_\d+_?$/;
const STALE_MS = 60 * 60_000; // 60분 이내만
const now = Date.now();
const parentMap = new Map<string, number>();
for (const s of source) {
if (now - s.lastSeen > STALE_MS) continue;
const m = (s.name || '').match(gearPattern);
if (m) {
const parent = m[1].trim();

파일 보기

@ -127,6 +127,10 @@ export function FleetClusterLayer({ ships, analysisMap, clusters, onShipSelect,
// 비허가 어구 클러스터: parentName → { parent: Ship | null, gears: Ship[] }
const gearGroupMap = useMemo(() => {
const gearPattern = /^(.+?)_\d+_\d+_?$/;
const MAX_DIST_DEG = 0.15; // ~10NM — 모선과 어구 간 최대 거리
const STALE_MS = 60 * 60_000; // 60분 이내 수신 신호만
const now = Date.now();
const nameToShip = new Map<string, Ship>();
for (const s of ships) {
const nm = (s.name || '').trim();
@ -134,12 +138,25 @@ export function FleetClusterLayer({ ships, analysisMap, clusters, onShipSelect,
nameToShip.set(nm, s);
}
}
const map = new Map<string, { parent: Ship | null; gears: Ship[] }>();
for (const s of ships) {
// 60분 이내 수신 신호만
if (now - s.lastSeen > STALE_MS) continue;
const m = (s.name || '').match(gearPattern);
if (!m) continue;
const parentName = m[1].trim();
const entry = map.get(parentName) ?? { parent: nameToShip.get(parentName) ?? null, gears: [] };
const parent = nameToShip.get(parentName) ?? null;
// 모선이 있으면 거리 제한 적용
if (parent) {
const dlat = Math.abs(s.lat - parent.lat);
const dlng = Math.abs(s.lng - parent.lng);
if (dlat > MAX_DIST_DEG || dlng > MAX_DIST_DEG) continue;
}
const entry = map.get(parentName) ?? { parent, gears: [] };
entry.gears.push(s);
map.set(parentName, entry);
}