wing-gis/ARCHITECTURE.md
htlee b9d924e81e chore: 팀 워크플로우 기반 초기 프로젝트 구성
WING-GIS 해양경찰 통합 GIS 위치정보시스템.
모노레포: frontend(React 19 + MapLibre + deck.gl) + services(Spring Boot + Gradle).

- npm + Nexus 프록시 레지스트리 설정
- 팀 워크플로우 v1.6.1 부트스트랩 파일 배치
- .githooks (commit-msg, post-checkout)
- custom_pre_commit: true (모노레포 pre-commit 별도 관리)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 12:36:38 +09:00

36 KiB

WING-GIS Architecture Design

해양경찰청 통합 GIS 위치정보시스템


1. System Overview

                         WING-GIS System Architecture
                         ============================

  [Browser / ECDIS / Mobile]
           |
           v
  +-----------------+     +------------------+     +------------------+
  | React 19 SPA    |     |  Nginx / Gateway |     |   Keycloak SSO   |
  | MapLibre+deck.gl|<--->|  (API Gateway)   |<--->|  (INR-04 Auth)   |
  | (wing-gis-web)  |     |                  |     |                  |
  +-----------------+     +------------------+     +------------------+
                                   |
                    +--------------+--------------+
                    |              |              |
              +-----v----+  +-----v----+  +------v-----+
              |  GIS API  |  | Vessel   |  | Analysis   |
              |  Service  |  | Signal   |  | Service    |
              | (SFR-01~  |  | Service  |  | (SFR-09)   |
              |  SFR-04)  |  | (SFR-05~ |  +------+-----+
              +-----+----+  |  SFR-08)  |         |
                    |        +-----+----+         |
                    |              |              |
              +-----v--------------v--------------v-----+
              |          PostgreSQL + PostGIS            |
              |         (wing_gis_db / wing_vessel_db)  |
              +-----------------------------------------+
                    |              |
              +-----v----+  +-----v-----------+
              |  Redis    |  | Kafka / RabbitMQ|
              |  (Cache)  |  | (Signal Stream) |
              +----------+  +-----------------+

2. Technology Stack

Frontend (구현 완료)

Category Technology Version Purpose
Framework React 19.x SPA UI
Language TypeScript 5.9 Type safety
Map Engine MapLibre GL JS 5.18 ENC 전자해도 렌더링
Map Overlay deck.gl (MapboxOverlay) 9.2 선박 아이콘 WebGL 렌더링
State Zustand 5.x 경량 상태 관리
UI Library Ant Design 6.x 해경 UI 컴포넌트 (일부 사용)
API Client Axios + fetch - 서버 통신
WebSocket STOMP.js 7.x 실시간 물표 수신 (예정)
Build Vite 8.x 빌드 도구
Chart ECharts 6.x 통계/분석 차트 (예정)
ENC Tiles gcnautical.com - S-57 전자해도 벡터 타일

Backend

Category Technology Version Purpose
Framework Spring Boot 3.3.x MSA 서비스
Language Java 21 (LTS) 백엔드 로직
ORM JPA/Hibernate + QueryDSL - DB 접근
GIS GeoTools 31.x S-57/S-101 파싱
API Docs SpringDoc (OpenAPI 3) - INR-05 API 명세
Security Spring Security + Keycloak - SSO/GPKI (INR-04)
Message Kafka / RabbitMQ - 물표 스트리밍
Cache Redis 7.x 물표 캐시
Container Docker + K8s - ECR-01 MSA 인프라

Database

Category Technology Purpose
Main DB PostgreSQL 16 + PostGIS 3.4 공간데이터 저장
Tile Cache pg_tileserv / Martin 벡터 타일 서빙
Time Series TimescaleDB (확장) 물표 이력/항적
File Storage MinIO (S3 호환) SHP/GeoJSON 업로드

3. MSA Service Decomposition (ECR-01)

wing-gis/
├── services/
│   ├── wing-gis-gateway/        # API Gateway (Spring Cloud Gateway)
│   ├── wing-gis-auth/           # 인증/권한 (INR-04: SSO, GPKI)
│   ├── wing-gis-map/            # 통합 GIS 서비스 (SFR-01~04)
│   ├── wing-gis-vessel/         # 물표/선박 신호 (SFR-05~06, SFR-08)
│   ├── wing-gis-layer/          # 레이어 관리 (SFR-07)
│   ├── wing-gis-analysis/       # 분석 서비스 (SFR-09)
│   ├── wing-gis-integration/    # 통합연계모듈 (SFR-06, SFR-10)
│   ├── wing-gis-admin/          # 관리도구
│   └── wing-gis-mcp/            # MCP 에이전트 (INR-06: LLM 연계)
├── frontend/
│   └── wing-gis-web/            # React SPA
├── infra/
│   ├── docker-compose.yml       # 개발환경
│   ├── k8s/                     # 운영환경 K8s 매니페스트
│   └── sql/                     # DB 초기화 스크립트
└── docs/
    └── api/                     # API 명세서

