diff --git a/frontend/public/manual/image1.png b/frontend/public/manual/image1.png new file mode 100644 index 0000000..35f8f23 Binary files /dev/null and b/frontend/public/manual/image1.png differ diff --git a/frontend/public/manual/image10.png b/frontend/public/manual/image10.png new file mode 100644 index 0000000..3355ad0 Binary files /dev/null and b/frontend/public/manual/image10.png differ diff --git a/frontend/public/manual/image11.png b/frontend/public/manual/image11.png new file mode 100644 index 0000000..5ba4275 Binary files /dev/null and b/frontend/public/manual/image11.png differ diff --git a/frontend/public/manual/image12.png b/frontend/public/manual/image12.png new file mode 100644 index 0000000..e601a22 Binary files /dev/null and b/frontend/public/manual/image12.png differ diff --git a/frontend/public/manual/image13.png b/frontend/public/manual/image13.png new file mode 100644 index 0000000..c22adf8 Binary files /dev/null and b/frontend/public/manual/image13.png differ diff --git a/frontend/public/manual/image14.png b/frontend/public/manual/image14.png new file mode 100644 index 0000000..9a397f2 Binary files /dev/null and b/frontend/public/manual/image14.png differ diff --git a/frontend/public/manual/image15.png b/frontend/public/manual/image15.png new file mode 100644 index 0000000..6d019df Binary files /dev/null and b/frontend/public/manual/image15.png differ diff --git a/frontend/public/manual/image16.png b/frontend/public/manual/image16.png new file mode 100644 index 0000000..3980d40 Binary files /dev/null and b/frontend/public/manual/image16.png differ diff --git a/frontend/public/manual/image17.png b/frontend/public/manual/image17.png new file mode 100644 index 0000000..f532ae5 Binary files /dev/null and b/frontend/public/manual/image17.png differ diff --git a/frontend/public/manual/image18.png b/frontend/public/manual/image18.png new file mode 100644 index 0000000..bc046cf Binary files /dev/null and b/frontend/public/manual/image18.png differ diff --git a/frontend/public/manual/image19.png b/frontend/public/manual/image19.png new file mode 100644 index 0000000..0267818 Binary files /dev/null and b/frontend/public/manual/image19.png differ diff --git a/frontend/public/manual/image2.png b/frontend/public/manual/image2.png new file mode 100644 index 0000000..5861df8 Binary files /dev/null and b/frontend/public/manual/image2.png differ diff --git a/frontend/public/manual/image20.png b/frontend/public/manual/image20.png new file mode 100644 index 0000000..de0a98c Binary files /dev/null and b/frontend/public/manual/image20.png differ diff --git a/frontend/public/manual/image21.png b/frontend/public/manual/image21.png new file mode 100644 index 0000000..03a5bb1 Binary files /dev/null and b/frontend/public/manual/image21.png differ diff --git a/frontend/public/manual/image22.png b/frontend/public/manual/image22.png new file mode 100644 index 0000000..9eda05f Binary files /dev/null and b/frontend/public/manual/image22.png differ diff --git a/frontend/public/manual/image23.png b/frontend/public/manual/image23.png new file mode 100644 index 0000000..80cd5fb Binary files /dev/null and b/frontend/public/manual/image23.png differ diff --git a/frontend/public/manual/image24.png b/frontend/public/manual/image24.png new file mode 100644 index 0000000..3ad0bdf Binary files /dev/null and b/frontend/public/manual/image24.png differ diff --git a/frontend/public/manual/image25.png b/frontend/public/manual/image25.png new file mode 100644 index 0000000..69f09f8 Binary files /dev/null and b/frontend/public/manual/image25.png differ diff --git a/frontend/public/manual/image26.png b/frontend/public/manual/image26.png new file mode 100644 index 0000000..44a4341 Binary files /dev/null and b/frontend/public/manual/image26.png differ diff --git a/frontend/public/manual/image27.png b/frontend/public/manual/image27.png new file mode 100644 index 0000000..7da9af8 Binary files /dev/null and b/frontend/public/manual/image27.png differ diff --git a/frontend/public/manual/image28.png b/frontend/public/manual/image28.png new file mode 100644 index 0000000..b11b297 Binary files /dev/null and b/frontend/public/manual/image28.png differ diff --git a/frontend/public/manual/image29.png b/frontend/public/manual/image29.png new file mode 100644 index 0000000..75a3ee6 Binary files /dev/null and b/frontend/public/manual/image29.png differ diff --git a/frontend/public/manual/image3.png b/frontend/public/manual/image3.png new file mode 100644 index 0000000..8d3ef4b Binary files /dev/null and b/frontend/public/manual/image3.png differ diff --git a/frontend/public/manual/image30.png b/frontend/public/manual/image30.png new file mode 100644 index 0000000..d109b73 Binary files /dev/null and b/frontend/public/manual/image30.png differ diff --git a/frontend/public/manual/image31.png b/frontend/public/manual/image31.png new file mode 100644 index 0000000..cd3de33 Binary files /dev/null and b/frontend/public/manual/image31.png differ diff --git a/frontend/public/manual/image32.png b/frontend/public/manual/image32.png new file mode 100644 index 0000000..039e898 Binary files /dev/null and b/frontend/public/manual/image32.png differ diff --git a/frontend/public/manual/image33.png b/frontend/public/manual/image33.png new file mode 100644 index 0000000..69d95f0 Binary files /dev/null and b/frontend/public/manual/image33.png differ diff --git a/frontend/public/manual/image34.png b/frontend/public/manual/image34.png new file mode 100644 index 0000000..f41fd9f Binary files /dev/null and b/frontend/public/manual/image34.png differ diff --git a/frontend/public/manual/image35.png b/frontend/public/manual/image35.png new file mode 100644 index 0000000..01a3d48 Binary files /dev/null and b/frontend/public/manual/image35.png differ diff --git a/frontend/public/manual/image36.png b/frontend/public/manual/image36.png new file mode 100644 index 0000000..90d1c4c Binary files /dev/null and b/frontend/public/manual/image36.png differ diff --git a/frontend/public/manual/image37.png b/frontend/public/manual/image37.png new file mode 100644 index 0000000..9db4c39 Binary files /dev/null and b/frontend/public/manual/image37.png differ diff --git a/frontend/public/manual/image38.png b/frontend/public/manual/image38.png new file mode 100644 index 0000000..4fd4bcb Binary files /dev/null and b/frontend/public/manual/image38.png differ diff --git a/frontend/public/manual/image39.png b/frontend/public/manual/image39.png new file mode 100644 index 0000000..73875c7 Binary files /dev/null and b/frontend/public/manual/image39.png differ diff --git a/frontend/public/manual/image4.png b/frontend/public/manual/image4.png new file mode 100644 index 0000000..3404fad Binary files /dev/null and b/frontend/public/manual/image4.png differ diff --git a/frontend/public/manual/image40.png b/frontend/public/manual/image40.png new file mode 100644 index 0000000..0df13a1 Binary files /dev/null and b/frontend/public/manual/image40.png differ diff --git a/frontend/public/manual/image41.png b/frontend/public/manual/image41.png new file mode 100644 index 0000000..6f09a7f Binary files /dev/null and b/frontend/public/manual/image41.png differ diff --git a/frontend/public/manual/image42.png b/frontend/public/manual/image42.png new file mode 100644 index 0000000..ee96650 Binary files /dev/null and b/frontend/public/manual/image42.png differ diff --git a/frontend/public/manual/image43.png b/frontend/public/manual/image43.png new file mode 100644 index 0000000..767e1ea Binary files /dev/null and b/frontend/public/manual/image43.png differ diff --git a/frontend/public/manual/image44.png b/frontend/public/manual/image44.png new file mode 100644 index 0000000..8d9135c Binary files /dev/null and b/frontend/public/manual/image44.png differ diff --git a/frontend/public/manual/image45.png b/frontend/public/manual/image45.png new file mode 100644 index 0000000..dec4163 Binary files /dev/null and b/frontend/public/manual/image45.png differ diff --git a/frontend/public/manual/image46.png b/frontend/public/manual/image46.png new file mode 100644 index 0000000..f338731 Binary files /dev/null and b/frontend/public/manual/image46.png differ diff --git a/frontend/public/manual/image47.png b/frontend/public/manual/image47.png new file mode 100644 index 0000000..c4d83e3 Binary files /dev/null and b/frontend/public/manual/image47.png differ diff --git a/frontend/public/manual/image48.png b/frontend/public/manual/image48.png new file mode 100644 index 0000000..6130f68 Binary files /dev/null and b/frontend/public/manual/image48.png differ diff --git a/frontend/public/manual/image49.png b/frontend/public/manual/image49.png new file mode 100644 index 0000000..4e8fdaf Binary files /dev/null and b/frontend/public/manual/image49.png differ diff --git a/frontend/public/manual/image5.png b/frontend/public/manual/image5.png new file mode 100644 index 0000000..e274910 Binary files /dev/null and b/frontend/public/manual/image5.png differ diff --git a/frontend/public/manual/image50.png b/frontend/public/manual/image50.png new file mode 100644 index 0000000..b3d0729 Binary files /dev/null and b/frontend/public/manual/image50.png differ diff --git a/frontend/public/manual/image51.png b/frontend/public/manual/image51.png new file mode 100644 index 0000000..cb373d2 Binary files /dev/null and b/frontend/public/manual/image51.png differ diff --git a/frontend/public/manual/image52.png b/frontend/public/manual/image52.png new file mode 100644 index 0000000..24cba58 Binary files /dev/null and b/frontend/public/manual/image52.png differ diff --git a/frontend/public/manual/image53.png b/frontend/public/manual/image53.png new file mode 100644 index 0000000..8bf2c49 Binary files /dev/null and b/frontend/public/manual/image53.png differ diff --git a/frontend/public/manual/image54.png b/frontend/public/manual/image54.png new file mode 100644 index 0000000..f637998 Binary files /dev/null and b/frontend/public/manual/image54.png differ diff --git a/frontend/public/manual/image55.png b/frontend/public/manual/image55.png new file mode 100644 index 0000000..d6e9ec7 Binary files /dev/null and b/frontend/public/manual/image55.png differ diff --git a/frontend/public/manual/image56.png b/frontend/public/manual/image56.png new file mode 100644 index 0000000..f0817cc Binary files /dev/null and b/frontend/public/manual/image56.png differ diff --git a/frontend/public/manual/image57.png b/frontend/public/manual/image57.png new file mode 100644 index 0000000..39bac57 Binary files /dev/null and b/frontend/public/manual/image57.png differ diff --git a/frontend/public/manual/image58.png b/frontend/public/manual/image58.png new file mode 100644 index 0000000..7d35b36 Binary files /dev/null and b/frontend/public/manual/image58.png differ diff --git a/frontend/public/manual/image59.png b/frontend/public/manual/image59.png new file mode 100644 index 0000000..dc80e0c Binary files /dev/null and b/frontend/public/manual/image59.png differ diff --git a/frontend/public/manual/image6.png b/frontend/public/manual/image6.png new file mode 100644 index 0000000..b13de43 Binary files /dev/null and b/frontend/public/manual/image6.png differ diff --git a/frontend/public/manual/image60.png b/frontend/public/manual/image60.png new file mode 100644 index 0000000..c68209f Binary files /dev/null and b/frontend/public/manual/image60.png differ diff --git a/frontend/public/manual/image61.png b/frontend/public/manual/image61.png new file mode 100644 index 0000000..81fb99e Binary files /dev/null and b/frontend/public/manual/image61.png differ diff --git a/frontend/public/manual/image62.png b/frontend/public/manual/image62.png new file mode 100644 index 0000000..5e25bc6 Binary files /dev/null and b/frontend/public/manual/image62.png differ diff --git a/frontend/public/manual/image63.png b/frontend/public/manual/image63.png new file mode 100644 index 0000000..0d3a435 Binary files /dev/null and b/frontend/public/manual/image63.png differ diff --git a/frontend/public/manual/image64.png b/frontend/public/manual/image64.png new file mode 100644 index 0000000..a4f4008 Binary files /dev/null and b/frontend/public/manual/image64.png differ diff --git a/frontend/public/manual/image65.png b/frontend/public/manual/image65.png new file mode 100644 index 0000000..cdd0724 Binary files /dev/null and b/frontend/public/manual/image65.png differ diff --git a/frontend/public/manual/image66.png b/frontend/public/manual/image66.png new file mode 100644 index 0000000..8a201e1 Binary files /dev/null and b/frontend/public/manual/image66.png differ diff --git a/frontend/public/manual/image67.png b/frontend/public/manual/image67.png new file mode 100644 index 0000000..746fddc Binary files /dev/null and b/frontend/public/manual/image67.png differ diff --git a/frontend/public/manual/image68.png b/frontend/public/manual/image68.png new file mode 100644 index 0000000..1c1d3b9 Binary files /dev/null and b/frontend/public/manual/image68.png differ diff --git a/frontend/public/manual/image69.png b/frontend/public/manual/image69.png new file mode 100644 index 0000000..7620400 Binary files /dev/null and b/frontend/public/manual/image69.png differ diff --git a/frontend/public/manual/image7.png b/frontend/public/manual/image7.png new file mode 100644 index 0000000..a948b66 Binary files /dev/null and b/frontend/public/manual/image7.png differ diff --git a/frontend/public/manual/image70.png b/frontend/public/manual/image70.png new file mode 100644 index 0000000..ede13f7 Binary files /dev/null and b/frontend/public/manual/image70.png differ diff --git a/frontend/public/manual/image71.png b/frontend/public/manual/image71.png new file mode 100644 index 0000000..a6976b0 Binary files /dev/null and b/frontend/public/manual/image71.png differ diff --git a/frontend/public/manual/image72.png b/frontend/public/manual/image72.png new file mode 100644 index 0000000..f3f41d7 Binary files /dev/null and b/frontend/public/manual/image72.png differ diff --git a/frontend/public/manual/image73.png b/frontend/public/manual/image73.png new file mode 100644 index 0000000..de5025e Binary files /dev/null and b/frontend/public/manual/image73.png differ diff --git a/frontend/public/manual/image74.png b/frontend/public/manual/image74.png new file mode 100644 index 0000000..fa88e25 Binary files /dev/null and b/frontend/public/manual/image74.png differ diff --git a/frontend/public/manual/image75.png b/frontend/public/manual/image75.png new file mode 100644 index 0000000..bdb2628 Binary files /dev/null and b/frontend/public/manual/image75.png differ diff --git a/frontend/public/manual/image76.png b/frontend/public/manual/image76.png new file mode 100644 index 0000000..65c4b3d Binary files /dev/null and b/frontend/public/manual/image76.png differ diff --git a/frontend/public/manual/image77.png b/frontend/public/manual/image77.png new file mode 100644 index 0000000..6a9c060 Binary files /dev/null and b/frontend/public/manual/image77.png differ diff --git a/frontend/public/manual/image8.png b/frontend/public/manual/image8.png new file mode 100644 index 0000000..bc34f4f Binary files /dev/null and b/frontend/public/manual/image8.png differ diff --git a/frontend/public/manual/image9.png b/frontend/public/manual/image9.png new file mode 100644 index 0000000..c4fe430 Binary files /dev/null and b/frontend/public/manual/image9.png differ diff --git a/frontend/src/common/components/layout/TopBar.tsx b/frontend/src/common/components/layout/TopBar.tsx index 5695c75..c0c7690 100755 --- a/frontend/src/common/components/layout/TopBar.tsx +++ b/frontend/src/common/components/layout/TopBar.tsx @@ -3,6 +3,7 @@ import type { MainTab } from '../../types/navigation' import { useAuthStore } from '../../store/authStore' import { useMenuStore } from '../../store/menuStore' import { useMapStore } from '../../store/mapStore' +import UserManualPopup from '../ui/UserManualPopup' interface TopBarProps { activeTab: MainTab @@ -11,6 +12,7 @@ interface TopBarProps { export function TopBar({ activeTab, onTabChange }: TopBarProps) { const [showQuickMenu, setShowQuickMenu] = useState(false) + const [showManual, setShowManual] = useState(false) const quickMenuRef = useRef(null) const { hasPermission, user, logout } = useAuthStore() const { menuConfig, isLoaded } = useMenuStore() @@ -173,10 +175,26 @@ export function TopBar({ activeTab, onTabChange }: TopBarProps) { ))} + +
+ + {/* 매뉴얼 */} +
)} + + {/* 사용자 매뉴얼 팝업 */} + setShowManual(false)} /> ) } diff --git a/frontend/src/common/components/ui/UserManualPopup.tsx b/frontend/src/common/components/ui/UserManualPopup.tsx new file mode 100644 index 0000000..89e4256 --- /dev/null +++ b/frontend/src/common/components/ui/UserManualPopup.tsx @@ -0,0 +1,1616 @@ +import { useState } from 'react'; + +interface UserManualPopupProps { + isOpen: boolean; + onClose: () => void; +} + +interface InputItem { + label: string; + type: string; + required: boolean; + desc: string; +} + +interface ScreenItem { + id: string; + name: string; + menuPath: string; + imageIndex: number; + overview: string; + description?: string; + procedure?: string[]; + inputs?: InputItem[]; + notes?: string[]; +} + +interface Chapter { + id: string; + number: string; + title: string; + subtitle: string; + screens: ScreenItem[]; +} + +const CHAPTERS: Chapter[] = [ + { + id: 'ch01', + number: '01', + title: '유출유 확산예측', + subtitle: 'Oil Spill Dispersion Prediction', + screens: [ + { + id: '001', + name: '직접입력', + menuPath: '유출유확산예측 > 유출유확산분석', + imageIndex: 1, + overview: + '해양 유출유 사고 발생 시 오염원 위치와 유출 조건을 직접 입력하여 확산 범위를 예측하는 주요 분석 화면이다. KOSPS·POSEIDON·OpenDrift·앙상블의 4종 수치 모델을 선택적으로 적용할 수 있다. 실시간 기상·해양 데이터와 연계하여 즉시 예측 결과를 지도에 표출한다.', + description: + '화면 좌측에 예측정보 입력 패널(사고명, 위치, 유종, 유출량, 예측 시간)이 위치한다. 중앙 지도에서 클릭하여 사고 발생 위치를 직접 지정하거나 위·경도 좌표를 수동 입력할 수 있다. 하단 타임라인 슬라이더로 시간 경과에 따른 확산 경과를 재생할 수 있다. 우측 \'분석 요약\' 패널에서 예측 면적, 이동거리, 이동 방향, 풍화 비율 등을 확인할 수 있다.', + procedure: [ + '상단 메뉴에서 \'유출유확산예측 > 유출유확산분석\'을 클릭하여 화면을 이동한다.', + '좌측 패널에서 사고명, 날짜, 유종, 유출량, 예측 시간을 입력한다.', + '지도를 클릭하거나 좌표 입력란에 위·경도를 직접 입력하여 사고 위치를 지정한다.', + '적용할 확산 모델(KOSPS·POSEIDON·OpenDrift·앙상블) 체크박스를 선택한다.', + '\'확산예측 실행\' 버튼을 클릭하여 예측을 시작한다.', + '하단 타임라인 재생 버튼으로 시간별 확산 결과를 확인한다.', + ], + inputs: [ + { label: '사고명', type: '텍스트', required: true, desc: '사고 식별 명칭' }, + { label: '날짜/시간', type: '날짜+시간', required: true, desc: '사고 발생 일시' }, + { label: '위도/경도', type: '숫자', required: true, desc: '지도 클릭 자동 입력 가능' }, + { label: '유종', type: '드롭다운', required: true, desc: '벙커C유·경유·연료유 등' }, + { label: '유출량', type: '숫자 kL', required: true, desc: '유출 유류 총량' }, + { label: '예측 시간', type: '숫자 h', required: true, desc: '확산 예측 기간' }, + { label: '적용 모델', type: '체크박스', required: true, desc: 'KOSPS·POSEIDON·OpenDrift·앙상블 중 선택' }, + ], + notes: [ + '좌표 입력 후 반드시 \'적용\' 버튼을 클릭해야 지도에 반영된다.', + '앙상블 모델 선택 시 3개 모델이 동시 실행되어 계산 시간이 증가할 수 있다.', + '유출량이 0 이하이거나 예측 시간이 입력되지 않으면 실행 버튼이 비활성화된다.', + ], + }, + { + id: '002', + name: '모델종류별 확산예측 실행', + menuPath: '유출유확산예측 > 유출유확산분석', + imageIndex: 2, + overview: + 'KOSPS·POSEIDON·OpenDrift 3개 모델의 예측 결과를 동시에 지도에 표출하여 모델 간 비교 분석을 지원한다. 모델별 입자 궤적(파란점·빨간점·하늘점)이 중첩 표시되어 확산 경향의 편차를 한눈에 파악할 수 있다.', + description: + '지도에 모델별 색상 구분 입자가 동시에 표시되며, 각 모델의 확산 방향과 범위 차이를 시각적으로 비교할 수 있다. 우측 \'분석 요약\' 패널에 예측 면적(km2), 이동거리(km), 방향, 이동속도(cm/s)가 표출된다. 풍화 상태 막대그래프(유출량·해면연소·자연분산·수중분산·잔류 비율)를 제공한다. \'다각형 분석수행\' 버튼으로 특정 구역 내 오염 면적을 별도 산정할 수 있다.', + procedure: [ + '확산분석 화면에서 적용 모델 체크박스를 2개 이상 선택한다.', + '\'확산예측 실행\' 버튼을 클릭한다.', + '지도에서 각 모델의 입자 분포와 확산 범위를 비교한다.', + '우측 \'분석 요약\' 탭에서 모델별 정량 지표를 확인한다.', + '하단 타임라인으로 시간 경과별 확산 변화를 재생한다.', + ], + notes: [ + '여러 모델을 동시에 선택하면 계산 자원 소모가 증가하여 결과 표출까지 수 분이 소요될 수 있다.', + '모델별 예측 결과에 차이가 있을 경우, 앙상블 결과 또는 현장 데이터와 교차 검토하여 활용한다.', + ], + }, + { + id: '003', + name: '사고정보 조회', + menuPath: '유출유확산예측 > 유출유확산분석', + imageIndex: 3, + overview: + '시스템에 등록된 실제 사고 정보를 불러와 확산분석에 자동 연동하는 기능이다. 사고코드·선박명·유종·유출량·발생 좌표 등이 자동으로 예측정보 입력란에 채워진다.', + description: + '좌측 \'사고정보\' 패널에 진행 중인 사고 목록이 표시된다. 사고를 선택하면 지도 중심이 해당 사고 발생 위치로 자동 이동하고 위치 핀이 표시된다. 사고 상태는 \'진행중(빨간 배지)\'과 \'종료(회색 배지)\'로 구분된다.', + procedure: [ + '좌측 \'사고정보\' 패널의 펼침 버튼을 클릭하여 패널을 연다.', + '목록에서 분석할 사고를 클릭한다.', + '사고 정보가 예측정보 입력란에 자동으로 입력되었는지 확인한다.', + '필요 시 유출량·예측 시간 등 추가 정보를 수정한다.', + '\'확산예측 실행\'을 클릭하여 분석을 시작한다.', + ], + notes: [ + '\'진행중\' 상태의 사고만 실시간 확산예측과 연동된다.', + '사고 데이터는 관계 기관으로부터 등록된 정보를 기반으로 하며, 입력 오류 시 관리자에게 문의한다.', + ], + }, + { + id: '004', + name: '영향 민감자원 레이어 중첩 표시', + menuPath: '유출유확산예측 > 유출유확산분석', + imageIndex: 4, + overview: + '유출유 확산 예측 결과와 해양 민감자원(환경생태·수산자원·관광지 등) 레이어를 지도에 동시 표출하는 기능이다. 잠재적 피해 자원을 사전에 파악하여 방제 우선순위 설정에 활용한다.', + description: + '좌측 하단 \'정보 레이어\' 패널에서 환경생태·사회경제·민감도평가·해경관할구역 등 대분류 토글을 제공한다. 각 항목 우측에 해당 레이어 데이터 건수가 표시된다. \'전체 켜기/끄기\' 버튼으로 모든 레이어를 일괄 제어할 수 있다.', + procedure: [ + '좌측 하단 \'정보 레이어\' 패널을 열고 원하는 레이어 항목을 활성화한다.', + '확산예측 실행 후 지도에 표출된 오염 범위와 레이어 분포를 비교한다.', + '오염 영향이 우려되는 자원 레이어를 클릭하여 상세 정보를 확인한다.', + '필요한 레이어 조합을 선택하여 보고서용 지도 캡처에 활용한다.', + ], + notes: [ + '레이어 수가 많을 경우 지도 로딩 속도가 느려질 수 있으므로 필요한 레이어만 선택적으로 활성화한다.', + ], + }, + { + id: '005', + name: 'AI자동추천 배치안 적용', + menuPath: '유출유확산예측 > 유출유확산분석 > 오일펜스 배치 가이드', + imageIndex: 5, + overview: + '확산예측 결과를 기반으로 AI(NSGA-II 알고리즘)가 최적 오일펜스 배치안을 자동으로 생성하는 기능이다. 최대 3개 방어선의 위치·방향·총 길이·차단율을 자동 계산하여 지도에 표출한다.', + description: + '\'오일펜스 배치 가이드\' 패널 상단 \'AI자동 추천\' 탭에서 배치 결과를 확인한다. 1차~3차 방어선별 배치 위치(좌표), 방향, 오일펜스 길이, 예상 차단율이 표시된다.', + procedure: [ + '확산예측 실행 완료 후 좌측 \'오일펜스 배치 가이드\' 패널을 연다.', + '\'AI자동 추천\' 탭을 선택하여 추천 배치안을 확인한다.', + '방어선별 차단율 및 오일펜스 총 길이를 검토한다.', + '\'추천 배치안 적용하기\' 버튼을 클릭하여 지도에 표출한다.', + '현장 여건(조류·지형·자원 현황)을 고려하여 최종 배치안을 확정한다.', + ], + inputs: [ + { label: '배치 수', type: '숫자', required: false, desc: '투입할 오일펜스 방어선 수' }, + { label: '최소 차단율', type: '숫자 %', required: false, desc: '목표 차단율' }, + ], + notes: [ + 'AI 추천 기능은 확산예측이 완료된 후에 활성화된다.', + '추천 배치안은 수치 모델 기반 결과로, 현장 조류 변동·수심·접근 가능성 등을 반드시 현장 담당자가 최종 확인해야 한다.', + ], + }, + { + id: '006', + name: '이미지업로드', + menuPath: '유출유확산예측 > 유출유확산분석', + imageIndex: 6, + overview: + '위성·드론·항공기에서 촬영한 이미지를 업로드하여 실제 오염 현황과 모델 예측 결과를 비교 분석하는 기능이다.', + description: + '예측정보 입력 패널 상단 \'이미지 업로드\' 탭을 선택하면 파일 업로드 영역이 활성화된다. 업로드된 이미지는 지도에 자동으로 오버레이 표출된다.', + procedure: [ + '예측정보 입력 패널에서 \'이미지 업로드\' 탭을 선택한다.', + '\'파일 선택\' 버튼을 클릭하거나 파일을 드래그하여 업로드한다.', + '업로드된 이미지가 지도에 올바르게 표출되는지 위치를 확인한다.', + '확산예측 결과와 이미지를 동시에 표출하여 비교한다.', + ], + inputs: [ + { label: '업로드 파일', type: '파일 PNG/JPG', required: false, desc: '위성·드론·항공기 촬영 이미지' }, + ], + notes: [ + '지원 파일 형식은 PNG, JPG이다.', + '업로드한 이미지의 좌표 기준(GCP)이 없을 경우 지도 상 위치 정확도가 낮을 수 있다.', + ], + }, + { + id: '007', + name: '분석 목록', + menuPath: '유출유확산예측', + imageIndex: 7, + overview: + '완료 또는 진행 중인 유출유 확산예측 분석 이력을 목록 형식으로 조회하는 화면이다. 사고명·날짜·유종·유출량·모델 상태 등을 한눈에 파악할 수 있다.', + description: + '목록에는 번호·사고명·사고일시·예측시간·유종·유출량·모델별 상태(KOSPS·POSEIDON·OPENDRIFT)·담당자 등이 표시된다. 모델 상태는 \'완료(녹색 배지)\'와 \'대기(회색 배지)\'로 구분된다.', + procedure: [ + '상단 메뉴에서 \'유출유확산예측\'을 클릭하여 분석 목록 화면으로 이동한다.', + '검색창에 사고명을 입력하거나 페이지를 이동하여 원하는 분석을 찾는다.', + '사고명 링크를 클릭하여 해당 분석 결과 상세 화면으로 이동한다.', + '신규 분석이 필요한 경우 우측 상단 \'+ 새 분석\' 버튼을 클릭한다.', + ], + notes: [ + '분석 결과 삭제 시 복구가 불가하므로, 삭제 전 보고서 출력 또는 데이터 저장 여부를 확인한다.', + ], + }, + { + id: '008', + name: '분석 조회(test001)', + menuPath: '유출유확산예측 > 분석 목록', + imageIndex: 8, + overview: + '분석 목록에서 특정 분석 건을 선택하면 해당 확산분석 결과 화면으로 이동하여 상세 내용을 조회한다. 이전 분석 결과를 재검토하거나 조건 변경 후 재분석할 수 있다.', + procedure: [ + '분석 목록에서 조회할 사고명 링크를 클릭한다.', + '로드된 분석 정보를 확인한다.', + '필요 시 입력 조건을 수정하고 \'확산예측 실행\'을 다시 클릭하여 재분석한다.', + '결과를 보고서로 출력하거나 저장한다.', + ], + notes: [ + '기존 분석에서 모델 조건 변경 후 재실행 시 이전 결과가 덮어써질 수 있으므로, 원본 결과를 먼저 저장한다.', + ], + }, + { + id: '009', + name: '유출유확산모델 이론 - 시스템 개요', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 9, + overview: + 'Wing 시스템에 탑재된 유출유 확산 수치 모델의 개요와 운용 체계를 안내하는 이론 화면이다. KOSPS·POSEIDON·OpenDrift 3종 모델의 특징·비교·데이터 흐름을 확인할 수 있다.', + procedure: [ + '상단 메뉴에서 \'유출유확산예측 > 유출유확산모델 이론\'을 클릭한다.', + '\'시스템 개요\' 탭을 선택하여 전체 모델 체계를 확인한다.', + '각 탭(KOSPS·POSEIDON·OpenDrift 등)을 클릭하여 상세 이론을 열람한다.', + ], + }, + { + id: '010', + name: '유출유확산모델 이론 - KOSPS', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 10, + overview: + '한국해양과학기술원(KIOST)이 개발한 KOSPS 모델의 상세 이론을 안내한다. 국내 연안 특성에 최적화된 조류예측(CHARRY) 및 풍류 경험식 적용 원리를 설명한다.', + notes: [ + 'KOSPS는 국내 연안 중심으로 검증된 모델로, 원해·심해 적용 시 정확도 제한이 있을 수 있다.', + ], + }, + { + id: '011', + name: '유출유확산모델 이론 - POSEIDON', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 11, + overview: + '입자추적 최적화 예측 시스템 POSEIDON의 이론 및 MOHID 3D 해양순환모델 적용 원리를 안내한다. GA·DE·HS·PSO 등 4종 최적화 알고리즘을 통한 파라미터 자동 최적화 방법을 설명한다.', + }, + { + id: '012', + name: '유출유확산모델 이론 - OpenDrift', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 12, + overview: + '노르웨이 MET Norway가 개발한 오픈소스 라그랑지안 확산 프레임워크 OpenDrift의 이론을 안내한다. NEMO·ROMS·HYCOM·Copernicus CMEMS 등 다양한 해양 예보 모델과 연동 가능한 범용성을 설명한다.', + }, + { + id: '013', + name: '유출유확산모델 이론 - 입자추적법', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 13, + overview: + '유출유 수치 모델에 적용되는 라그랑지안 입자추적법(Lagrangian Particle Tracking Method)의 수학적 이론과 수식을 안내한다.', + }, + { + id: '014', + name: '유출유확산모델 이론 - 풍화 프로세스', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 14, + overview: + '유출유가 시간 경과에 따라 겪는 풍화(Weathering) 프로세스(증발·유화·자연분산 등)의 이론과 타임라인을 안내한다.', + notes: [ + '풍화 속도는 유종·기온·해수온·파랑 조건에 따라 크게 달라질 수 있으므로 참고용으로 활용한다.', + ], + }, + { + id: '015', + name: '유출유확산모델 이론 - 해양환경 입력', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 15, + overview: + '유출유 확산 수치 모델에 사용되는 해양환경 입력 데이터(기상·해류·조류·해수면 온도) 체계를 안내한다. KMA RDAPS·ECMWF·NIFS ROMS·HYCOM·TPXO9 등 데이터 소스 설명.', + }, + { + id: '016', + name: '유출유확산모델 이론 - 모델 검증', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 16, + overview: + '유출유 확산 모델의 정확도 검증 사례(2007 허베이스피리트, 2014 무이산 등)와 RMSE·Skill Score 통계 지표를 안내한다.', + }, + { + id: '017', + name: '유출유확산모델 이론 - 앙상블', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 17, + overview: + 'KOSPS·POSEIDON·OpenDrift 3종 모델의 결과를 통합하는 앙상블 예측 방법론과 가중평균 알고리즘을 안내한다. 최악 시나리오(Worst Case) 산출 방법도 설명한다.', + }, + { + id: '018', + name: '유출유확산모델 이론 - 발전 방향', + menuPath: '유출유확산예측 > 유출유확산모델 이론', + imageIndex: 18, + overview: + '현재 유출유 확산 모델의 한계와 향후 개선 방향(4단계 로드맵)을 안내한다.', + }, + { + id: '019', + name: '오일펜스 배치 알고리즘 이론 - 개요', + menuPath: '유출유확산예측 > 오일펜스 배치 알고리즘 이론', + imageIndex: 19, + overview: + '오일펜스 최적 배치 알고리즘의 전체 개요와 최적화 목표(차단 면적 최대화·도달시간 최소화·자원 효율화)를 안내한다.', + }, + { + id: '020', + name: '오일펜스 배치 알고리즘 이론 - 배치 이론', + menuPath: '유출유확산예측 > 오일펜스 배치 알고리즘 이론', + imageIndex: 20, + overview: + '차단 효율 함수(E(theta, U))와 V형·U형·J형 배치 형태별 이론적 차단 원리를 안내한다. 다단계 차단선 배치 시 총 차단 효율 산출 공식도 포함한다.', + }, + { + id: '021', + name: '오일펜스 배치 알고리즘 이론 - 최적화 알고리즘', + menuPath: '유출유확산예측 > 오일펜스 배치 알고리즘 이론', + imageIndex: 21, + overview: + 'NSGA-II(Non-dominated Sorting Genetic Algorithm II) 기반 다목적 최적화 알고리즘의 원리와 보조 알고리즘(PSO·Greedy) 비교를 안내한다.', + }, + { + id: '022', + name: '오일펜스 배치 알고리즘 이론 - 유체역학 모델', + menuPath: '유출유확산예측 > 오일펜스 배치 알고리즘 이론', + imageIndex: 22, + overview: + '오일펜스 차단 성능 평가에 사용되는 유체역학 모델의 이론을 안내한다.', + }, + { + id: '023', + name: '오일펜스 배치 알고리즘 이론 - 현장 적용', + menuPath: '유출유확산예측 > 오일펜스 배치 알고리즘 이론', + imageIndex: 23, + overview: + '오일펜스 배치 알고리즘의 실제 사고 현장 적용 사례와 현장 운용 시 고려사항을 안내한다.', + }, + { + id: '024', + name: '오일펜스 배치 알고리즘 이론 - 참고문헌', + menuPath: '유출유확산예측 > 오일펜스 배치 알고리즘 이론', + imageIndex: 24, + overview: + '오일펜스 배치 알고리즘 이론에 사용된 학술 논문·기술 보고서·국제 기준 등 참고문헌 목록을 안내한다.', + }, + ], + }, + { + id: 'ch02', + number: '02', + title: 'HNS·대기확산', + subtitle: 'HNS Atmospheric Dispersion', + screens: [ + { + id: '025', + name: '대기확산예측 실행', + menuPath: 'HNS대기확산 > 대기확산분석', + imageIndex: 25, + overview: + 'HNS(위험유해물질) 해상 유출 시 대기 확산 범위, 위험 농도 구역, 영향 인구를 예측하는 핵심 분석 화면이다. ALOHA(EPA) 또는 이문진박사모델 두 가지 알고리즘 중 선택하여 가우시안 Plume/Puff 모델을 적용한다.', + description: + '화면 좌측에 사고 기본정보·물질 및 유출 조건·기상조건 입력 패널이 위치한다. 중앙 지도에 AEGL-1~3 위험 구역이 색상별 Plume 형태로 표출된다. 우측 \'예측 결과\' 패널에 최대 농도(ppm), AEGL-1 영향 면적, 위험 등급 등이 표시된다.', + procedure: [ + '상단 메뉴에서 \'HNS대기확산 > 대기확산분석\'을 클릭한다.', + '사고 기본정보(사고명·날짜·시간·위치)를 입력한다.', + 'HNS 물질 종류 및 누출 방식·유출량을 선택·입력한다.', + '기상조건(풍향·풍속·기온·대기안정도·예측 시간)을 입력한다.', + '적용 알고리즘(ALOHA/이문진박사모델)을 선택한다.', + '\'확산예측 실행\' 버튼을 클릭한다.', + '지도의 위험 구역 Plume과 우측 예측 결과 패널을 확인한다.', + ], + inputs: [ + { label: '사고명', type: '텍스트', required: true, desc: '사고 식별 명칭' }, + { label: '사고 일시', type: '날짜+시간', required: true, desc: '사고 발생 일시' }, + { label: '위도/경도', type: '숫자', required: true, desc: '사고 발생 지점 좌표' }, + { label: 'HNS 물질', type: '드롭다운', required: true, desc: 'AEGL/ERPG 기준값 자동 로드' }, + { label: '누출 방식', type: '라디오', required: true, desc: '순간 유출 또는 지속 유출' }, + { label: '유출량', type: '숫자', required: true, desc: 'ton 또는 g/s 단위' }, + { label: '풍향', type: '숫자', required: true, desc: '0~360도' }, + { label: '풍속', type: '숫자 m/s', required: true, desc: '최소 0.5 m/s 이상' }, + { label: '기온', type: '숫자', required: true, desc: '현재 기온' }, + { label: '대기안정도', type: '선택 A~F', required: true, desc: 'Pasquill-Gifford 분류' }, + { label: '예측 시간', type: '숫자 h', required: true, desc: '확산 예측 기간' }, + { label: '적용 알고리즘', type: '라디오', required: true, desc: 'ALOHA 또는 이문진박사모델' }, + ], + notes: [ + '풍속은 최소 0.5 m/s 이상 입력해야 하며 0 입력 시 오류 발생.', + 'HNS 물질 선택 후 AEGL/ERPGs 기준값이 자동 로드되었는지 반드시 확인.', + ], + }, + { + id: '026', + name: 'HNS 분석 목록', + menuPath: 'HNS대기확산', + imageIndex: 26, + overview: + '완료된 HNS 대기확산 분석 이력을 목록 형식으로 조회하는 화면이다. AEGL-1~3 거리·위험 등급·피해반경·담당자 등 주요 결과 정보를 한눈에 파악할 수 있다.', + procedure: [ + '상단 메뉴에서 \'HNS대기확산\'을 클릭하여 분석 목록으로 이동한다.', + '검색창에서 분석명을 검색하거나 목록을 스크롤하여 원하는 분석을 찾는다.', + '분석명 링크를 클릭하여 해당 분석 결과 지도 화면으로 이동한다.', + ], + }, + { + id: '027', + name: '시나리오 상세', + menuPath: 'HNS대기확산 > 시나리오 관리', + imageIndex: 27, + overview: + '단일 HNS 사고에 대해 여러 기상·유출 조건 시나리오(S-01~S-05 등)를 생성·비교 관리하는 화면이다. 시나리오별 위험도·위험 구역·대응 권고사항을 한눈에 비교할 수 있다.', + description: + '시나리오 목록 카드에 시나리오명·위험도 배지(CRITICAL/HIGH/MEDIUM/RESOLVED)·최대농도·IDLH 거리·ERPG-2 거리·영향인구 요약이 표시된다.', + procedure: [ + '\'HNS대기확산 > 시나리오 관리\'를 클릭하여 이동한다.', + '원하는 사고 건을 선택하면 시나리오 목록이 표시된다.', + '시나리오 카드를 클릭하여 상세 위험 구역과 대응 권고사항을 확인한다.', + '\'비교 차트\' 탭으로 이동하여 시나리오 간 시간별 변화를 비교한다.', + ], + }, + { + id: '028', + name: '비교 차트', + menuPath: 'HNS대기확산 > 시나리오 관리', + imageIndex: 28, + overview: + '생성된 여러 HNS 시나리오의 최대 지표면 농도·위험 반경·영향 인구를 시간별 변화 차트로 비교하는 화면이다.', + description: + '상단은 시나리오별 최대 지표면 농도(ppm) 시간별 변화 그래프. 중단에 위험 반경(km)과 영향 인구(명) 변화 차트. 하단에 피대농도·IDLH 거리·ERPG-2 반경·영향인구·풍향/풍속·위험등급 항목별 비교표가 제공된다.', + }, + { + id: '029', + name: '확산범위 오버레이', + menuPath: 'HNS대기확산 > 시나리오 관리', + imageIndex: 29, + overview: + 'HNS 대기확산 시나리오의 시간대별(T+0h~T+4h) 확산 범위를 지도에 오버레이 표출하는 화면이다.', + procedure: [ + '시나리오 관리 화면에서 \'확산범위 오버레이\' 탭을 클릭한다.', + '지도에서 시간대별 확산 범위를 확인한다.', + '슬라이더를 이동하여 원하는 시간대의 확산 상태를 조회한다.', + ], + }, + { + id: '030', + name: '신규 시나리오', + menuPath: 'HNS대기확산 > 시나리오 관리', + imageIndex: 30, + overview: + '기상·유출 조건을 변경하여 새로운 HNS 대기확산 시나리오를 생성하는 입력 모달 화면이다.', + procedure: [ + '시나리오 관리 화면 우측 상단 \'신규 시나리오\' 버튼을 클릭한다.', + '시나리오명과 기준 시각을 입력한다.', + 'HNS 물질·누출 구분·유출량을 입력한다.', + '기상조건(풍향·풍속·기온·대기안정도)을 입력한다.', + '\'시나리오 생성 및 예측 실행\'을 클릭한다.', + ], + inputs: [ + { label: '시나리오명', type: '텍스트', required: true, desc: '시나리오 식별 명칭' }, + { label: 'HNS 물질', type: '드롭다운', required: true, desc: '유출 물질 선택' }, + { label: '누출 구분', type: '라디오', required: true, desc: '순간/지속' }, + { label: '유출량', type: '숫자', required: true, desc: 'ton 또는 g/s' }, + { label: '풍향/풍속', type: '숫자', required: true, desc: '각도와 m/s' }, + { label: '기온', type: '숫자', required: true, desc: '섭씨' }, + { label: '대기안정도', type: '선택 A~F', required: true, desc: 'Pasquill-Gifford' }, + ], + }, + { + id: '031', + name: 'HNS 대응매뉴얼', + menuPath: 'HNS대기확산', + imageIndex: 31, + overview: + '해양 HNS 사고 대응 절차를 정리한 Marine HNS Response Manual(Bonn Agreement·HELCOM·REMPEC 기반)을 시스템 내에서 직접 열람하는 화면이다. 8개 챕터. SEBC 거동 분류 5유형 카드.', + procedure: [ + '상단 메뉴에서 \'HNS대기확산 > HNS 대응매뉴얼\'을 클릭한다.', + '원하는 챕터 카드를 클릭하여 세부 내용을 확인한다.', + '하단 SEBC 분류 카드를 클릭하여 거동 유형별 대응 방법을 확인한다.', + ], + }, + { + id: '032', + name: 'HNS 확산모델 이론 - 시스템 개요', + menuPath: 'HNS대기확산 > 확산모델 이론', + imageIndex: 32, + overview: + 'Wing에 탑재된 HNS 대기확산 모델(WRF-Chem·Gaussian Plume/Puff·ROMS 연동)의 전체 체계와 처리 흐름을 안내한다.', + }, + { + id: '033', + name: 'HNS 확산모델 이론 - 가우시안 모델', + menuPath: 'HNS대기확산 > 확산모델 이론', + imageIndex: 33, + overview: + 'HNS 대기확산 예측에 적용되는 Gaussian Plume·Puff 모델의 수학적 이론과 Pasquill-Gifford 대기안정도 분류 체계를 안내한다.', + }, + { + id: '034', + name: 'HNS 확산모델 이론 - 물질별 시나리오', + menuPath: 'HNS대기확산 > 확산모델 이론', + imageIndex: 34, + overview: + '주요 HNS 물질(NH3·CH3OH·H2·LNG 등)의 물질 특성 및 대기확산 시나리오 적용 기준을 안내한다.', + }, + { + id: '035', + name: 'HNS 확산모델 이론 - 해양환경 보정', + menuPath: 'HNS대기확산 > 확산모델 이론', + imageIndex: 35, + overview: + '해양 환경 특성(해풍·육풍 순환·해수면 거칠기·SST 영향·MABL 구조)에 따른 대기확산 모델 보정 인자를 안내한다.', + }, + { + id: '036', + name: 'HNS 확산모델 이론 - 모델 검증', + menuPath: 'HNS대기확산 > 확산모델 이론', + imageIndex: 36, + overview: + 'HNS 대기확산 모델의 실측값 대비 예측 정확도 검증 결과(ALOHA·이문진박사모델·실측값 3종 비교)를 안내한다.', + }, + { + id: '037', + name: 'HNS 확산모델 이론 - 실시간 비교', + menuPath: 'HNS대기확산 > 확산모델 이론', + imageIndex: 37, + overview: + '동일 조건에서 ALOHA와 이문진박사모델의 예측 결과를 실시간으로 비교하는 시뮬레이션 화면이다.', + }, + { + id: '038', + name: 'HNS 확산모델 이론 - WRF-Chem 발전', + menuPath: 'HNS대기확산 > 확산모델 이론', + imageIndex: 38, + overview: + 'WRF-Chem 기상-화학 연계 모델 및 ROMS 해양확산 수치모의 검증 결과와 고도화 방향을 안내한다.', + }, + { + id: '039', + name: 'HNS물질정보 - SEBC 거동분류', + menuPath: 'HNS대기확산 > HNS물질정보', + imageIndex: 39, + overview: + 'HNS 물질의 해양 거동 특성을 SEBC 기준으로 분류한 정보를 제공한다. G(기체)·E(증발)·F(부유)·D(용해)·S(침강) 5가지 기본 유형과 복합 거동 유형을 안내한다.', + }, + { + id: '040', + name: 'HNS물질정보 - 주요 물질 특성', + menuPath: 'HNS대기확산 > HNS물질정보', + imageIndex: 40, + overview: + 'NH3·CH4·H2·페놀·톨루엔 등 주요 HNS 물질의 상세 물리화학적 특성을 카드 형식으로 제공하는 화면이다.', + }, + { + id: '041', + name: 'HNS물질정보 - 위험도 기준', + menuPath: 'HNS대기확산 > HNS물질정보', + imageIndex: 41, + overview: + 'HNS 물질의 위험도 평가에 사용되는 AEGL·ERPG·IDLH·TWA 등 주요 독성 기준값 체계를 안내한다.', + }, + { + id: '042', + name: 'HNS물질정보 - 물질 상세검색', + menuPath: 'HNS대기확산 > HNS물질정보', + imageIndex: 42, + overview: + 'HNS 6,500여 종의 물질 데이터베이스에서 CAS 번호·물질명·거동 분류 조건으로 물질을 검색하는 화면이다.', + inputs: [ + { label: '검색어', type: '텍스트', required: true, desc: 'CAS 번호 또는 물질명' }, + { label: '거동 분류', type: '체크박스', required: false, desc: 'SEBC 유형 필터' }, + ], + notes: [ + 'CAS 번호 입력 시 하이픈(-) 포함 정확한 형식으로 입력해야 검색된다.', + ], + }, + ], + }, + { + id: 'ch03', + number: '03', + title: '긴급구난', + subtitle: 'Emergency Rescue', + screens: [ + { + id: '043', + name: '긴급구난예측', + menuPath: '긴급구난', + imageIndex: 43, + overview: + '해상 조난자·표류 선박·표류 물체의 위치를 예측하는 긴급구난(SAR) 분석 화면이다. 해류·바람·파랑 데이터 기반 라그랑지안 표류 궤적 시뮬레이션을 수행한다.', + description: + '화면 좌측에 사고 발생 위치·일시·표류체 종류·예측 시간·기상조건 입력 패널이 위치한다. 중앙 지도에 표류 예측 궤적과 탐색 구역(최우선·일반)이 표출된다.', + procedure: [ + '상단 메뉴에서 \'긴급구난\'을 클릭한다.', + '사고 발생 위치(위경도)와 일시를 입력한다.', + '표류체 종류(선박/사람/컨테이너 등)를 선택한다.', + '예측 시간과 기상 조건을 입력한다.', + '\'예측 실행\' 버튼을 클릭하여 표류 궤적과 탐색 구역을 확인한다.', + ], + inputs: [ + { label: '사고 위치', type: '숫자', required: true, desc: '위·경도' }, + { label: '사고 일시', type: '날짜+시간', required: true, desc: '발생 일시' }, + { label: '표류체 종류', type: '드롭다운', required: true, desc: '선박·사람·컨테이너·구명정 등' }, + { label: '예측 시간', type: '숫자 h', required: true, desc: '표류 예측 기간' }, + { label: '기상조건', type: '숫자', required: false, desc: '미입력 시 실시간 자동 적용' }, + ], + notes: [ + '표류체 종류 선택이 부적절한 경우 예측 정확도가 낮아질 수 있다.', + '신속한 대응을 위해 입력 완료 즉시 실행하고 기상 변화 시 재분석을 수행한다.', + ], + }, + { + id: '044', + name: '긴급구난 목록', + menuPath: '긴급구난', + imageIndex: 44, + overview: + '완료 또는 진행 중인 긴급구난 예측 분석 이력을 목록 형식으로 조회하는 화면이다.', + procedure: [ + '상단 메뉴에서 \'긴급구난\'을 클릭하면 목록 화면이 표시된다.', + '원하는 분석을 검색하거나 목록에서 선택한다.', + '사고명 링크를 클릭하여 상세 분석 결과로 이동한다.', + ], + }, + { + id: '045', + name: '시나리오 상세', + menuPath: '긴급구난 > 시나리오 관리', + imageIndex: 45, + overview: + '긴급구난 사고에 대해 기상·해양 조건을 달리 설정한 복수 시나리오를 생성·비교 관리하는 화면이다.', + procedure: [ + '\'긴급구난 > 시나리오 관리\'를 클릭하여 이동한다.', + '생성된 시나리오 카드를 확인하거나 \'신규 시나리오\' 버튼으로 추가 생성한다.', + '시나리오 카드를 클릭하여 상세 내용을 확인한다.', + ], + }, + { + id: '046', + name: '비교 차트', + menuPath: '긴급구난 > 시나리오 관리', + imageIndex: 46, + overview: + '긴급구난 시나리오별 탐색 면적·표류 속도·최대 이동거리를 시간별 변화 차트로 비교하는 화면이다.', + }, + { + id: '047', + name: '지도 오버레이', + menuPath: '긴급구난 > 시나리오 관리', + imageIndex: 47, + overview: + '긴급구난 시나리오의 시간대별 표류 예측 궤적 및 탐색 구역을 지도에 오버레이 표출하는 화면이다.', + }, + { + id: '048', + name: '긴급구난모델 이론', + menuPath: '긴급구난', + imageIndex: 48, + overview: + '긴급구난 표류 예측에 적용되는 라그랑지안 표류 모델·탐색 구역(Search Area) 산출 방법·IMO SAR 기준 적용 이론을 안내한다.', + }, + ], + }, + { + id: 'ch04', + number: '04', + title: '보고자료', + subtitle: 'Reports', + screens: [ + { + id: '049', + name: '보고서 목록', + menuPath: '보고자료', + imageIndex: 49, + overview: + '시스템에서 생성된 모든 사고 대응 보고서를 목록 형식으로 관리하는 화면이다. 보고서명·사고명·생성일시·유형·작성자·상태가 표시된다.', + procedure: [ + '상단 메뉴에서 \'보고자료\'를 클릭하여 보고서 목록으로 이동한다.', + '검색창에서 원하는 보고서를 검색하거나 목록에서 선택한다.', + '보고서명을 클릭하여 미리보기하거나 PDF를 다운로드한다.', + ], + }, + { + id: '050', + name: '초기보고서', + menuPath: '보고자료 > 표준보고서 템플릿', + imageIndex: 50, + overview: + '사고 발생 초기 지휘부 보고를 위한 표준 보고서 템플릿을 제공한다. 확산예측 결과와 사고 기본정보가 자동 연동된다.', + procedure: [ + '보고자료 메뉴에서 \'표준보고서 템플릿\'을 클릭한다.', + '좌측 사이드바에서 \'초기보고서\'를 선택한다.', + '자동 입력된 항목을 검토하고 필요 내용을 추가 입력한다.', + '\'저장\' 또는 \'PDF 출력\' 버튼을 활용한다.', + ], + }, + { + id: '051', + name: '지휘부 보고', + menuPath: '보고자료 > 표준보고서 템플릿', + imageIndex: 51, + overview: + '사고 지휘부 보고용 표준 보고서 템플릿. 방제 대응 현황·자원 투입 현황·향후 계획이 포함된다.', + }, + { + id: '052', + name: '예측보고서', + menuPath: '보고자료 > 표준보고서 템플릿', + imageIndex: 52, + overview: + '확산예측 결과를 포함한 예측보고서 템플릿. 모델 종류·예측 시간·주요 결과가 자동 연동된다.', + }, + { + id: '053', + name: '종합보고서', + menuPath: '보고자료 > 표준보고서 템플릿', + imageIndex: 53, + overview: + '사고 종료 후 방제 대응 전 과정을 정리하는 종합보고서. 사고개요·대응경과·방제실적·환경영향평가·교훈이 포함된다.', + }, + { + id: '054', + name: '유출유 보고', + menuPath: '보고자료 > 표준보고서 템플릿', + imageIndex: 54, + overview: + '유출유 사고 전용 표준 보고서 템플릿. 확산예측·오일펜스 배치·풍화 상태가 자동 연동된다.', + }, + { + id: '055', + name: '유출유 확산예측 보고서 생성', + menuPath: '보고자료 > 보고서 생성', + imageIndex: 55, + overview: + '유출유 확산예측 분석 결과를 기반으로 보고서를 자동 생성하는 화면이다.', + procedure: [ + '보고자료 메뉴에서 \'보고서 생성\'을 클릭한다.', + '\'유출유 확산예측\' 유형을 선택한다.', + '연동할 분석 결과를 드롭다운에서 선택한다.', + '보고 대상을 선택한다.', + '\'보고서 생성\' 버튼을 클릭한다.', + ], + inputs: [ + { label: '분석 결과', type: '드롭다운', required: true, desc: '연동할 분석 건 선택' }, + { label: '보고 대상', type: '체크박스', required: true, desc: '지휘부·현장·외부 기관' }, + ], + }, + { + id: '056', + name: 'HNS 대기확산 보고서 생성', + menuPath: '보고자료 > 보고서 생성', + imageIndex: 56, + overview: + 'HNS 대기확산 분석 결과를 기반으로 보고서를 자동 생성하는 화면이다.', + }, + { + id: '057', + name: '긴급구난 보고서 생성', + menuPath: '보고자료 > 보고서 생성', + imageIndex: 57, + overview: + '긴급구난 예측 분석 결과를 기반으로 구조 현장 지휘부용 보고서를 자동 생성하는 화면이다.', + }, + ], + }, + { + id: 'ch05', + number: '05', + title: '항공탐색', + subtitle: 'Aerial Surveillance', + screens: [ + { + id: '058', + name: '영상사진관리', + menuPath: '항공탐색', + imageIndex: 58, + overview: + '드론·항공기·위성에서 수집된 영상 및 사진을 통합 관리하는 화면이다. 촬영 일시·위치·기기 유형별 분류 조회와 유출유 면적분석 연계를 지원한다.', + procedure: [ + '상단 메뉴에서 \'항공탐색 > 영상사진관리\'를 클릭한다.', + '목록에서 원하는 영상/사진을 선택하거나 지도 마커를 클릭하여 확인한다.', + '신규 파일 업로드 시 \'파일 업로드\' 버튼을 클릭한다.', + ], + inputs: [ + { label: '업로드 파일', type: '파일', required: false, desc: 'JPG·PNG·GeoTIFF·KMZ' }, + { label: '촬영 일시', type: '날짜+시간', required: false, desc: '촬영 시점' }, + { label: '장비 유형', type: '드롭다운', required: false, desc: '드론·항공기·위성·CCTV' }, + ], + notes: [ + '50MB 초과 파일은 업로드 전 압축하거나 관리자에게 문의한다.', + ], + }, + { + id: '059', + name: '유출유면적분석', + menuPath: '항공탐색', + imageIndex: 59, + overview: + '항공·위성 이미지를 기반으로 유출유 오염 면적을 AI 자동 산출하는 화면이다. 자동 추출된 오염 경계선을 수동 편집하여 정밀 면적을 산정할 수 있다.', + procedure: [ + '영상사진관리에서 분석 대상 이미지를 선택하고 \'면적 분석\' 버튼을 클릭한다.', + '\'AI 자동 분석 실행\' 버튼을 클릭하여 오염 경계선을 추출한다.', + '폴리곤 경계선을 검토하고 필요 시 편집 도구로 수동 조정한다.', + '최종 면적·둘레·중심 좌표를 확인하고 저장한다.', + ], + }, + { + id: '060', + name: '실시간드론', + menuPath: '항공탐색', + imageIndex: 60, + overview: + '현장 드론에서 실시간 전송되는 영상 스트리밍을 시스템 내에서 직접 모니터링하는 화면이다.', + procedure: [ + '상단 메뉴에서 \'항공탐색 > 실시간 드론\'을 클릭한다.', + '연결된 드론 목록에서 모니터링할 드론을 선택한다.', + '실시간 영상을 확인하고 필요 시 스냅샷을 저장한다.', + ], + notes: [ + '드론 스트리밍은 네트워크 연결 상태에 따라 화질 및 지연이 달라질 수 있다.', + ], + }, + { + id: '061', + name: '오염선박 3D분석', + menuPath: '항공탐색', + imageIndex: 61, + overview: + '항공·위성 이미지를 기반으로 오염 선박의 3D 모델을 생성하고 오염 분포를 입체적으로 분석하는 화면이다.', + }, + { + id: '062', + name: '위성요청', + menuPath: '항공탐색', + imageIndex: 62, + overview: + 'SAR·광학 위성 촬영 요청 및 수신 결과를 관리하는 화면이다.', + inputs: [ + { label: '요청 위치', type: '숫자', required: true, desc: '위·경도' }, + { label: '촬영 희망 일시', type: '날짜+시간', required: true, desc: '촬영 필요 일시' }, + { label: '위성 종류', type: '라디오', required: true, desc: 'SAR 또는 광학' }, + { label: '해상도', type: '드롭다운', required: false, desc: '요청 이미지 해상도' }, + ], + notes: [ + '위성 촬영 가능 여부는 궤도 조건에 따라 결정되며 요청이 항상 수용되지 않을 수 있다.', + ], + }, + { + id: '063', + name: 'CCTV 조회', + menuPath: '항공탐색', + imageIndex: 63, + overview: + '해안·항만 CCTV의 실시간 영상을 조회하는 화면이다. 사고 인근 CCTV를 지도에서 선택하여 스트리밍으로 확인할 수 있다.', + procedure: [ + '상단 메뉴에서 \'항공탐색 > CCTV조회\'를 클릭한다.', + '지도에서 확인할 CCTV 마커를 클릭한다.', + '실시간 영상을 확인하고 필요 시 스냅샷을 저장한다.', + ], + }, + { + id: '064', + name: '항공탐색 이론 - 개요', + menuPath: '항공탐색 > 항공탐색 이론', + imageIndex: 64, + overview: + 'Wing 항공탐색 기능에 적용되는 원격탐사·ESI 방제지도·면적 산정·확산예측 연계 이론의 전체 개요를 안내한다.', + }, + { + id: '065', + name: '항공탐색 이론 - 탐지 장비', + menuPath: '항공탐색 > 항공탐색 이론', + imageIndex: 65, + overview: + '해양 오염 항공 탐지에 사용되는 주요 장비(SAR·적외선 카메라·UV 센서·광학 카메라)의 특성과 적용 원리를 안내한다.', + }, + { + id: '066', + name: '항공탐색 이론 - 원격탐사', + menuPath: '항공탐색 > 항공탐색 이론', + imageIndex: 66, + overview: + '위성 및 항공 원격탐사(Remote Sensing)의 기본 원리와 해양 오염 탐지 적용 방법을 안내한다.', + }, + { + id: '067', + name: '항공탐색 이론 - ESI 방제지도', + menuPath: '항공탐색 > 항공탐색 이론', + imageIndex: 67, + overview: + '환경민감지수(ESI) 방제지도의 해안선 민감도 등급 분류 체계와 방제 우선순위 결정 방법을 안내한다.', + }, + { + id: '068', + name: '항공탐색 이론 - 면적 산정', + menuPath: '항공탐색 > 항공탐색 이론', + imageIndex: 68, + overview: + '항공·위성 이미지 기반 유출유 면적 산정에 적용되는 AI 알고리즘(객체 탐지·영상 분할)의 원리를 안내한다.', + }, + { + id: '069', + name: '항공탐색 이론 - 확산예측 연계', + menuPath: '항공탐색 > 항공탐색 이론', + imageIndex: 69, + overview: + '항공 탐색 결과(실측 면적·위치)와 유출유 확산예측 모델 보정 연계 방법을 안내한다.', + }, + { + id: '070', + name: '항공탐색 이론 - 논문 특허', + menuPath: '항공탐색 > 항공탐색 이론', + imageIndex: 70, + overview: + 'Wing 항공탐색 기능의 기반이 되는 관련 논문과 특허 목록을 안내한다.', + }, + ], + }, + { + id: 'ch06', + number: '06', + title: '게시판', + subtitle: 'Bulletin Board', + screens: [ + { + id: '071', + name: '전체 게시판', + menuPath: '게시판', + imageIndex: 71, + overview: + '공지사항·자료실·Q&A·해경매뉴얼 게시물을 통합 조회하는 전체 게시판 화면이다.', + procedure: [ + '상단 메뉴에서 \'게시판\'을 클릭하여 전체 게시판으로 이동한다.', + '유형 필터 탭을 선택하거나 검색창에 키워드를 입력한다.', + '원하는 게시물 제목을 클릭하여 상세 내용을 확인한다.', + ], + }, + { + id: '072', + name: '공지사항', + menuPath: '게시판', + imageIndex: 72, + overview: + '시스템 공지·업데이트·장애 안내 등 운영 공지사항을 게시하는 화면이다. 관리자만 등록·수정 가능.', + }, + { + id: '073', + name: '자료실', + menuPath: '게시판', + imageIndex: 73, + overview: + '매뉴얼·지침서·참고자료 등 업무 관련 문서 파일을 공유하는 게시판 화면이다.', + }, + { + id: '074', + name: 'QNA', + menuPath: '게시판', + imageIndex: 74, + overview: + '시스템 사용 관련 질문을 등록하고 답변을 확인하는 Q&A 게시판 화면이다.', + inputs: [ + { label: '제목', type: '텍스트', required: true, desc: '질문 제목' }, + { label: '카테고리', type: '드롭다운', required: true, desc: '기능문의·오류신고·개선요청' }, + { label: '내용', type: '텍스트', required: true, desc: '질문 내용' }, + { label: '첨부 파일', type: '파일', required: false, desc: '스크린샷 등' }, + ], + }, + { + id: '075', + name: '해경 매뉴얼', + menuPath: '게시판', + imageIndex: 75, + overview: + '해양경찰청 방제·대응 매뉴얼을 시스템 내에서 바로 조회할 수 있는 화면이다. 관리자만 등록·수정 가능.', + }, + ], + }, + { + id: 'ch07', + number: '07', + title: '기상정보', + subtitle: 'Weather', + screens: [ + { + id: '076', + name: '기상정보', + menuPath: '기상정보', + imageIndex: 76, + overview: + '현재 사고 지역 주변의 실시간 기상 정보(풍향·풍속·기온·파고·시정 등)를 조회하는 화면이다. 기상 데이터는 확산예측 모델 입력으로 자동 연동된다.', + description: + '사고 위치 기준 반경 내 기상 관측소 목록과 최신 관측값이 표시된다. 시계열 그래프로 과거 24시간 기상 변화를 확인할 수 있다.', + procedure: [ + '상단 메뉴에서 \'기상정보\'를 클릭하여 이동한다.', + '지도에서 관측소 마커를 클릭하거나 목록에서 관측소를 선택한다.', + '최신 기상값과 시계열 그래프를 확인한다.', + ], + notes: [ + '극한 기상 조건에서는 확산예측 정확도가 낮아질 수 있으므로 현장 기상 관측값과 병행 확인한다.', + ], + }, + ], + }, + { + id: 'ch08', + number: '08', + title: '통합조회', + subtitle: 'Integrated Search', + screens: [ + { + id: '077', + name: '통합조회', + menuPath: '통합조회', + imageIndex: 77, + overview: + 'Wing 시스템 전체 분석 이력(유출유·HNS·긴급구난·보고서)을 통합 조회하는 화면이다. 사고명·날짜·분석 유형·담당자 등 복합 조건으로 검색하고 결과를 지도와 목록으로 표출한다.', + description: + '화면 좌측에 날짜 범위·분석 유형·담당자·사고 지역 복합 필터 패널이 위치한다. 중앙 지도에 검색 결과 사고지점 마커가 표출된다. Excel·CSV 내보내기를 지원한다.', + procedure: [ + '상단 메뉴에서 \'통합조회\'를 클릭하여 이동한다.', + '날짜 범위·분석 유형 등 필터 조건을 설정한다.', + '\'검색\' 버튼을 클릭하여 결과를 조회한다.', + '지도 마커 또는 목록 항목을 클릭하여 해당 분석 결과 상세 화면으로 이동한다.', + 'Excel·CSV 내보내기 버튼으로 이력 자료를 저장한다.', + ], + inputs: [ + { label: '날짜 범위', type: '날짜', required: false, desc: '시작·종료 날짜' }, + { label: '분석 유형', type: '체크박스', required: false, desc: '유출유·HNS·긴급구난·보고서' }, + { label: '담당자', type: '텍스트', required: false, desc: '이름 필터' }, + { label: '사고 지역', type: '텍스트', required: false, desc: '지역명 필터' }, + ], + }, + ], + }, +]; + +const UserManualPopup = ({ isOpen, onClose }: UserManualPopupProps) => { + const [selectedChapterId, setSelectedChapterId] = useState('ch01'); + const [expandedScreenIds, setExpandedScreenIds] = useState>(new Set()); + const [lightboxSrc, setLightboxSrc] = useState(null); + + if (!isOpen) return null; + + const selectedChapter = CHAPTERS.find((ch) => ch.id === selectedChapterId) ?? CHAPTERS[0]; + + const toggleScreen = (screenId: string) => { + setExpandedScreenIds((prev) => { + const next = new Set(prev); + if (next.has(screenId)) { + next.delete(screenId); + } else { + next.add(screenId); + } + return next; + }); + }; + + const expandAll = () => { + setExpandedScreenIds(new Set(selectedChapter.screens.map((s) => s.id))); + }; + + const collapseAll = () => { + setExpandedScreenIds(new Set()); + }; + + const allExpanded = + selectedChapter.screens.length > 0 && + selectedChapter.screens.every((s) => expandedScreenIds.has(s.id)); + + return ( + <> +
{ + if (e.target === e.currentTarget) onClose(); + }} + > +
+ {/* Header */} +
+
+ + Wing 사용자 매뉴얼 + + + v0.5 + +
+ +
+ + {/* Body */} +
+ {/* Left Sidebar */} +
+ {CHAPTERS.map((chapter) => { + const isActive = chapter.id === selectedChapterId; + return ( + + ); + })} +
+ + {/* Right Content */} +
+ {/* Chapter heading */} +
+
+
+ + CH {selectedChapter.number} + +

+ {selectedChapter.title} +

+ + {selectedChapter.subtitle} + +
+
+ + {selectedChapter.screens.length}개 화면 + + +
+
+
+ + {/* Screen cards */} +
+ {selectedChapter.screens.map((screen) => { + const isExpanded = expandedScreenIds.has(screen.id); + const imageSrc = `/manual/image${screen.imageIndex}.png`; + return ( +
+ {/* Screen header (toggle) */} + + + {/* Screen detail (expanded) */} + {isExpanded && ( +
+ {/* Screenshot image */} +
+ {screen.name} setLightboxSrc(imageSrc)} + style={{ + width: '100%', + borderRadius: '6px', + border: '1px solid #1e2a45', + cursor: 'zoom-in', + display: 'block', + }} + /> +

+ 이미지를 클릭하면 크게 볼 수 있다 +

+
+ + {/* Menu path breadcrumb */} +
+ {screen.menuPath} +
+ + {/* Overview */} +
+

+ {screen.overview} +

+
+ + {/* Description */} + {screen.description && ( +
+
+ 화면 설명 +
+

+ {screen.description} +

+
+ )} + + {/* Procedure */} + {screen.procedure && screen.procedure.length > 0 && ( +
+
+ 사용 절차 +
+
    + {screen.procedure.map((step, idx) => ( +
  1. + + {idx + 1} + + + {step} + +
  2. + ))} +
+
+ )} + + {/* Inputs */} + {screen.inputs && screen.inputs.length > 0 && ( +
+
+ 입력 항목 +
+
+ + + + + + + + + + + {screen.inputs.map((input, idx) => ( + + + + + + + ))} + +
+ 항목 + + 유형 + + 필수 + + 설명 +
+ {input.label} + + {input.type} + + {input.required ? ( + + 필수 + + ) : ( + + 선택 + + )} + + {input.desc} +
+
+
+ )} + + {/* Notes */} + {screen.notes && screen.notes.length > 0 && ( +
+
+ 유의사항 +
+
    + {screen.notes.map((note, idx) => ( +
  • + + + {note} + +
  • + ))} +
+
+ )} +
+ )} +
+ ); + })} +
+
+
+
+
+ + {/* Lightbox */} + {lightboxSrc !== null && ( +
setLightboxSrc(null)} + > +
e.stopPropagation()} + > + 확대 이미지 + +
+
+ )} + + ); +}; + +export default UserManualPopup;