Merge pull request 'release: 어구 거리제한' (#139) from develop into main
All checks were successful
Deploy KCG / deploy (push) Successful in 1m58s
All checks were successful
Deploy KCG / deploy (push) Successful in 1m58s
This commit is contained in:
커밋
db352946ae
@ -127,8 +127,8 @@ 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 MAX_DIST_DEG = 0.15; // ~10NM
|
||||
const STALE_MS = 60 * 60_000;
|
||||
const now = Date.now();
|
||||
|
||||
const nameToShip = new Map<string, Ship>();
|
||||
@ -139,26 +139,35 @@ export function FleetClusterLayer({ ships, analysisMap, clusters, onShipSelect,
|
||||
}
|
||||
}
|
||||
|
||||
const map = new Map<string, { parent: Ship | null; gears: Ship[] }>();
|
||||
// 1단계: 같은 모선명 어구 수집 (60분 이내만)
|
||||
const rawGroups = new Map<string, 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 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 arr = rawGroups.get(parentName) ?? [];
|
||||
arr.push(s);
|
||||
rawGroups.set(parentName, arr);
|
||||
}
|
||||
|
||||
const entry = map.get(parentName) ?? { parent, gears: [] };
|
||||
entry.gears.push(s);
|
||||
map.set(parentName, entry);
|
||||
// 2단계: 거리 기반 서브 클러스터링 (같은 이름이라도 멀면 분리)
|
||||
const map = new Map<string, { parent: Ship | null; gears: Ship[] }>();
|
||||
for (const [parentName, gears] of rawGroups) {
|
||||
const parent = nameToShip.get(parentName) ?? null;
|
||||
|
||||
// 기준점: 모선 있으면 모선 위치, 없으면 첫 어구
|
||||
const anchor = parent ?? gears[0];
|
||||
if (!anchor) continue;
|
||||
|
||||
const nearby = gears.filter(g => {
|
||||
const dlat = Math.abs(g.lat - anchor.lat);
|
||||
const dlng = Math.abs(g.lng - anchor.lng);
|
||||
return dlat <= MAX_DIST_DEG && dlng <= MAX_DIST_DEG;
|
||||
});
|
||||
|
||||
if (nearby.length === 0) continue;
|
||||
map.set(parentName, { parent, gears: nearby });
|
||||
}
|
||||
return map;
|
||||
}, [ships]);
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user