4. Frontend Structure (React) — 현재 구현 상태

wing-gis-web/src/
├── App.tsx                              # 루트 (레이아웃 + useAisPolling)
├── main.tsx                             # 엔트리 포인트
├── App.css                              # 디자인 토큰 (CSS 변수)
│
├── components/
│   ├── layout/                          # ✅ 5-패널 레이아웃
│   │   ├── TitleBar.tsx                 # 상단 헤더
│   │   ├── SubToolbar.tsx               # 컨텍스트별 도구 모음
│   │   ├── Sidebar.tsx                  # 좌측 (검색, 레이어 트리)
│   │   ├── RightPanel.tsx               # 우측 (물표현황 실데이터/경보/해양정보)
│   │   └── BottomBar.tsx                # 하단 상태바
│   ├── map/                             # ✅ MapLibre GL JS + deck.gl 기반
│   │   ├── MapViewML.tsx                # 맵 컨테이너 + deck.gl 콜백 (툴팁/클릭)
│   │   ├── MapTools.tsx                 # 확대/축소/초기화
│   │   ├── BaseMapSelector.tsx          # 배경지도 탭
│   │   ├── ScaleBar.tsx                 # 축척바
│   │   ├── MapLegend.tsx                # 물표 범례 (실시간 AIS 카운트)
│   │   └── CoordStatusBar.tsx           # 좌표/줌 상태바
│   └── vessel/                          # ✅ 선박 UI
│       ├── VesselPopup.tsx              # 선박 미니 팝업
│       ├── VesselSearch.tsx             # 선박 통합 검색 (SFR-08)
│       └── VesselSignalToggle.tsx       # 신호 소스 ON/OFF 토글
│
├── features/
│   ├── vesselLayer/                     # ✅ AIS 실시간 + 비AIS 더미 렌더링
│   │   ├── hooks/
│   │   │   └── useVesselDeckLayer.ts    # AIS+비AIS deck.gl 레이어 통합
│   │   └── lib/
│   │       ├── aisAdapter.ts            # AisTarget → AisFeature 변환
│   │       ├── aisDeckLayers.ts         # AIS IconLayer + halo + overlay
│   │       ├── aisIcons.ts              # SignalKindCode별 SVG 아이콘 8종
│   │       ├── shipTooltip.ts           # 호버 툴팁 HTML (사진 썸네일 포함)
│   │       ├── ShipBatchRenderer.ts     # 뷰포트 컬링 + 밀도 제어 (제네릭)
│   │       ├── vesselAdapter.ts         # 비AIS Vessel → VesselFeature
│   │       ├── vesselDeckLayers.ts      # 비AIS deck.gl 레이어
│   │       └── vesselIcons.ts           # 비AIS VesselSource별 아이콘
│   ├── nauticalChart/                   # ✅ ENC 전자해도 오버레이
│   │   ├── hooks/useNauticalChartOverlay.ts
│   │   ├── lib/fetchNauticalStyle.ts    # gcnautical.com 스타일 fetch
│   │   ├── lib/nauticalLayerManager.ts  # 레이어 주입/제거/S-52 테마
│   │   ├── model/types.ts               # S52Theme, NauticalChartSettings
│   │   └── ui/NauticalChartToggle.tsx   # ENC on/off + 주간/황혼/야간
│   └── shipImage/                       # ✅ 선박 사진 (호버 썸네일 + 클릭 모달)
│       ├── api/shipImageApi.ts          # 이미지 API + URL 유틸
│       └── ui/ShipImageModal.tsx        # 사진 뷰어 모달 (네비게이션+캐러셀)
│
├── hooks/
│   ├── useMap.ts                        # ✅ MapLibre + MapboxOverlay 초기화
│   ├── useDeckLayers.ts                 # ✅ deck.gl 레이어 + getTooltip/onClick
│   ├── useStore.ts                      # ✅ Zustand (vessels, aisTargets, signalState...)
│   ├── useAisPolling.ts                 # ✅ AIS REST 폴링 (60분→1분→2시간 프루닝)
│   └── useVesselStream.ts              # ⏳ STOMP WebSocket (백엔드 연동 시)
│
├── services/
│   ├── aisApi.ts                        # ✅ /signal-batch/api/v2/vessels/recent-positions
│   ├── api.ts                           # Axios 인스턴스
│   └── vesselApi.ts                     # 물표 CRUD API
│
├── types/
│   ├── ais.ts                           # ✅ SignalKindCode 8종, AisTarget, DTO, 색상맵
│   ├── vessel.ts                        # Vessel, VesselSource 7종
│   └── layer.ts                         # LayerGroup, S100_PRODUCTS
│
├── utils/
│   ├── coordinate.ts                    # DMS 변환, 축척 계산
│   ├── s52Colors.ts                     # S-52 수심 색상 팔레트
│   └── vesselIcon.ts                    # 범용 SVG 아이콘 생성
│
├── lib/map/
│   ├── mapCore.ts                       # kickRepaint, onMapStyleReady
│   ├── mapConstants.ts                  # 기본 좌표, 줌, OSM 폴백 스타일
│   └── MaplibreDeckCustomLayer.ts       # Globe 모드용 커스텀 레이어 (예비)
│
├── context/MapContext.tsx               # mapRef, overlayRef 전달
└── data/mockVessels.ts                  # 비AIS 더미 데이터

