release: 중국어선감시 연결선 폭발 수정 #95
@ -100,47 +100,44 @@ export function ChineseFishingOverlay({ ships }: Props) {
|
||||
}));
|
||||
}, [chineseFishing]);
|
||||
|
||||
// 조업 중인 선박만 (어구 아이콘 표시용)
|
||||
const operating = useMemo(() => analyzed.filter(a => a.analysis.isOperating), [analyzed]);
|
||||
// 조업 중인 선박만 (어구 아이콘 표시용, 최대 100척)
|
||||
const operating = useMemo(() => analyzed.filter(a => a.analysis.isOperating).slice(0, 100), [analyzed]);
|
||||
|
||||
// 어구/어망 → 모선 연결 탐지
|
||||
// 어구/어망 → 모선 연결 탐지 (거리 제한 + 정확 매칭 우선)
|
||||
const gearLinks: GearToParentLink[] = useMemo(() => {
|
||||
// 어구/어망 선박 (이름_숫자_ 또는 이름% 패턴)
|
||||
const gearPattern = /^.+_\d+_\d*$|%$/;
|
||||
const gearShips = ships.filter(s => gearPattern.test(s.name));
|
||||
|
||||
if (gearShips.length === 0) return [];
|
||||
|
||||
// 모선 후보 (모든 선박의 이름 → Ship 매핑)
|
||||
// 모선 후보
|
||||
const nameMap = new Map<string, Ship>();
|
||||
for (const s of ships) {
|
||||
if (!gearPattern.test(s.name) && s.name) {
|
||||
// 정확한 이름 매핑
|
||||
nameMap.set(s.name.trim(), s);
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_DIST_DEG = 0.15; // ~10NM — 이 이상 떨어지면 연결 안 함
|
||||
const MAX_LINKS = 200; // 브라우저 성능 보호
|
||||
|
||||
const links: GearToParentLink[] = [];
|
||||
for (const gear of gearShips) {
|
||||
if (links.length >= MAX_LINKS) break;
|
||||
|
||||
const parentName = extractParentName(gear.name);
|
||||
if (!parentName) continue;
|
||||
if (!parentName || parentName.length < 3) continue; // 너무 짧은 이름 제외
|
||||
|
||||
// 정확히 일치하는 모선 찾기
|
||||
let parent = nameMap.get(parentName);
|
||||
// 정확 매칭만 (부분 매칭 제거 — 오탐 원인)
|
||||
const parent = nameMap.get(parentName);
|
||||
if (!parent) continue;
|
||||
|
||||
// 정확 매칭 없으면 부분 매칭 (앞부분이 같은 선박)
|
||||
if (!parent) {
|
||||
for (const [name, ship] of nameMap) {
|
||||
if (name.startsWith(parentName) || parentName.startsWith(name)) {
|
||||
parent = ship;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 거리 제한: ~10NM 이내만 연결
|
||||
const dlat = Math.abs(gear.lat - parent.lat);
|
||||
const dlng = Math.abs(gear.lng - parent.lng);
|
||||
if (dlat > MAX_DIST_DEG || dlng > MAX_DIST_DEG) continue;
|
||||
|
||||
if (parent) {
|
||||
links.push({ gear, parent, parentName });
|
||||
}
|
||||
links.push({ gear, parent, parentName });
|
||||
}
|
||||
return links;
|
||||
}, [ships]);
|
||||
@ -227,8 +224,8 @@ export function ChineseFishingOverlay({ ships }: Props) {
|
||||
);
|
||||
})}
|
||||
|
||||
{/* 본선/부속선/어선 역할 라벨 */}
|
||||
{analyzed.filter(a => a.role.role).map(({ ship, role }) => (
|
||||
{/* 본선/부속선/어선 역할 라벨 (본선/부속/운반만, 최대 100개) */}
|
||||
{analyzed.filter(a => a.role.role && a.role.role !== 'FV').slice(0, 100).map(({ ship, role }) => (
|
||||
<Marker key={`role-${ship.mmsi}`} longitude={ship.lng} latitude={ship.lat} anchor="top">
|
||||
<div style={{
|
||||
marginTop: 6,
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user