커밋 그래프

5 커밋

작성자 SHA1 메시지 날짜
6f4044ce39 feat: MapLibre → deck.gl 전면 전환 + 어구 서브클러스터 구조 개선
- 실시간 선박 13K: MapLibre symbol → deck.gl IconLayer (useShipDeckLayers + shipDeckStore)
- 선단/어구 폴리곤: MapLibre Source/Layer → deck.gl GeoJsonLayer (useFleetClusterDeckLayers)
- 선박 팝업: MapLibre Popup → React 오버레이 (ShipPopupOverlay + ShipHoverTooltip)
- 리플레이 집중 모드 (focusMode), 라벨 클러스터링, fontScale 연동
- Python: group_key 고정 + sub_cluster_id 분리, 한국 국적 어구 오탐 제외
- DB: sub_cluster_id 컬럼 추가 + 기존 '#N' 데이터 마이그레이션
- Backend: DISTINCT ON CTE로 서브클러스터 중복 제거, subClusterId DTO 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 15:44:09 +09:00
bbbc326e38 refactor: FleetClusterLayer 10파일 분리 + deck.gl 리플레이 기반 구축
FleetClusterLayer.tsx 2357줄 → 10개 파일 분리:
- fleetClusterTypes/Utils/Constants: 타입, 기하 함수, 모델 상수
- useFleetClusterGeoJson: 27개 useMemo GeoJSON 훅
- FleetClusterMapLayers: MapLibre Source/Layer JSX
- CorrelationPanel/HistoryReplayController: 패널 서브컴포넌트
- GearGroupSection/FleetGearListPanel: 좌측 목록 (DRY)
- FleetClusterLayer: 오케스트레이터 524줄

deck.gl + Zustand 리플레이 기반 (Phase 0~2):
- zustand 5.0.12, @deck.gl/geo-layers 9.2.11 설치
- gearReplayStore: Zustand + rAF 애니메이션 루프
- gearReplayPreprocess: TripsLayer 전처리 + cursor O(1) 보간
- useGearReplayLayers: deck.gl 레이어 빌더 (10fps 스로틀)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 07:44:07 +09:00
8f9b347e1f feat: 폴리곤 히스토리 애니메이션 + 어구 추적 안정화
- FleetClusterLayer: 12시간 타임라인 기반 폴리곤 재생 애니메이션
  - 중심 이동 궤적 (점선) + 어구별 개별 궤적 (실선)
  - 가상 어구/선박 아이콘 COG 회전 + 스냅샷 동기화
  - 재생 컨트롤러: 재생/일시정지 + 프로그레스 바 (드래그/클릭)
  - 신호없음 구간: 마지막 유효 스냅샷 유지 + 회색 점선 표시
  - 히스토리 모드 시 현재 강조 레이어 (deck.gl + MapLibre) 숨김
  - ESC 키: 히스토리 닫기 + 선택 해제
- polygon_builder: STALE_SEC 3600→21600 (6시간, 어구 P75 갭 3.5h 커버)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 07:33:48 +09:00
4c22d5f1f9 fix(prediction): 어구그룹 탐지 — 전체 AIS 선박 대상으로 확장
- detect_gear_groups: vessel_dfs(분류 대상만) → vessel_store.get_all_latest_positions()(전체 14K선박)
- build_all_group_snapshots: 동일하게 all_positions 기반으로 전환
- vessel_store: get_all_latest_positions() 메서드 추가
- 결과: 0 gear groups → 210 gear groups (GEAR_IN_ZONE 57, GEAR_OUT_ZONE 45)
2026-03-24 14:17:44 +09:00
2441e3068a feat(prediction): 선단/어구그룹 폴리곤 서버사이드 생성 + PostGIS 저장
- DB migration 009: group_polygon_snapshots 테이블 (PostGIS geometry)
- polygon_builder.py: Shapely 기반 convex hull + buffer 폴리곤 생성
- scheduler.py: 5분 주기 분석 사이클에 폴리곤 생성 Step 4.5 통합
- fleet_tracker.py: get_company_vessels() 메서드 추가
- kcgdb.py: save_group_snapshots(), cleanup_group_snapshots() 추가
- requirements.txt: shapely>=2.0 추가
2026-03-24 13:30:31 +09:00