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) — 완료
Phase 2: 핵심 기능 (M+2 ~ M+4) — 진행 중
Phase 3: 통합 (M+4 ~ M+6)
Phase 4: 안정화 (M+6 ~ M+7)