구현 상태 범례

  • 구현 완료 (실동작)
  • 코드 준비됨, 백엔드 연동 대기

미구현 (향후 개발)

  • components/layer/ — LayerTree, LayerUpload, LayerStyle (SLD 편집)
  • components/analysis/ — AnalysisTabs, BufferAnalysis, HeatmapAnalysis
  • components/admin/ — UserManage, IntegrationStatus, AuditLog
  • components/common/ — LoginModal (SSO/GPKI), NotificationBell
  • hooks/useAuth.ts, hooks/useLayer.ts
  • services/layerApi.ts, services/analysisApi.ts, services/authApi.ts
  • types/s100.ts, types/auth.ts
  • React Router 라우팅

5. Backend Structure (Spring Boot)

wing-gis-map/                    # 대표 서비스 구조
├── src/main/java/kr/go/kcg/wingis/
│   ├── WingGisMapApplication.java
│   ├── config/
│   │   ├── SecurityConfig.java
│   │   ├── CorsConfig.java
│   │   ├── WebSocketConfig.java
│   │   └── PostgisConfig.java
│   ├── domain/
│   │   ├── vessel/
│   │   │   ├── Vessel.java          # Entity
│   │   │   ├── VesselTrack.java     # 항적 Entity
│   │   │   ├── VesselRepository.java
│   │   │   ├── VesselService.java
│   │   │   └── VesselController.java
│   │   ├── layer/
│   │   │   ├── Layer.java
│   │   │   ├── LayerGroup.java
│   │   │   ├── S100Layer.java       # S-100 전용
│   │   │   ├── LayerRepository.java
│   │   │   ├── LayerService.java
│   │   │   └── LayerController.java
│   │   ├── chart/
│   │   │   ├── ChartDataset.java    # S-101 ENC 데이터셋
│   │   │   ├── ChartFeature.java    # 해도 피처
│   │   │   └── ChartService.java
│   │   ├── boundary/
│   │   │   ├── Boundary.java        # EEZ/NLL/관할구역
│   │   │   └── BoundaryService.java
│   │   ├── analysis/
│   │   │   ├── AnalysisResult.java
│   │   │   ├── AnalysisService.java
│   │   │   └── AnalysisController.java
│   │   └── user/
│   │       ├── User.java
│   │       └── UserService.java
│   ├── integration/                 # SFR-06 통합연계모듈
│   │   ├── ais/
│   │   │   ├── AisReceiver.java     # AIS 수신기
│   │   │   └── AisDecoder.java      # NMEA 디코더
│   │   ├── vpass/
│   │   │   └── VPassClient.java
│   │   ├── vts/
│   │   │   └── VtsRadarClient.java
│   │   ├── lrit/
│   │   │   └── LritClient.java
│   │   └── DataFusionEngine.java    # 물표 융합 엔진
│   ├── dto/
│   │   ├── VesselDto.java
│   │   ├── LayerDto.java
│   │   └── SearchDto.java
│   └── exception/
│       └── GlobalExceptionHandler.java
├── src/main/resources/
│   ├── application.yml
│   ├── application-dev.yml
│   └── application-prod.yml
├── build.gradle
└── Dockerfile

6. Database Schema (PostgreSQL + PostGIS)

Core Tables

