2026-01-30 13:01:54 +09:00
|
|
|
# CLAUDE.md - GIS 함정용 프로젝트 가이드
|
|
|
|
|
|
2026-02-04 08:16:29 +09:00
|
|
|
## 응답 규칙
|
|
|
|
|
- **모든 응답은 반드시 한글로 작성한다.**
|
|
|
|
|
|
2026-01-30 13:01:54 +09:00
|
|
|
## 프로젝트 개요
|
|
|
|
|
|
|
|
|
|
| 항목 | 내용 |
|
|
|
|
|
|------|------|
|
|
|
|
|
| 프로젝트명 | dark (GIS 함정용) |
|
|
|
|
|
| 참조 프로젝트 | mda-react-front (메인 프로젝트) |
|
|
|
|
|
| 목적 | 선박위치정보 전시 및 조회 기능 프론트엔드 |
|
2026-02-04 08:16:29 +09:00
|
|
|
| 현재 단계 | Phase 6 진행 중 - 리플레이 기능 구현 완료 |
|
2026-01-30 13:01:54 +09:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 메인 프로젝트(mda-react-front) 기술 스택
|
|
|
|
|
|
|
|
|
|
| 항목 | 기술 |
|
|
|
|
|
|------|------|
|
|
|
|
|
| 지도 엔진 | OpenLayers 9.2.4 |
|
|
|
|
|
| 실시간 렌더링 | Deck.gl 9.0.38 (GPU) |
|
|
|
|
|
| UI 프레임워크 | React 18.2.0 |
|
|
|
|
|
| 상태 관리 | Zustand 4.5.2 |
|
|
|
|
|
| 라우팅 | React Router 6.15.0 |
|
|
|
|
|
| 데이터 페칭 | React Query 4.32.6 |
|
|
|
|
|
| 실시간 통신 | STOMP WebSocket |
|
|
|
|
|
| 번들러 | Vite 5.2.10 |
|
|
|
|
|
| 타입 | TypeScript 5.0.2 |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 현재 프로젝트(dark) 기술 스택
|
|
|
|
|
|
2026-02-04 08:16:29 +09:00
|
|
|
| 항목 | 기술 |
|
|
|
|
|
|------|------|
|
|
|
|
|
| 번들러 | Vite 5.2.10 |
|
|
|
|
|
| 언어 | JavaScript (TypeScript 도입 검토) |
|
|
|
|
|
| UI | React 18.2.0 |
|
|
|
|
|
| 라우팅 | React Router 6.30.3 |
|
|
|
|
|
| 상태관리 | Zustand 4.5.2 (subscribeWithSelector) |
|
|
|
|
|
| 지도 엔진 | OpenLayers 9.2.4 |
|
|
|
|
|
| 선박 렌더링 | Deck.gl 9.2.6 (core, layers, extensions) |
|
|
|
|
|
| 실시간 통신 | @stomp/stompjs (STOMP WebSocket) |
|
|
|
|
|
| HTTP | Axios 1.4.0 |
|
|
|
|
|
| 스타일 | SCSS |
|
2026-01-30 13:01:54 +09:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-02-04 08:16:29 +09:00
|
|
|
## 프로젝트 구조
|
2026-01-30 13:01:54 +09:00
|
|
|
|
|
|
|
|
```
|
|
|
|
|
src/
|
|
|
|
|
├── index.js # 앱 엔트리 포인트
|
|
|
|
|
├── App.jsx # 라우트 정의
|
|
|
|
|
│
|
2026-02-04 08:16:29 +09:00
|
|
|
├── publish/ # [퍼블리싱 원본] - 직접 수정 금지, 참조용
|
2026-01-30 13:01:54 +09:00
|
|
|
│
|
2026-02-04 08:16:29 +09:00
|
|
|
├── pages/ # [구현 페이지]
|
|
|
|
|
│ └── HomePage.jsx # 메인 페이지 (지도 + 레이아웃)
|
2026-01-30 13:01:54 +09:00
|
|
|
│
|
2026-02-04 08:16:29 +09:00
|
|
|
├── components/
|
|
|
|
|
│ ├── layout/ # Header, Sidebar, ToolBar, MainLayout, SideNav
|
|
|
|
|
│ ├── ship/ # ShipLegend, ShipDetailModal, ShipContextMenu, TrackQueryModal
|
|
|
|
|
│ └── map/ # TopBar (좌표/시간표시, 검색), PatrolShipSelector (함정선택)
|
2026-01-30 13:01:54 +09:00
|
|
|
│
|
|
|
|
|
├── map/ # [지도 모듈]
|
2026-02-04 08:16:29 +09:00
|
|
|
│ ├── MapContainer.jsx # OpenLayers + Deck.gl 통합 (window.__mainMap__)
|
|
|
|
|
│ ├── ShipBatchRenderer.js # 배치 렌더러 (적응형 렌더링, 필터 캐시)
|
|
|
|
|
│ └── layers/
|
|
|
|
|
│ ├── baseLayer.js # 베이스맵 (worldMap, eastAsiaMap, korMap)
|
|
|
|
|
│ ├── shipLayer.js # Deck.gl 선박 레이어 (아이콘, 라벨, 벡터, 신호상태)
|
|
|
|
|
│ └── trackLayer.js # 항적 레이어
|
2026-01-30 13:01:54 +09:00
|
|
|
│
|
|
|
|
|
├── stores/ # [Zustand 스토어]
|
2026-02-04 08:16:29 +09:00
|
|
|
│ ├── shipStore.js # 선박 데이터 (핵심 - mutable Map/Set + 버전 카운터)
|
|
|
|
|
│ ├── mapStore.js # 지도 상태
|
|
|
|
|
│ ├── trackStore.js # 항적 상태
|
|
|
|
|
│ └── trackingModeStore.js # 추적 모드 (지도/선박 모드, 반경 설정)
|
2026-01-30 13:01:54 +09:00
|
|
|
│
|
2026-02-04 08:16:29 +09:00
|
|
|
├── tracking/ # [항적조회 패키지] - 메인 프로젝트 TS→JS 변환
|
|
|
|
|
│ ├── stores/ # trackQueryStore, trackQueryAnimationStore
|
|
|
|
|
│ ├── services/ # trackQueryApi (API + 통합선박 처리)
|
|
|
|
|
│ ├── components/ # TrackQueryViewer, TrackQueryTimeline, GlobalTrackQueryViewer
|
|
|
|
|
│ ├── hooks/ # useEquipmentFilter, useTrackHighlight
|
|
|
|
|
│ ├── utils/ # trackQueryLayerUtils, TrackQueryBatchRenderer, shipIconUtil
|
|
|
|
|
│ └── types/ # trackQuery.types.js
|
2026-01-30 13:01:54 +09:00
|
|
|
│
|
2026-02-04 08:16:29 +09:00
|
|
|
├── replay/ # [리플레이 패키지] - 메인 프로젝트 TS→JS 변환
|
|
|
|
|
│ ├── stores/ # replayStore, animationStore, mergedTrackStore, playbackTrailStore
|
|
|
|
|
│ ├── services/ # ReplayWebSocketService (WebSocket 청크 수신)
|
|
|
|
|
│ ├── components/ # ReplayTimeline, ReplayControlV2, VesselListManager
|
|
|
|
|
│ ├── hooks/ # useReplayLayer (Deck.gl 레이어 관리)
|
|
|
|
|
│ ├── utils/ # replayLayerRegistry
|
|
|
|
|
│ └── types/ # replay.types.js
|
2026-01-30 13:01:54 +09:00
|
|
|
│
|
2026-02-04 08:16:29 +09:00
|
|
|
├── hooks/ # useShipData, useShipLayer, useShipSearch, useTrackingMode, useRadiusFilter
|
|
|
|
|
├── api/ # signalApi
|
|
|
|
|
├── common/ # stompClient (STOMP WebSocket)
|
|
|
|
|
├── types/ # constants.js (신호원/선종/플래그 상수)
|
|
|
|
|
├── assets/ # 이미지, 아이콘 아틀라스
|
|
|
|
|
└── scss/ # 스타일
|
2026-01-30 13:01:54 +09:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 라우팅 구조
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
/ → 메인 (지도)
|
|
|
|
|
├── /ship → 선박 조회
|
|
|
|
|
├── /satellite → 위성
|
|
|
|
|
├── /weather → 기상
|
|
|
|
|
├── /analysis → 분석
|
|
|
|
|
├── /settings → 설정
|
|
|
|
|
└── /mypage → 마이페이지
|
|
|
|
|
|
|
|
|
|
/publish → 퍼블리싱 미리보기
|
|
|
|
|
├── /publish/panel1 → 선박 패널
|
|
|
|
|
├── /publish/panel2 → 위성 패널
|
|
|
|
|
├── /publish/panel3 → 기상 패널
|
|
|
|
|
├── /publish/panel4 → 분석 패널
|
|
|
|
|
├── /publish/panel5 → 타임라인
|
|
|
|
|
├── /publish/panel6 → AI모드
|
|
|
|
|
├── /publish/panel7 → 리플레이
|
|
|
|
|
├── /publish/panel8 → 항적조회
|
|
|
|
|
└── /publish/... → 기타 퍼블리시 페이지
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 기능 구현 로드맵
|
|
|
|
|
|
2026-02-04 08:16:29 +09:00
|
|
|
### Phase 1: 기반 구축 (01-26 완료)
|
|
|
|
|
- [x] CRA → Vite 마이그레이션
|
|
|
|
|
- [x] 프로젝트 구조 재편 (퍼블리시/구현 분리)
|
|
|
|
|
- [x] Zustand 스토어 설정 (mapStore, shipStore)
|
|
|
|
|
- [x] 기본 레이아웃 구현 (MainLayout, Header, Sidebar, ToolBar)
|
|
|
|
|
|
|
|
|
|
### Phase 2: 지도 및 선박 표시 (01-26 완료)
|
|
|
|
|
- [x] OpenLayers 맵 컨테이너 + 베이스맵 레이어
|
|
|
|
|
- [x] STOMP WebSocket 클라이언트
|
|
|
|
|
- [x] Deck.gl 선박 아이콘 레이어 (IconLayer + 아틀라스)
|
|
|
|
|
- [x] 선박 범례 컴포넌트 (ShipLegend)
|
|
|
|
|
|
|
|
|
|
### Phase 3: 선박 레이어 고도화 (01-27 완료)
|
|
|
|
|
- [x] 신호상태(AVETDR) 아이콘, 속도벡터 좌표 투영
|
|
|
|
|
- [x] 배치 렌더러 최적화 (ShipBatchRenderer)
|
|
|
|
|
- [x] 선명표시 클러스터링, 선박통합 ON/OFF
|
|
|
|
|
|
|
|
|
|
### Phase 4: shipStore 성능 최적화 + 카운트 동기화 (01-28~30 완료)
|
|
|
|
|
- [x] Map/Set mutable update + 버전 카운터 패턴
|
|
|
|
|
- [x] 카운트 5초 쓰로틀 + targetId 중복 제거
|
|
|
|
|
- [x] 레이더 카운트 제외 (통합 여부 무관)
|
|
|
|
|
- [x] Ctrl+Drag 박스 선택 + 우클릭 컨텍스트 메뉴
|
|
|
|
|
- [x] 통합모드 전환 시 selectedShipIds 동기화
|
|
|
|
|
|
|
|
|
|
### Phase 5: 항적조회 + 버그 수정 (02-02~03 완료)
|
|
|
|
|
- [x] tracking 패키지 TS→JS 변환 (13개 파일)
|
|
|
|
|
- [x] 모달 항적조회 + 우클릭 항적조회
|
|
|
|
|
- [x] 라이브 연결선 (PathStyleExtension dash + 1초 인터벌)
|
|
|
|
|
- [x] 레이더 타겟 통합 표시 버그 수정 (integrate 플래그 기반)
|
|
|
|
|
|
|
|
|
|
### Phase 6: 리플레이 기능 (02-03 완료)
|
|
|
|
|
- [x] replay 패키지 TS→JS 변환 (stores, components, hooks, services, utils, types)
|
|
|
|
|
- [x] WebSocket 기반 청크 데이터 수신 (ReplayWebSocketService)
|
|
|
|
|
- [x] 시간 기반 애니메이션 (재생/일시정지/정지, 배속 1x~1000x)
|
|
|
|
|
- [x] 프로그레스 바 슬라이더 (CSS 변수 방식, thumb/progress/배경 동기화)
|
|
|
|
|
- [x] 항적 표시 토글 (playbackTrailStore - 프레임 기반 페이딩)
|
|
|
|
|
- [x] 선박 상태 관리 (기본/선택/삭제) + 필터링 (선종, 신호원)
|
|
|
|
|
- [x] 드래그 가능한 타임라인 컨트롤러
|
|
|
|
|
- [x] 닫기 시 초기화 (라이브 선박 복원)
|
|
|
|
|
|
|
|
|
|
### Phase 6.5: TopBar 및 추적 모드 (02-04 완료)
|
|
|
|
|
- [x] TopBar 컴포넌트 (좌표 표시, 시간 표시, 선박 검색)
|
|
|
|
|
- [x] 좌표/시간 포맷 설정 드롭다운 (도분초/도, KST/UTC)
|
|
|
|
|
- [x] 선박 검색 기능 (like 검색, 디바운싱, 통합모드 지원)
|
|
|
|
|
- [x] 추적 모드 구현 (trackingModeStore)
|
|
|
|
|
- 지도 모드 / 선박 모드 전환 (라디오 버튼)
|
|
|
|
|
- 경비함정 선택 드롭다운 (PatrolShipSelector)
|
|
|
|
|
- 반경 설정 (10/25/50/100/200 NM)
|
|
|
|
|
- [x] 반경 필터링 (useRadiusFilter, ShipBatchRenderer)
|
|
|
|
|
- Bounding Box 사전 필터 + Haversine 거리 계산
|
|
|
|
|
- 렌더링, 카운트, 검색 결과 모두 반경 내 선박만 표시
|
|
|
|
|
- [x] 추적 함정 지도 따라가기 (useTrackingMode)
|
|
|
|
|
- 반경 원 표시 (OpenLayers VectorLayer)
|
|
|
|
|
- 지도 중심 자동 이동
|
|
|
|
|
- [x] 추적 함정 아이콘 강조 (ScatterplotLayer - 시안색 마커)
|
|
|
|
|
- [x] 컨텍스트 메뉴 반경설정 (경비함정 우클릭 → 반경설정 서브메뉴)
|
|
|
|
|
|
|
|
|
|
### Phase 7: 미구현 (예정)
|
|
|
|
|
- [ ] 동적 우선순위 (Dynamic Priority) - 계획 수립 완료 (`.claude/plans/`)
|
|
|
|
|
- [ ] 퍼블리시 → 구현 전환 (Panel1~8, 기능 페이지)
|
2026-01-30 13:01:54 +09:00
|
|
|
- [ ] 기상 레이어
|
|
|
|
|
- [ ] 관심영역 설정
|
|
|
|
|
- [ ] 위성 영상
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 메인 프로젝트 참조 파일
|
|
|
|
|
|
|
|
|
|
### 지도 초기화
|
|
|
|
|
- `mda-react-front/src/map/MainMapContext.tsx` - OpenLayers 맵 초기화
|
|
|
|
|
|
|
|
|
|
### 레이어 설정
|
|
|
|
|
- `mda-react-front/src/common/mapLayer.ts` - 베이스맵 타일
|
|
|
|
|
- `mda-react-front/src/common/targetLayer.ts` - 선박 레이어
|
|
|
|
|
- `mda-react-front/src/common/deck.ts` - Deck.gl 설정
|
|
|
|
|
|
|
|
|
|
### 상태 관리
|
|
|
|
|
- `mda-react-front/src/shared/model/` - Zustand 스토어
|
|
|
|
|
|
|
|
|
|
### 스타일
|
|
|
|
|
- `mda-react-front/src/map/control.css` - 지도 컨트롤 스타일
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 개발 명령어
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-02-04 08:16:29 +09:00
|
|
|
# 개발 서버 실행 (Vite, http://localhost:3000)
|
|
|
|
|
npm run dev
|
2026-01-30 13:01:54 +09:00
|
|
|
|
|
|
|
|
# 프로덕션 빌드
|
|
|
|
|
npm run build
|
|
|
|
|
|
2026-02-04 08:16:29 +09:00
|
|
|
# 환경별 빌드
|
|
|
|
|
npm run build:dev
|
|
|
|
|
npm run build:prod
|
|
|
|
|
|
|
|
|
|
# 빌드 미리보기
|
|
|
|
|
npm run preview
|
|
|
|
|
|
|
|
|
|
# 린트
|
|
|
|
|
npm run lint
|
2026-01-30 13:01:54 +09:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 세션 관리
|
|
|
|
|
|
|
|
|
|
- 세션 핸드오버: `.claude/SESSION_HANDOVER.md`
|
|
|
|
|
- 자동 요약: 컨텍스트 95% 도달 시 자동 저장
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 변경 이력
|
|
|
|
|
|
|
|
|
|
| 날짜 | 내용 |
|
|
|
|
|
|------|------|
|
2026-02-04 08:16:29 +09:00
|
|
|
| 2026-02-04 | Phase 6.5 완료 (TopBar, 추적 모드, 반경 필터링) |
|
|
|
|
|
| 2026-02-03 | Phase 6 완료 (리플레이 기능 구현) |
|
|
|
|
|
| 2026-02-03 | Phase 5 완료 (항적조회, 레이더 통합 버그 수정), CLAUDE.md 현황 동기화 |
|
|
|
|
|
| 2026-01-30 | Phase 4 완료 (shipStore 성능 최적화, 카운트 동기화) |
|
|
|
|
|
| 2026-01-27 | Phase 2~3 완료 (지도, 선박 레이어 고도화) |
|
|
|
|
|
| 2026-01-26 | 초기 프로젝트 분석 및 워크플로우 정의, Phase 1 완료 |
|