-- 물표/선박
CREATE TABLE vessel (
    id              BIGSERIAL PRIMARY KEY,
    mmsi            VARCHAR(20) UNIQUE,
    imo             VARCHAR(20),
    name            VARCHAR(100),
    callsign        VARCHAR(20),
    ship_type       VARCHAR(50),
    flag            VARCHAR(5),
    gt              DECIMAL,
    dwt             DECIMAL,
    loa             DECIMAL,
    beam            DECIMAL,
    draft           DECIMAL,
    status          VARCHAR(30),
    source          VARCHAR(20),       -- AIS/V-Pass/VTS/RADAR/E-NAV/VHF-DSC
    position        GEOMETRY(Point, 4326),
    sog             DECIMAL,
    cog             DECIMAL,
    heading         DECIMAL,
    nav_status      VARCHAR(30),
    destination     VARCHAR(100),
    eta             TIMESTAMP,
    last_updated    TIMESTAMP DEFAULT NOW(),
    created_at      TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_vessel_position ON vessel USING GIST(position);
CREATE INDEX idx_vessel_mmsi ON vessel(mmsi);
CREATE INDEX idx_vessel_source ON vessel(source);

-- 항적 (TimescaleDB hypertable 권장)
CREATE TABLE vessel_track (
    id              BIGSERIAL,
    vessel_id       BIGINT REFERENCES vessel(id),
    position        GEOMETRY(Point, 4326),
    sog             DECIMAL,
    cog             DECIMAL,
    heading         DECIMAL,
    recorded_at     TIMESTAMP NOT NULL,
    PRIMARY KEY (id, recorded_at)
);

CREATE INDEX idx_track_vessel ON vessel_track(vessel_id, recorded_at DESC);
CREATE INDEX idx_track_position ON vessel_track USING GIST(position);

-- 레이어
CREATE TABLE layer_group (
    id              SERIAL PRIMARY KEY,
    name            VARCHAR(100),
    parent_id       INTEGER REFERENCES layer_group(id),
    sort_order      INTEGER DEFAULT 0,
    icon            VARCHAR(10),
    is_system       BOOLEAN DEFAULT FALSE
);

CREATE TABLE layer (
    id              BIGSERIAL PRIMARY KEY,
    group_id        INTEGER REFERENCES layer_group(id),
    name            VARCHAR(200),
    layer_type      VARCHAR(30),      -- VECTOR/RASTER/WMS/S100
    s100_product    VARCHAR(10),      -- S-101/S-102/S-104/S-111/S-122/S-124/S-127/S-412
    geometry_type   VARCHAR(20),      -- POINT/LINE/POLYGON
    srid            INTEGER DEFAULT 4326,
    style_sld       TEXT,
    min_scale       INTEGER,
    max_scale       INTEGER,
    is_visible      BOOLEAN DEFAULT TRUE,
    is_default_on   BOOLEAN DEFAULT FALSE,
    feature_count   INTEGER DEFAULT 0,
    source_url      VARCHAR(500),
    created_by      BIGINT,
    created_at      TIMESTAMP DEFAULT NOW()
);

-- S-100 전자해도 데이터셋
CREATE TABLE chart_dataset (
    id              BIGSERIAL PRIMARY KEY,
    cell_name       VARCHAR(20),      -- KR4G3A40
    product         VARCHAR(10),      -- S-101, S-102, ...
    edition         INTEGER,
    update_num      INTEGER,
    scale           INTEGER,
    status          VARCHAR(20),      -- CURRENT/SUPERSEDED/NEW
    coverage        GEOMETRY(Polygon, 4326),
    fc_version      VARCHAR(20),
    pc_version      VARCHAR(20),
    feature_count   INTEGER,
    file_path       VARCHAR(500),
    issued_date     DATE,
    created_at      TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_chart_coverage ON chart_dataset USING GIST(coverage);

-- 해도 피처
CREATE TABLE chart_feature (
    id              BIGSERIAL PRIMARY KEY,
    dataset_id      BIGINT REFERENCES chart_dataset(id),
    feature_type    VARCHAR(50),      -- Lighthouse/DepthArea/Buoy/...
    feature_name_ko VARCHAR(200),
    feature_name_en VARCHAR(200),
    geometry        GEOMETRY(Geometry, 4326),
    attributes      JSONB,            -- S-101 속성 (유연한 구조)
    scamin          INTEGER,
    created_at      TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_feature_geom ON chart_feature USING GIST(geometry);
CREATE INDEX idx_feature_type ON chart_feature(feature_type);
CREATE INDEX idx_feature_attrs ON chart_feature USING GIN(attributes);

-- 경계/관할구역
CREATE TABLE boundary (
    id              SERIAL PRIMARY KEY,
    name            VARCHAR(100),
    boundary_type   VARCHAR(30),      -- EEZ/NLL/TERRITORIAL/JURISDICTION
    geometry        GEOMETRY(MultiPolygon, 4326),
    organization    VARCHAR(100),
    attributes      JSONB
);

CREATE INDEX idx_boundary_geom ON boundary USING GIST(geometry);

-- 분석 결과
CREATE TABLE analysis_result (
    id              BIGSERIAL PRIMARY KEY,
    analysis_type   VARCHAR(50),      -- ILLEGAL_FISHING/TRANSSHIP/DARK_VESSEL/...
    name            VARCHAR(200),
    geometry        GEOMETRY(Geometry, 4326),
    result_data     JSONB,
    confidence      DECIMAL,
    status          VARCHAR(20),
    created_by      BIGINT,
    created_at      TIMESTAMP DEFAULT NOW(),
    expires_at      TIMESTAMP
);

-- 사용자
CREATE TABLE app_user (
    id              BIGSERIAL PRIMARY KEY,
    username        VARCHAR(50) UNIQUE NOT NULL,
    name            VARCHAR(50),
    department      VARCHAR(100),
    organization    VARCHAR(100),     -- 지방청/해양경찰서
    role            VARCHAR(30),      -- ADMIN/OPERATOR/VIEWER
    jurisdiction_id INTEGER REFERENCES boundary(id),
    sso_id          VARCHAR(100),
    gpki_dn         VARCHAR(500),
    is_active       BOOLEAN DEFAULT TRUE,
    last_login      TIMESTAMP,
    created_at      TIMESTAMP DEFAULT NOW()
);

-- 경보/알림
CREATE TABLE alert (
    id              BIGSERIAL PRIMARY KEY,
    alert_type      VARCHAR(30),      -- SOS/ZONE_VIOLATION/SIGNAL_LOST/...
    severity        VARCHAR(10),      -- CRITICAL/WARNING/INFO
    title           VARCHAR(200),
    description     TEXT,
    vessel_id       BIGINT REFERENCES vessel(id),
    position        GEOMETRY(Point, 4326),
    is_acknowledged BOOLEAN DEFAULT FALSE,
    acknowledged_by BIGINT REFERENCES app_user(id),
    created_at      TIMESTAMP DEFAULT NOW()
);

-- 감사 로그
CREATE TABLE audit_log (
    id              BIGSERIAL PRIMARY KEY,
    user_id         BIGINT REFERENCES app_user(id),
    action          VARCHAR(50),
    target_type     VARCHAR(50),
    target_id       VARCHAR(50),
    detail          JSONB,
    ip_address      VARCHAR(45),
    created_at      TIMESTAMP DEFAULT NOW()
);

7. API Endpoints (RESTful)

Vessel API (SFR-05, SFR-08)

GET    /api/v1/vessels                    # 물표 목록 (필터/페이징)
GET    /api/v1/vessels/{mmsi}             # 물표 상세
GET    /api/v1/vessels/{mmsi}/tracks      # 항적 조회
GET    /api/v1/vessels/search?q=          # 통합 검색 (SFR-08)
GET    /api/v1/vessels/bbox?bbox=         # 영역 내 물표
WS     /ws/vessels                        # 실시간 물표 스트림

Layer API (SFR-03, SFR-07)

GET    /api/v1/layers                     # 레이어 트리
POST   /api/v1/layers/upload              # 레이어 업로드
PUT    /api/v1/layers/{id}/style          # SLD 스타일 변경
GET    /api/v1/layers/{id}/features       # 피처 조회
DELETE /api/v1/layers/{id}                # 레이어 삭제

Chart API (SFR-04)

GET    /api/v1/charts                     # S-100 데이터셋 목록
GET    /api/v1/charts/{cellName}/features # 해도 피처
GET    /api/v1/charts/tile/{z}/{x}/{y}    # 벡터 타일

Analysis API (SFR-09)

POST   /api/v1/analysis/buffer            # 버퍼 분석
POST   /api/v1/analysis/heatmap           # 히트맵
POST   /api/v1/analysis/upload            # 결과 업로드
GET    /api/v1/analysis/results           # 결과 목록

Auth API (INR-04)

POST   /api/v1/auth/login                 # 로그인
POST   /api/v1/auth/sso                   # SSO 인증
POST   /api/v1/auth/gpki                  # GPKI 인증
GET    /api/v1/auth/me                    # 현재 사용자
POST   /api/v1/auth/logout                # 로그아웃

8. S-100 Product Specification Support Matrix

8.1 Specification Inventory

본 사업에서 지원하는 IHO S-100 기반 제품 규격과 보유 문서 현황:

S-100 Product Version Full Name PS FC PC DCEG Validation Sample
S-100 Ed.5.2.1 (Dec 2025) Universal Hydrographic Data Model PDF - Lua/XSLT - S-158-100 v1.0.0 -
S-101 Ed.2.0.0 Electronic Navigational Chart (ENC) PDF XML 2.0.0 ZIP 2.0.0 PDF 2.0.0 S-158-101 v1.1.0 -
S-102 Ed.3.0.0 Bathymetric Surface PDF XML 3.0.0 ZIP 3.0.0 - S-158-102 v1.0.0 -
S-104 Ed.2.0.0 Water Level Information PDF XML 2.0.0 - - - -
S-111 Ed.2.0.0 Surface Currents PDF XML 2.0.0 ZIP 2.0.0 - - -
S-122 Ed.1.0.0 Marine Protected Areas (MPA) ZIP XML 1.0.0 - - - ZIP
S-123 Ed.1.0.0 Marine Radio Services (MRS) ZIP XML 1.0.0 - - - ZIP
S-124 Ed.2.0.0 Navigational Warnings PDF XML 2.0.0 ZIP 2.0.0 PDF 2.0.0 - -
S-127 Ed.1.0.0 Marine Traffic Management PDF ZIP 1.0.0 - - - ZIP

참조 경로: /Documents/GIS/S-100 Specifications/{S-1xx}/

8.2 Service-to-Product Mapping

각 백엔드 서비스가 담당하는 S-100 제품과 구체적 활용 범위:

┌─────────────────────────────────────────────────────────────────────────┐
│                        wing-gis-map (GIS API)                          │
│                                                                         │
│  S-101 ENC Ed.2.0.0 ─── 전자해도 렌더링, 피처 조회, Edition 관리       │
│    ├─ FC 2.0.0 ── FeatureType 정의 (DepthArea, Lighthouse, Buoy...)   │
│    ├─ PC 2.0.0 ── S-52 Portrayal 렌더링 규칙                          │
│    ├─ DCEG 2.0.0 ── 피처 속성 검증 (Data Capture Encoding Guide)      │
│    └─ S-158-101 ── 데이터 품질 검증 (Validation Checks)               │
│                                                                         │
│  S-102 Bathymetric Ed.3.0.0 ─── 수심 격자 데이터 표출                  │
│    ├─ FC 3.0.0 ── BAG 수심 피처 정의                                   │
│    └─ PC 3.0.0 ── 수심 음영/등심선 색상 팔레트                         │
│                                                                         │
│  S-104 Water Level Ed.2.0.0 ─── 실시간 조석/수위 오버레이              │
│    └─ FC 2.0.0 ── 조석 관측점/예측 격자 피처 정의                      │
│                                                                         │
│  S-111 Surface Currents Ed.2.0.0 ─── 해류 벡터/격자 오버레이           │
│    ├─ FC 2.0.0 ── 해류 벡터 피처 정의                                  │
│    └─ PC 2.0.0 ── 해류 화살표/색상 렌더링 규칙                         │
│                                                                         │
│  S-122 MPA Ed.1.0.0 ─── 해양보호구역 경계 표출                         │
│    └─ FC 1.0.0 ── 보호구역 등급/경계 피처 정의                         │
│                                                                         │
│  S-123 MRS Ed.1.0.0 ─── 해양무선 커버리지 표출                         │
│    └─ FC 1.0.0 ── VHF/MF/HF 무선 범위 피처 정의                       │
│                                                                         │
│  S-124 Nav Warnings Ed.2.0.0 ─── 항행경보 구역 실시간 표출             │
│    ├─ FC 2.0.0 ── 경보 구역/유형 피처 정의                             │
│    ├─ PC 2.0.0 ── 경보 심볼/색상 렌더링                                │
│    └─ DCEG 2.0.0 ── 경보 데이터 입력 검증                              │
│                                                                         │
│  S-127 MTM Ed.1.0.0 ─── TSS/VTS 구역 표출                             │
│    └─ FC 1.0.0 ── 통항분리대/VTS 관할 피처 정의                        │
│                                                                         │
│  S-100 Ed.5.2.1 ─── 공통 데이터 모델 / Exchange Set / 인코딩          │
│    ├─ Part 5 (FC) ── Feature Catalogue 구조 파싱                       │
│    ├─ Part 9/9a (Portrayal/Lua) ── 렌더링 엔진                         │
│    ├─ Part 10a/10b/10c ── 인코딩 (8211/GML/HDF5)                      │
│    ├─ Part 15 ── 암호화/서명 (Encryption optional, Signing mandatory)  │
│    ├─ Part 16/16a ── Interoperability / Harmonised Portrayal            │
│    └─ Part 17 ── Discovery Metadata (Exchange Catalogue)               │
├─────────────────────────────────────────────────────────────────────────┤
│                    wing-gis-vessel (Vessel Signal)                       │
│                                                                         │
│  S-124 ─── 조난 경보 연동 (VHF-DSC → S-124 Nav Warning 자동 생성)     │
│  S-127 ─── VTS 관제 구역 내 선박 연계                                  │
├─────────────────────────────────────────────────────────────────────────┤
│                    wing-gis-integration (통합연계모듈)                    │
│                                                                         │
│  S-100 Part 10b (GML) ─── 물표 데이터 GML 인코딩 변환                  │
│  S-100 Part 14 ─── Online Communication Exchange 프로토콜               │
│  S-100 Part 17 ─── Exchange Catalogue 메타데이터 관리                   │
│  S-100 Part 15 ─── 데이터 서명/검증 (Digital Signature)                │
├─────────────────────────────────────────────────────────────────────────┤
│                    wing-gis-analysis (분석 서비스)                        │
│                                                                         │
│  S-102 ─── 수심 격자 기반 해저 지형 분석                                │
│  S-104 ─── 조석 데이터 기반 수위 예측 분석                              │
│  S-111 ─── 해류 데이터 기반 표류 예측 분석                              │
├─────────────────────────────────────────────────────────────────────────┤
│                    wing-gis-layer (레이어 관리)                           │
│                                                                         │
│  S-100 Part 5 ─── Feature Catalogue XML 파싱/관리                      │
│  S-100 Part 9 ─── Portrayal Catalogue 관리 (SLD 변환)                  │
│  S-100 Part 11 ─── Product Specification 메타 관리                     │
│  S-158 ─── Validation Checks 실행 엔진                                 │
└─────────────────────────────────────────────────────────────────────────┘

8.3 Feature Catalogue Integration

FC(Feature Catalogue) XML을 파싱하여 DB에 자동 로드하는 구조:

S-100 Specifications/S-101/101_Feature_Catalogue_2.0.0.xml
         │
         ▼
  ┌──────────────┐     ┌──────────────────────────────┐
  │  FC Parser    │────▶│  chart_feature_type (DB)     │
  │  (GeoTools/   │     │  ├─ feature_type: Lighthouse │
  │   JAXB)       │     │  ├─ attributes: JSONB        │
  │               │     │  ├─ geometry_type: Point      │
  └──────────────┘     │  └─ product: S-101            │
                        └──────────────────────────────┘
FC File Product Feature Types DB Table
101_FC_2.0.0.xml S-101 DepthArea, DepthContour, Lighthouse, Buoy, Rock, Wreck, FairwaySystem, AnchorageArea, RestrictedArea, Coastline, LandArea, ... (~180 types) chart_feature
102_FC_3.0.0.xml S-102 BathymetricDataset, TrackingList, QualityOfBathymetricData chart_feature
104_FC_2.0.0.xml S-104 WaterLevelTrend, WaterLevelTimeSeries, TidalStation chart_feature
111_FC_2.0.0.xml S-111 SurfaceCurrentDataset, SurfaceCurrentTimeSeries chart_feature
122_FC_1.0.0.xml S-122 MarineProtectedArea boundary
123_FC_1.0.0.xml S-123 RadioServiceArea, RadioStation chart_feature
124_FC_2.0.0.xml S-124 NavigationalWarningPart, NavigationalWarningFeaturePart alert / chart_feature
S-127_FC_1.0.0 S-127 TrafficSeparationScheme, VTSArea, ReportingPoint boundary

8.4 Portrayal Catalogue Integration

PC(Portrayal Catalogue)를 활용한 S-52 기반 렌더링 규칙:

PC File Product 렌더링 대상 Frontend 적용
101_PC_2.0.0 S-101 해도 심볼/색상/선형 OpenLayers Style + Lua 엔진
102_PC_3.0.0 S-102 수심 음영/등심선 Raster 타일 색상 팔레트
111_PC_2.0.0 S-111 해류 벡터 화살표 SVG 벡터 오버레이
124_PC_2.0.0 S-124 항행경보 구역 심볼 경보 폴리곤 스타일
S-100 BPC (Lua) 공통 Lua 기반 Portrayal 스크립팅 Part 9a Lua 인터프리터

8.5 Validation Integration (S-158)

S-158 기반 데이터 품질 검증:

Validation File 대상 검증 내용 서비스
S-158-100_v1.0.0 S-100 공통 Exchange Set 구조, 메타데이터, 인코딩 규칙 wing-gis-integration
S-158-101_v1.1.0 S-101 ENC 피처 속성 완전성, 토폴로지, SCAMIN, 좌표 정밀도 wing-gis-map
S-158-102_v1.0.0 S-102 수심 BAG 격자 무결성, 수심 범위 검증 wing-gis-map

8.6 Data Encoding Support (S-100 Part 10)

Encoding S-100 Part 지원 제품 라이브러리
ISO/IEC 8211 Part 10a S-101 (레거시 S-57 호환) GeoTools S-57 Driver
GML 3.2 Part 10b S-122, S-123, S-124, S-127 JAXB + GML Parser
HDF5 Part 10c S-102, S-104, S-111 (격자 데이터) JHdf5 / HDF5 Java

8.7 S-100 Ed.5.2.1 Key Changes Applied

본 시스템에 반영된 S-100 Ed.5.2.1 (December 2025) 주요 변경사항:

Part 변경 내용 시스템 반영
Part 1 URI Derived Type에 fileURI 추가, MRN 형식 변경 메타데이터 URI 처리
Part 5 FC InformationType/FeatureType 상속 관계 정정 FC XML 파서
Part 10b GML 파일 확장자 .GML 필수, xlink:title 명시 GML 인코딩 모듈
Part 10c HDF5 featureAttributeTableKey 컬럼명 변경, timePoint optional HDF5 리더
Part 11 Product Specification 참조를 IHO GI Registry로 변경 PS 메타 관리
Part 14 ISO/IEC 80000-13:2025 추가 온라인 교환
Part 15 암호화 optional, 서명 mandatory, schemeAdministrator [1] 필수 S-63 Encryptor
Part 16a Harmonised Portrayal URL 변경 렌더링 엔진
Part 17 editionNumber → PositiveInteger, boundingPolygon 좌표 순서 CRS 기준 Exchange Catalogue
Part 18 URL 정규화 참조 변경 다국어 지원

9. RFP Requirement Mapping (80 Requirements)

RFP ID 요구사항 서비스 상태 비고
SFR-01 통합 GIS 서비스 wing-gis-map + MapViewML MapLibre GL JS
SFR-02 서비스 제공 방식 React SPA (WEB) Vite 8
SFR-03 전자해도+공간정보 통합조회 nauticalChart 피처 gcnautical.com ENC
SFR-04 S-100 차세대 전자해도 fetchEncStyle + S-52 테마 주간/황혼/야간
SFR-05 물표정보 연계+융합 useAisPolling + deck.gl AIS 실시간, 비AIS 더미
SFR-06 통합연계모듈 wing-gis-integration Kafka 스트림
SFR-07 관할 기반+사용자 레이어 wing-gis-layer 업로드/SLD
SFR-08 선박 통합 검색 VesselSearch ⚠️ UI 구현, 백엔드 미연동
SFR-09 외부 분석결과 시각화 wing-gis-analysis GeoJSON/SHP
SFR-10 7개 시스템 통합 wing-gis-integration 7종 어댑터
PER-03 동시접속 3,000명 K8s HPA + Redis Scale-out
ECR-01 MSA 아키텍처 Docker + K8s ⚠️ Docker Compose 완료, K8s 미구현
INR-04 SSO/GPKI wing-gis-auth + Keycloak
INR-05 API 서비스 SpringDoc OpenAPI
INR-06 MCP 에이전트 wing-gis-mcp LLM 연계
DAR-01~12 데이터 요구사항 PostgreSQL + PostGIS ⚠️ 스키마 완료, 데이터 미적재

구현 완료 · ⚠️ 부분 구현 · 미착수


10. Development Phases

Phase 1: 기반 구축 (M+0 ~ M+2) — 완료

  • 프로젝트 구조 설계 (ARCHITECTURE.md)
  • React 프로젝트 초기화 (Vite 8 + TypeScript 5.9)
  • PostgreSQL + PostGIS 스키마 생성 (001_init_schema.sql)
  • Docker Compose 개발환경 (7개 서비스)
  • MapLibre GL JS 기반 지도 (OpenLayers → MapLibre 전환 완료)
  • deck.gl MapboxOverlay 통합 (선박 WebGL 렌더링)
  • ENC 전자해도 (gcnautical.com 벡터 타일, S-52 테마)
  • 레이아웃 5-패널 구조 (TitleBar/SubToolbar/Sidebar/RightPanel/BottomBar)
  • Zustand 상태 관리 (vessels, aisTargets, signalState, nauticalChartSettings)

Phase 2: 핵심 기능 (M+2 ~ M+4) — 진행 중

  • AIS 실시간 물표 (REST 폴링 60분 초기 → 1분 간격 → 2시간 프루닝)
  • SignalKindCode 기반 아이콘 (8종 색상/형태, 항해/정박 구분)
  • 호버 툴팁 (이름, MMSI, SOG/COG, 사진 썸네일)
  • 선박 사진 모달 (고화질 뷰어, 네비게이션, 캐러셀)
  • 물표현황 실데이터 (AIS 카운트, 관할 내 선박 분류)
  • 선박 통합 검색 UI (SFR-08, 백엔드 미연동)
  • EEZ/NLL/관할구역 경계 레이어
  • 사용자 인증 (SSO/GPKI)

Phase 3: 통합 (M+4 ~ M+6)

  • 7개 시스템 연계 어댑터 (V-Pass/E-NAV/VTS/VTS-RADAR/AIR-AIS/VHF-DSC/LRIT)
  • STOMP WebSocket 실시간 물표 스트리밍
  • 통합연계모듈 (수집/정제/융합/배포)
  • 공간분석 기능 (버퍼/히트맵/통계)
  • 레이어 업로드/SLD 편집
  • MCP 에이전트 (LLM 연계)

Phase 4: 안정화 (M+6 ~ M+7)

  • 성능 최적화 (ShipBatchRenderer 밀도 컬링 고도화, 3,000명 동시접속)
  • 보안 감사 로그
  • 운영 전환 + 교육